diff --git a/.github/workflows/actions-nightly.yml b/.github/workflows/actions-nightly.yml new file mode 100644 index 0000000000..355a53883c --- /dev/null +++ b/.github/workflows/actions-nightly.yml @@ -0,0 +1,25 @@ +name: CI + +on: + push: + branches: + - master + pull_request: + workflow_dispatch: + +permissions: + checks: write + pull-requests: write + +jobs: + contracts: + name: Contracts (nightly) + uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v3.2.0 + with: + rust-toolchain: nightly-2024-05-22 + path-to-sc-meta: framework/meta + enable-contracts-size-report: false + mx-scenario-go-version: v2.1.0-alpha + coverage-args: --ignore-filename-regex='meta/src' --ignore-filename-regex='wasm-adapter' --ignore-filename-regex='benchmarks/' --ignore-filename-regex='tests/' --output ./coverage.md + secrets: + token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index b6d06db260..dc0bcc8596 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -12,190 +12,13 @@ permissions: pull-requests: write jobs: - wasm_test: - name: Wasm tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install rust - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: nightly-2023-12-11 - target: wasm32-unknown-unknown - - - name: Install prerequisites - run: | - pipx install multiversx-sdk-cli==v9.3.1 - - cargo install wasm-opt - cargo install twiggy - - cargo install --path framework/meta - sc-meta install mx-scenario-go --tag v2.1.0-alpha - - which mxpy - which wasm-opt - which mx-scenario-go - - - name: Build the wasm contracts - env: - RUSTFLAGS: "" - run: sc-meta all build --no-imports --target-dir $(pwd)/target --path . - - - name: Run the wasm tests - env: - RUSTFLAGS: "" - run: cargo test --features multiversx-sc-scenario/run-go-tests - - - name: Generate the contract report - env: - RUSTFLAGS: "" - run: | - sc-meta all build-dbg --twiggy-paths --target-dir $(pwd)/target --path . - mxpy contract report --skip-build --skip-twiggy --output-format json --output-file report.json - - - name: Upload the report json - uses: actions/upload-artifact@v3 - with: - name: report - path: report.json - - - name: Download the base report - uses: dawidd6/action-download-artifact@v2 - if: github.event_name == 'pull_request' - continue-on-error: true - with: - workflow: actions.yml - name: report - commit: ${{ github.event.pull_request.base.sha }} - path: base-report - - - name: Generate the report template - if: github.event_name == 'pull_request' - run: | - echo "Contract comparison - from {{ .base }} to {{ .head }}" > report.md - if [ ! -f base-report/report.json ] - then - echo ":warning: Warning: Could not download the report for the base branch. Displaying only the report for the current branch. :warning:" >> report.md - mxpy contract report --compare report.json --output-format github-markdown --output-file report-table.md - else - mxpy contract report --compare base-report/report.json report.json --output-format github-markdown --output-file report-table.md - fi - cat report-table.md >> report.md - - - name: Render the report from the template - id: template - uses: chuhlomin/render-template@v1 - if: github.event_name == 'pull_request' - with: - template: report.md - vars: | - base: ${{ github.event.pull_request.base.sha }} - head: ${{ github.event.pull_request.head.sha }} - - - name: Upload the report markdown - uses: actions/upload-artifact@v3 - if: github.event_name == 'pull_request' - with: - name: report-markdown - path: report.md - - - name: Find the comment containing the report - id: fc - uses: peter-evans/find-comment@v2 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository - with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: "github-actions[bot]" - body-includes: "Contract comparison" - - - name: Create or update the report comment - uses: peter-evans/create-or-update-comment@v2 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository - with: - comment-id: ${{ steps.fc.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - body: ${{ steps.template.outputs.result }} - edit-mode: replace - - test_coverage: - name: Test Coverage - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Install rust - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: nightly-2023-12-11 - - - name: Install prerequisites - run: | - rustup component add llvm-tools-preview - dirname $(find ~/.rustup -name llvm-cov) >> $GITHUB_PATH - - echo $(dirname $(find ~/.rustup -name llvm-cov)) - - # which llvm-cov - # which llvm-profdata - - - name: Run tests and generate report - env: - RUSTFLAGS: "" - run: | - ./tests-coverage.sh - - - name: Upload the report - uses: actions/upload-artifact@v3 - with: - name: coverage - path: coverage.md - - - name: Find the comment containing the report - id: fc - uses: peter-evans/find-comment@v2 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository - with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: "github-actions[bot]" - body-includes: "Coverage Summary" - - - name: Create or update the report comment - uses: peter-evans/create-or-update-comment@v2 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository - with: - comment-id: ${{ steps.fc.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - body-file: ./coverage.md - edit-mode: replace - - rust_test: - name: Rust tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: nightly-2023-12-11 - - - name: Run the rust tests - env: - RUSTFLAGS: "" - run: cargo test - - clippy_check: - name: Clippy linter check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: nightly-2023-12-11 - components: clippy - - uses: giraffate/clippy-action@v1 - env: - RUSTFLAGS: "" - with: - github_token: ${{ github.token }} - clippy_flags: --all-targets --all-features + contracts: + name: Contracts + uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v3.1.0 + with: + rust-toolchain: stable + path-to-sc-meta: framework/meta + mx-scenario-go-version: v2.1.0-alpha + coverage-args: --ignore-filename-regex='meta/src' --ignore-filename-regex='wasm-adapter' --ignore-filename-regex='benchmarks/' --ignore-filename-regex='tests/' --output ./coverage.md + secrets: + token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/lldb-formatter-tests.yml b/.github/workflows/lldb-formatter-tests.yml index 36f2d29f08..9aaba9eadd 100644 --- a/.github/workflows/lldb-formatter-tests.yml +++ b/.github/workflows/lldb-formatter-tests.yml @@ -16,7 +16,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: default: true - toolchain: nightly-2023-12-11 + toolchain: stable - name: Download vscode-lldb uses: robinraju/release-downloader@v1.5 diff --git a/.github/workflows/proxy-compare.yml b/.github/workflows/proxy-compare.yml new file mode 100644 index 0000000000..3eef6460d6 --- /dev/null +++ b/.github/workflows/proxy-compare.yml @@ -0,0 +1,31 @@ +name: CI + +on: + push: + branches: + - master + pull_request: + +jobs: + proxy_compare: + name: Proxy compare - newly generated vs present in file tree + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + default: true + toolchain: stable + target: wasm32-unknown-unknown + + - name: Install prerequisites + run: | + cargo install --path framework/meta + + - name: Run proxy compare + run: | + cd contracts + sc-meta all proxy --compare diff --git a/.github/workflows/release-upload.yml b/.github/workflows/release-upload.yml index 6031a5d427..1309c97e5f 100644 --- a/.github/workflows/release-upload.yml +++ b/.github/workflows/release-upload.yml @@ -20,7 +20,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: default: true - toolchain: nightly-2023-12-11 + toolchain: stable target: wasm32-unknown-unknown - name: Setup the PATH variable @@ -54,4 +54,3 @@ jobs: file: ./examples-wasm.zip asset_name: examples-wasm.zip overwrite: true - body: "This is my release text" diff --git a/.github/workflows/template-test-current.yml b/.github/workflows/template-test-current.yml index 457a91435a..56382850fe 100644 --- a/.github/workflows/template-test-current.yml +++ b/.github/workflows/template-test-current.yml @@ -22,7 +22,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: default: true - toolchain: nightly-2023-12-11 + toolchain: stable target: wasm32-unknown-unknown - name: Install prerequisites diff --git a/.github/workflows/template-test-released.yml b/.github/workflows/template-test-released.yml index 8d60860f08..e6227765db 100644 --- a/.github/workflows/template-test-released.yml +++ b/.github/workflows/template-test-released.yml @@ -22,7 +22,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: default: true - toolchain: nightly-2023-12-11 + toolchain: stable target: wasm32-unknown-unknown - name: Install prerequisites diff --git a/.gitignore b/.gitignore index 6e26ebc202..8295450d89 100644 --- a/.gitignore +++ b/.gitignore @@ -8,22 +8,26 @@ # The root Cargo.lock is kept for dependabot. contracts/**/Cargo.lock !contracts/**/wasm*/Cargo.lock +contracts/**/output*/ data/**/Cargo.lock framework/**/Cargo.lock sdk/**/Cargo.lock tools/**/Cargo.lock vm/**/Cargo.lock -# Profiler outputs +# Coverage outputs *.profraw *.profdata *.coverage +coverage.md # These are backup files generated by rustfmt **/*.rs.bk -# VSCode config +# Editors config .vscode +.zed +.idea # Others my-vm-tests.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index c9c2118770..fca5916f11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,77 @@ They are: - `multiversx-chain-scenario-format`, in short `scenario-format`, scenario JSON serializer/deserializer, 1 crate. - `multiversx-sdk`, in short `sdk`, allows communication with the chain(s), 1 crate. + +## [sc 0.50.3] - 2024-05-25 +- Dependency update and fix. There was an issue with the `zip` dependency in sc-meta. + +## [sc 0.50.2] - 2024-05-24 +- Unified transaction syntax: + - Better compilation error messages for malformed transactions; + - Deprecated methods `async_call` and `async_call_promises`, which are kept for backwards compatibility, but causing confusion among developers; + - Contract upgrade available in tests. +- `sc-meta` proxy compare option, which checks that proxies are up to date. Useful for CI. +- `TypeAbi` - removed `Unmanaged` associated type trait bounds, and implemented it for more types. +- Removed jitter from interactor transaction fetch. +- Fixed an issue in the snippets generator. + +## [sc 0.50.1] - 2024-05-16 +- `sc-meta all snippets` generates unified syntax. +- Proxy generator can reference multi-contract variant. +- Fixes: + - `BoxedBytes` - fixed memory leak. + - `ManagedVecItem` - allowing larger payloads (up to 128 bytes). + +## [sc 0.50.0, codec 0.19.0, vm 0.8.4, sdk 0.4.1] - 2024-05-10 +- Framework now runs on **stable** Rust. All unstable features were removed. The most important changes enabling this: + - `CodecFrom` completely removed, `TypeAbiFrom` was used instead since 0.49.0. + - `ManagedVecItem` payload redesigned. + - Contract panic message mechanism improved. +- Unified syntax: + - `NotPayable` marker type in proxies, which prevents callers to add payment to a non-payable endpoint. + +## [sc 0.49.0, codec 0.18.8, sdk 0.4.0] - 2024-05-07 +- Unified transaction syntax + - new syntax for sending transactions from contracts + - new syntax for integration tests: tx, set state, check state, etc. + - new syntax for interactors + - new proxies, generated from sc-meta + - support for upgrade in new proxies +- Improved interactor tx result polling performance. + +## [sc 0.48.1, codec 0.18.7] - 2024-04-30 +- Simplified decoding of small numbers (i64/u64). +- Manual reset of the `StaticApi`, in order to free memory for long-running tasks. + +## [sc 0.49.0-alpha.4, sdk 0.4.0-alpha.4] - 2024-04-23 +Fourth pre-release, contains many interactor improvements, including improved tx polling. + +## [sc 0.49.0-alpha.3] - 2024-04-13 +Third pre-release of the unified syntax, includes backwards compatibility fixes and testing set state/check state. + +## [sc 0.49.0-alpha.2] - 2024-04-09 +Second pre-release of the unified syntax. Most features done, including fully featured interactors. +Still missing: set state/check state in tests. + +## [sc 0.48.0] - 2024-04-09 +- When serializing to a managed buffer, static buffer caching is disabled by default. +- `sc-meta:` - installers for wasm32 target and wasm-opt. +- Integrated traits for token management: `FixedSupplyToken`, `Mergeable`. + +## [sc 0.48.0-alpha.1] - 2024-03-27 (actually alpha release of 0.49.0) +First pre-release of the unified syntax. Syntax not yet stabilized, should only be used for experimenting with various smart contracts. + +## [sc 0.47.8] - 2024-03-22 +- Test coverage functionality in sc-meta. +- Removed deprecation from legacy whitebox testing framework, since it is still used extensively. + +## [sc 0.47.7] - 2024-03-15 +- Template bugfix (concerning the interactor). + +## [sc 0.47.6] - 2024-03-14 +- Template naming bugfix, regarding numbers in the project name. +- Added the interactor to the adder template. + ## [sc 0.47.5] - 2024-03-08 - Fixed an issue with `MapMapper` when reading from another contract. - Got rid of nightly feature `maybe_uninit_uninit_array`/`maybe_uninit_array_assume_init`. diff --git a/Cargo.lock b/Cargo.lock index 1e015137d2..ec245b66b9 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,7 +17,7 @@ name = "abi-tester" version = "0.0.0" dependencies = [ "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "multiversx-sc-scenario", ] @@ -26,7 +26,7 @@ name = "abi-tester-meta" version = "0.0.0" dependencies = [ "abi-tester", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -37,30 +37,19 @@ dependencies = [ "multiversx-sc-scenario", ] -[[package]] -name = "adder-interact" -version = "0.0.0" -dependencies = [ - "adder", - "clap", - "multiversx-sc-snippets", - "serde", - "toml", -] - [[package]] name = "adder-meta" version = "0.0.0" dependencies = [ "adder", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -71,11 +60,23 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -94,52 +95,53 @@ name = "alloc-features-meta" version = "0.0.0" dependencies = [ "alloc-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -147,9 +149,18 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arbitrary" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] [[package]] name = "arrayvec" @@ -157,17 +168,23 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" dependencies = [ "addr2line", "cc", @@ -180,9 +197,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.7" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "basic-features" @@ -210,7 +227,18 @@ name = "basic-features-meta" version = "0.0.0" dependencies = [ "basic-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", +] + +[[package]] +name = "basic-interact" +version = "0.0.0" +dependencies = [ + "adder", + "clap", + "multiversx-sc-snippets", + "serde", + "toml", ] [[package]] @@ -241,7 +269,7 @@ name = "big-float-features-meta" version = "0.0.0" dependencies = [ "big-float-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -271,9 +299,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block-buffer" @@ -307,14 +335,14 @@ name = "bonding-curve-contract-meta" version = "0.0.0" dependencies = [ "bonding-curve-contract", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "bstr" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", "serde", @@ -333,14 +361,14 @@ name = "builtin-func-features-meta" version = "0.0.0" dependencies = [ "builtin-func-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" @@ -350,18 +378,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" [[package]] name = "cfg-if" @@ -384,7 +409,7 @@ name = "check-pause-meta" version = "0.0.0" dependencies = [ "check-pause", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -401,14 +426,14 @@ version = "0.0.0" dependencies = [ "child", "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "clap" -version = "4.4.18" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -416,9 +441,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -428,9 +453,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck", "proc-macro2", @@ -440,15 +465,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "colored" @@ -472,6 +497,7 @@ version = "0.0.0" dependencies = [ "builtin-func-features", "forwarder", + "forwarder-legacy", "forwarder-queue", "forwarder-raw", "multiversx-sc", @@ -517,15 +543,6 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" -[[package]] -name = "coverage-renderer" -version = "0.1.0" -dependencies = [ - "anyhow", - "serde", - "serde_json", -] - [[package]] name = "cpufeatures" version = "0.2.12" @@ -537,9 +554,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -565,9 +582,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crowdfunding-erc20" @@ -583,7 +600,7 @@ name = "crowdfunding-erc20-meta" version = "0.0.0" dependencies = [ "crowdfunding-erc20", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -602,7 +619,7 @@ name = "crowdfunding-esdt-meta" version = "0.0.0" dependencies = [ "crowdfunding-esdt", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -618,7 +635,7 @@ name = "crypto-bubbles-meta" version = "0.0.0" dependencies = [ "crypto-bubbles", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -644,7 +661,7 @@ name = "crypto-zombies-meta" version = "0.0.0" dependencies = [ "crypto-zombies", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -660,6 +677,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "digest" version = "0.9.0" @@ -693,7 +721,18 @@ name = "digital-cash-meta" version = "0.0.0" dependencies = [ "digital-cash", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -721,9 +760,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "empty" @@ -739,14 +778,14 @@ name = "empty-meta" version = "0.0.0" dependencies = [ "empty", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -769,9 +808,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e7cf40684ae96ade6232ed84582f40ce0a66efcd43a5117aef610534f8e0b8" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" dependencies = [ "anstream", "anstyle", @@ -809,7 +848,7 @@ name = "erc1155-marketplace-meta" version = "0.0.0" dependencies = [ "erc1155-marketplace", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -817,7 +856,7 @@ name = "erc1155-meta" version = "0.0.0" dependencies = [ "erc1155", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -833,7 +872,7 @@ name = "erc1155-user-mock-meta" version = "0.0.0" dependencies = [ "erc1155-user-mock", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -849,7 +888,7 @@ name = "erc20-meta" version = "0.0.0" dependencies = [ "erc20", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -865,14 +904,14 @@ name = "erc721-meta" version = "0.0.0" dependencies = [ "erc721", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -901,7 +940,7 @@ name = "esdt-system-sc-mock-meta" version = "0.0.0" dependencies = [ "esdt-system-sc-mock", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -917,7 +956,23 @@ name = "esdt-transfer-with-fee-meta" version = "0.0.0" dependencies = [ "esdt-transfer-with-fee", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", +] + +[[package]] +name = "exchange-features" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "multiversx-sc-scenario", +] + +[[package]] +name = "exchange-features-meta" +version = "0.0.0" +dependencies = [ + "exchange-features", + "multiversx-sc-meta-lib", ] [[package]] @@ -933,22 +988,22 @@ name = "factorial-meta" version = "0.0.0" dependencies = [ "factorial", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "factory-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "order-book-factory", ] [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "first-contract" @@ -964,14 +1019,14 @@ version = "0.0.0" dependencies = [ "first-contract", "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1020,24 +1075,40 @@ name = "formatted-message-features-meta" version = "0.0.0" dependencies = [ "formatted-message-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "forwarder" version = "0.0.0" +dependencies = [ + "multiversx-sc", + "multiversx-sc-scenario", +] + +[[package]] +name = "forwarder-legacy" +version = "0.0.0" dependencies = [ "multiversx-sc", "multiversx-sc-scenario", "vault", ] +[[package]] +name = "forwarder-legacy-meta" +version = "0.0.0" +dependencies = [ + "forwarder-legacy", + "multiversx-sc-meta-lib", +] + [[package]] name = "forwarder-meta" version = "0.0.0" dependencies = [ "forwarder", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1047,7 +1118,6 @@ dependencies = [ "multiversx-sc", "multiversx-sc-scenario", "multiversx-sc-wasm-adapter", - "vault", ] [[package]] @@ -1055,7 +1125,7 @@ name = "forwarder-queue-meta" version = "0.0.0" dependencies = [ "forwarder-queue", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1071,7 +1141,7 @@ name = "forwarder-raw-meta" version = "0.0.0" dependencies = [ "forwarder-raw", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1088,7 +1158,7 @@ name = "fractional-nfts-meta" version = "0.0.0" dependencies = [ "fractional-nfts", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1203,9 +1273,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -1216,9 +1286,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "globset" @@ -1235,15 +1305,15 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", "indexmap", "slab", @@ -1254,21 +1324,25 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "serde", +] [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1293,9 +1367,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1304,12 +1378,24 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", "pin-project-lite", ] @@ -1319,12 +1405,6 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "humantime" version = "2.1.0" @@ -1333,39 +1413,58 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", "http", "http-body", "httparse", - "httpdate", "itoa", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", + "http-body-util", "hyper", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -1396,12 +1495,13 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.2" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", + "serde", ] [[package]] @@ -1409,13 +1509,10 @@ name = "interact" version = "0.0.0" dependencies = [ "clap", - "forwarder-queue", - "multiversx-sc-modules", + "multiversx-sc", "multiversx-sc-snippets", - "promises-features", "serde", "toml", - "vault", ] [[package]] @@ -1424,6 +1521,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.12.1" @@ -1435,15 +1538,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1480,7 +1583,7 @@ name = "kitty-auction-meta" version = "0.0.0" dependencies = [ "kitty-auction", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1498,7 +1601,7 @@ name = "kitty-genetic-alg-meta" version = "0.0.0" dependencies = [ "kitty-genetic-alg", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1517,7 +1620,7 @@ name = "kitty-ownership-meta" version = "0.0.0" dependencies = [ "kitty-ownership", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1533,7 +1636,7 @@ name = "large-storage-meta" version = "0.0.0" dependencies = [ "large-storage", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1544,9 +1647,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "linked-list-repeat" @@ -1562,14 +1665,14 @@ name = "linked-list-repeat-meta" version = "0.0.0" dependencies = [ "linked-list-repeat", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-esdt-and-nft" @@ -1584,24 +1687,30 @@ name = "local-esdt-and-nft-meta" version = "0.0.0" dependencies = [ "local-esdt-and-nft", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", ] +[[package]] +name = "lockfree-object-pool" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" + [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lottery-erc20" @@ -1617,7 +1726,7 @@ name = "lottery-erc20-meta" version = "0.0.0" dependencies = [ "lottery-erc20", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1633,7 +1742,7 @@ name = "lottery-esdt-meta" version = "0.0.0" dependencies = [ "lottery-esdt", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1650,7 +1759,7 @@ name = "managed-map-features-meta" version = "0.0.0" dependencies = [ "managed-map-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1667,14 +1776,14 @@ name = "map-repeat-meta" version = "0.0.0" dependencies = [ "map-repeat", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" @@ -1684,18 +1793,18 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", @@ -1715,7 +1824,7 @@ name = "multi-contract-features-meta" version = "0.0.0" dependencies = [ "multi-contract-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1739,6 +1848,7 @@ version = "0.0.0" dependencies = [ "clap", "multisig", + "multiversx-sc", "multiversx-sc-modules", "multiversx-sc-scenario", "multiversx-sc-snippets", @@ -1751,7 +1861,7 @@ name = "multisig-meta" version = "0.0.0" dependencies = [ "multisig", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1769,9 +1879,9 @@ dependencies = [ [[package]] name = "multiversx-chain-vm" -version = "0.8.3" +version = "0.8.4" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "colored", "ed25519-dalek", "hex", @@ -1794,10 +1904,10 @@ checksum = "b59072fa0624b55ae5ae3fa6bfa91515bbeb4ac440214bc4a509e2c8806d6e9f" [[package]] name = "multiversx-price-aggregator-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "arrayvec", - "getrandom 0.2.12", + "getrandom 0.2.15", "multiversx-sc", "multiversx-sc-modules", "multiversx-sc-scenario", @@ -1810,32 +1920,34 @@ version = "0.0.0" dependencies = [ "multiversx-price-aggregator-sc", "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", "num-bigint", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -1845,7 +1957,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -1856,20 +1968,37 @@ dependencies = [ [[package]] name = "multiversx-sc-meta" -version = "0.47.5" +version = "0.50.3" dependencies = [ "clap", "colored", "common-path", "convert_case", "copy_dir", - "hex", - "lazy_static", "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", + "multiversx-sc-snippets", "pathdiff", "reqwest", "ruplacer", + "semver", + "serde", + "serde_json", + "tokio", + "toml", + "zip", +] + +[[package]] +name = "multiversx-sc-meta-lib" +version = "0.50.3" +dependencies = [ + "clap", + "colored", + "convert_case", + "hex", + "lazy_static", + "multiversx-sc", "rustc_version", "semver", "serde", @@ -1877,19 +2006,18 @@ dependencies = [ "toml", "wasmparser", "wasmprinter", - "zip", ] [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-scenario" -version = "0.47.5" +version = "0.50.3" dependencies = [ "base64", "bech32", @@ -1902,7 +2030,7 @@ dependencies = [ "multiversx-chain-vm", "multiversx-chain-vm-executor", "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "multiversx-sdk", "num-bigint", "num-traits", @@ -1911,32 +2039,35 @@ dependencies = [ "serde_json", "sha2 0.10.8", "tokio", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-snippets" -version = "0.47.5" +version = "0.50.3" dependencies = [ "base64", "env_logger", "futures", "hex", "log", + "multiversx-chain-scenario-format", "multiversx-sc-scenario", "multiversx-sdk", + "serde_json", "tokio", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sdk" -version = "0.3.2" +version = "0.4.1" dependencies = [ "anyhow", "base64", @@ -1945,6 +2076,7 @@ dependencies = [ "hex", "hmac", "itertools", + "log", "pbkdf2", "pem", "rand 0.8.5", @@ -1960,7 +2092,7 @@ dependencies = [ [[package]] name = "multiversx-wegld-swap-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", "multiversx-sc-modules", @@ -1972,7 +2104,7 @@ name = "multiversx-wegld-swap-sc-meta" version = "0.0.0" dependencies = [ "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "multiversx-wegld-swap-sc", ] @@ -1989,11 +2121,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -2017,7 +2148,7 @@ dependencies = [ name = "nft-minter-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "nft-minter", ] @@ -2033,7 +2164,7 @@ dependencies = [ name = "nft-storage-prepay-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "nft-storage-prepay", ] @@ -2050,7 +2181,7 @@ dependencies = [ name = "nft-subscription-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "nft-subscription", ] @@ -2065,11 +2196,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -2085,9 +2215,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -2104,9 +2234,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" dependencies = [ "memchr", ] @@ -2119,17 +2249,17 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.63" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "cfg-if", "foreign-types", "libc", @@ -2157,9 +2287,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.99" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -2187,7 +2317,7 @@ dependencies = [ name = "pair-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "order-book-pair", ] @@ -2203,7 +2333,7 @@ dependencies = [ name = "panic-message-features-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "panic-message-features", ] @@ -2211,7 +2341,6 @@ dependencies = [ name = "parent" version = "0.0.0" dependencies = [ - "child", "multiversx-sc", "multiversx-sc-scenario", ] @@ -2221,15 +2350,15 @@ name = "parent-meta" version = "0.0.0" dependencies = [ "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "parent", ] [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2237,15 +2366,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -2266,10 +2395,14 @@ dependencies = [ name = "payable-features-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "payable-features", ] +[[package]] +name = "payload-macro-generator" +version = "0.1.0" + [[package]] name = "pbkdf2" version = "0.12.2" @@ -2281,9 +2414,9 @@ dependencies = [ [[package]] name = "pem" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ "base64", "serde", @@ -2295,11 +2428,31 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2319,15 +2472,15 @@ dependencies = [ name = "ping-pong-egld-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "ping-pong-egld", ] [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "ppv-lite86" @@ -2337,9 +2490,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -2349,14 +2502,13 @@ name = "promises-features" version = "0.0.0" dependencies = [ "multiversx-sc", - "vault", ] [[package]] name = "promises-features-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "promises-features", ] @@ -2373,7 +2525,7 @@ dependencies = [ name = "proxy-pause-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "proxy-pause", ] @@ -2390,7 +2542,7 @@ dependencies = [ name = "proxy-test-first-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "proxy-test-first", ] @@ -2406,7 +2558,7 @@ dependencies = [ name = "proxy-test-second-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "proxy-test-second", ] @@ -2423,15 +2575,15 @@ dependencies = [ name = "queue-repeat-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "queue-repeat", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -2505,7 +2657,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.15", ] [[package]] @@ -2546,24 +2698,24 @@ dependencies = [ name = "recursive-caller-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "recursive-caller", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -2573,9 +2725,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -2584,26 +2736,29 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" -version = "0.11.24" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ "base64", "bytes", "encoding_rs", + "futures-channel", "futures-core", "futures-util", "h2", "http", "http-body", + "http-body-util", "hyper", "hyper-tls", + "hyper-util", "ipnet", "js-sys", "log", @@ -2641,7 +2796,7 @@ dependencies = [ name = "rewards-distribution-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "rewards-distribution", ] @@ -2671,7 +2826,7 @@ dependencies = [ name = "rust-snippets-generator-test-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "rust-snippets-generator-test", ] @@ -2694,15 +2849,15 @@ dependencies = [ name = "rust-testing-framework-tester-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "rust-testing-framework-tester", ] [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" @@ -2715,11 +2870,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -2728,18 +2883,25 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ "base64", + "rustls-pki-types", ] +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -2750,6 +2912,22 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scenario-tester" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "multiversx-sc-scenario", +] + +[[package]] +name = "scenario-tester-meta" +version = "0.0.0" +dependencies = [ + "multiversx-sc-meta-lib", + "scenario-tester", +] + [[package]] name = "schannel" version = "0.1.23" @@ -2778,17 +2956,17 @@ name = "second-contract-meta" version = "0.0.0" dependencies = [ "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "second-contract", ] [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -2797,9 +2975,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -2818,15 +2996,15 @@ dependencies = [ name = "seed-nft-minter-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "seed-nft-minter", ] [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "send-tx-repeat" @@ -2840,24 +3018,24 @@ dependencies = [ name = "send-tx-repeat-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "send-tx-repeat", ] [[package]] name = "serde" -version = "1.0.196" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -2866,9 +3044,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "indexmap", "itoa", @@ -2878,9 +3056,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", @@ -2889,9 +3067,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -2921,7 +3099,7 @@ dependencies = [ name = "set-repeat-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "set-repeat", ] @@ -2961,9 +3139,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -2974,6 +3152,12 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "single-value-repeat" version = "0.0.0" @@ -2987,7 +3171,7 @@ dependencies = [ name = "single-value-repeat-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "single-value-repeat", ] @@ -3002,18 +3186,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3028,15 +3212,15 @@ dependencies = [ name = "str-repeat-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "str-repeat", ] [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" @@ -3046,9 +3230,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -3084,9 +3268,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", @@ -3094,6 +3278,26 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -3121,15 +3325,15 @@ dependencies = [ name = "token-release-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "token-release", ] [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -3167,23 +3371,22 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.10" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" dependencies = [ "indexmap", "serde", @@ -3194,18 +3397,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.4" +version = "0.22.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951" +checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" dependencies = [ "indexmap", "serde", @@ -3214,6 +3417,27 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -3253,7 +3477,7 @@ dependencies = [ name = "transfer-role-features-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "transfer-role-features", ] @@ -3296,6 +3520,12 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "url" version = "2.5.0" @@ -3312,7 +3542,7 @@ name = "use-module" version = "0.0.0" dependencies = [ "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "multiversx-sc-modules", "multiversx-sc-scenario", ] @@ -3321,7 +3551,7 @@ dependencies = [ name = "use-module-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "use-module", ] @@ -3343,7 +3573,7 @@ dependencies = [ name = "vault-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "vault", ] @@ -3366,7 +3596,7 @@ dependencies = [ name = "vec-repeat-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "vec-repeat", ] @@ -3378,9 +3608,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -3409,9 +3639,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3419,9 +3649,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -3434,9 +3664,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3446,9 +3676,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3456,9 +3686,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -3469,26 +3699,29 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasmparser" -version = "0.121.0" +version = "0.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953cf6a7606ab31382cb1caa5ae403e77ba70c7f8e12eeda167e7040d42bfda8" +checksum = "dd921789c9dcc495f589cb37d200155dee65b4a4beeb853323b5e24e0a5f9c58" dependencies = [ - "bitflags 2.4.2", + "ahash", + "bitflags 2.5.0", + "hashbrown", "indexmap", "semver", + "serde", ] [[package]] name = "wasmprinter" -version = "0.2.78" +version = "0.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e32c13c59fdc64d3f6998a1d52eb1d362b6904a88b754190ccb85661ad577a" +checksum = "0700bdace4821e6c694617938500ae9999946df464bb13219c16570f8b6f202f" dependencies = [ "anyhow", "wasmparser", @@ -3496,45 +3729,23 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] -[[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.48.0" @@ -3550,7 +3761,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -3570,17 +3781,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -3591,9 +3803,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -3603,9 +3815,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -3615,9 +3827,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -3627,9 +3845,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -3639,9 +3857,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -3651,9 +3869,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -3663,34 +3881,54 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.5.39" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29" +checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.50.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" dependencies = [ "cfg-if", "windows-sys 0.48.0", ] +[[package]] +name = "zerocopy" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -3708,12 +3946,31 @@ dependencies = [ [[package]] name = "zip" -version = "0.6.6" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "1dd56a4d5921bc2f99947ac5b3abe5f510b1be7376fdc5e9fce4a23c6a93e87c" dependencies = [ - "byteorder", + "arbitrary", "crc32fast", "crossbeam-utils", + "displaydoc", "flate2", + "indexmap", + "memchr", + "thiserror", + "zopfli", +] + +[[package]] +name = "zopfli" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +dependencies = [ + "bumpalo", + "crc32fast", + "lockfree-object-pool", + "log", + "once_cell", + "simd-adler32", ] diff --git a/Cargo.toml b/Cargo.toml index f2cc134137..345b8670a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "framework/base", "framework/derive", "framework/meta", + "framework/meta-lib", "framework/scenario", "framework/snippets", "framework/wasm-adapter", @@ -16,7 +17,7 @@ members = [ "sdk/scenario-format", "tools/mxpy-snippet-generator", - "tools/coverage-renderer", + "tools/payload-macro-generator", "vm", @@ -126,6 +127,8 @@ members = [ "contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta", "contracts/feature-tests/composability/forwarder", "contracts/feature-tests/composability/forwarder/meta", + "contracts/feature-tests/composability/forwarder-legacy", + "contracts/feature-tests/composability/forwarder-legacy/meta", "contracts/feature-tests/composability/forwarder-queue", "contracts/feature-tests/composability/forwarder-queue/meta", "contracts/feature-tests/composability/forwarder-raw", @@ -160,6 +163,8 @@ members = [ "contracts/feature-tests/erc-style-contracts/lottery-erc20/meta", "contracts/feature-tests/esdt-system-sc-mock", "contracts/feature-tests/esdt-system-sc-mock/meta", + "contracts/feature-tests/exchange-features", + "contracts/feature-tests/exchange-features/meta", "contracts/feature-tests/formatted-message-features", "contracts/feature-tests/formatted-message-features/meta", "contracts/feature-tests/managed-map-features", @@ -174,6 +179,8 @@ members = [ "contracts/feature-tests/rust-snippets-generator-test/meta", "contracts/feature-tests/rust-testing-framework-tester", "contracts/feature-tests/rust-testing-framework-tester/meta", + "contracts/feature-tests/scenario-tester", + "contracts/feature-tests/scenario-tester/meta", "contracts/feature-tests/use-module", "contracts/feature-tests/use-module/meta", ] diff --git a/contracts/benchmarks/large-storage/Cargo.toml b/contracts/benchmarks/large-storage/Cargo.toml index 804f964141..cf214259d5 100644 --- a/contracts/benchmarks/large-storage/Cargo.toml +++ b/contracts/benchmarks/large-storage/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/large_storage.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/benchmarks/large-storage/meta/Cargo.toml b/contracts/benchmarks/large-storage/meta/Cargo.toml index 7516ee6f65..d1a53cc5bf 100644 --- a/contracts/benchmarks/large-storage/meta/Cargo.toml +++ b/contracts/benchmarks/large-storage/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.large-storage] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/benchmarks/large-storage/meta/src/main.rs b/contracts/benchmarks/large-storage/meta/src/main.rs index fc0906971a..37d0f0ad71 100644 --- a/contracts/benchmarks/large-storage/meta/src/main.rs +++ b/contracts/benchmarks/large-storage/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/benchmarks/large-storage/tests/large_storage_scenario_rs_test.rs b/contracts/benchmarks/large-storage/tests/large_storage_scenario_rs_test.rs index 38297fd2f2..4a74775c67 100644 --- a/contracts/benchmarks/large-storage/tests/large_storage_scenario_rs_test.rs +++ b/contracts/benchmarks/large-storage/tests/large_storage_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/benchmarks/large-storage"); blockchain.register_contract( "mxsc:output/large-storage.mxsc.json", large_storage::ContractBuilder, diff --git a/contracts/benchmarks/large-storage/wasm/Cargo.lock b/contracts/benchmarks/large-storage/wasm/Cargo.lock index fa29ad6f14..cbc4f52165 100755 --- a/contracts/benchmarks/large-storage/wasm/Cargo.lock +++ b/contracts/benchmarks/large-storage/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/large-storage/wasm/Cargo.toml b/contracts/benchmarks/large-storage/wasm/Cargo.toml index 3442101383..be44a1813e 100644 --- a/contracts/benchmarks/large-storage/wasm/Cargo.toml +++ b/contracts/benchmarks/large-storage/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.large-storage] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/benchmarks/large-storage/wasm/src/lib.rs b/contracts/benchmarks/large-storage/wasm/src/lib.rs index 7637992615..fcaf9afbee 100644 --- a/contracts/benchmarks/large-storage/wasm/src/lib.rs +++ b/contracts/benchmarks/large-storage/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/benchmarks/mappers/benchmark-common/Cargo.toml b/contracts/benchmarks/mappers/benchmark-common/Cargo.toml index f2db85ecfe..b912617531 100644 --- a/contracts/benchmarks/mappers/benchmark-common/Cargo.toml +++ b/contracts/benchmarks/mappers/benchmark-common/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/linked-list-repeat/Cargo.toml b/contracts/benchmarks/mappers/linked-list-repeat/Cargo.toml index 558fbb4720..087afd185e 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/Cargo.toml +++ b/contracts/benchmarks/mappers/linked-list-repeat/Cargo.toml @@ -13,9 +13,9 @@ path = "../benchmark-common" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/linked-list-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/linked-list-repeat/meta/Cargo.toml index 3a2b64389a..a55bf6ff24 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/linked-list-repeat/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.linked-list-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/benchmarks/mappers/linked-list-repeat/meta/src/main.rs b/contracts/benchmarks/mappers/linked-list-repeat/meta/src/main.rs index 1c807b9ca5..2daa700b93 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/meta/src/main.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/benchmarks/mappers/linked-list-repeat/sc-config.toml b/contracts/benchmarks/mappers/linked-list-repeat/sc-config.toml new file mode 100644 index 0000000000..b26db4379a --- /dev/null +++ b/contracts/benchmarks/mappers/linked-list-repeat/sc-config.toml @@ -0,0 +1,5 @@ +[[proxy]] +path = "src/linked_list_repeat_proxy.rs" +[[proxy.path-rename]] +from = "benchmark_common::example_struct" +to = "benchmark_common" diff --git a/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs b/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs index 640fcb3968..40dfcba638 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs @@ -3,6 +3,7 @@ multiversx_sc::imports!(); use benchmark_common::ExampleStruct; +pub mod linked_list_repeat_proxy; #[multiversx_sc::contract] pub trait LinkedListRepeat: benchmark_common::BenchmarkCommon { diff --git a/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat_proxy.rs b/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat_proxy.rs new file mode 100644 index 0000000000..100ff19071 --- /dev/null +++ b/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat_proxy.rs @@ -0,0 +1,166 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct LinkedListRepeatProxy; + +impl TxProxyTrait for LinkedListRepeatProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = LinkedListRepeatProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + LinkedListRepeatProxyMethods { wrapped_tx: tx } + } +} + +pub struct LinkedListRepeatProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl LinkedListRepeatProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl LinkedListRepeatProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn add< + Arg0: ProxyArg, + Arg1: ProxyArg>, + >( + self, + num_repeats: Arg0, + value: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("add") + .argument(&num_repeats) + .argument(&value) + .original_result() + } + + pub fn count< + Arg0: ProxyArg>, + >( + self, + value: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("count") + .argument(&value) + .original_result() + } + + pub fn remove< + Arg0: ProxyArg, + >( + self, + num_repeats: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("remove") + .argument(&num_repeats) + .original_result() + } + + pub fn bench( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("bench") + .original_result() + } + + pub fn add_struct< + Arg0: ProxyArg, + Arg1: ProxyArg>, + >( + self, + num_repeats: Arg0, + value: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("add_struct") + .argument(&num_repeats) + .argument(&value) + .original_result() + } + + pub fn count_struct< + Arg0: ProxyArg>, + >( + self, + value: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("count_struct") + .argument(&value) + .original_result() + } + + pub fn remove_struct< + Arg0: ProxyArg, + >( + self, + num_repeats: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("remove_struct") + .argument(&num_repeats) + .original_result() + } + + pub fn bench_struct( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("bench_struct") + .original_result() + } +} diff --git a/contracts/benchmarks/mappers/linked-list-repeat/tests/linked_list_repeat_blackbox_test.rs b/contracts/benchmarks/mappers/linked-list-repeat/tests/linked_list_repeat_blackbox_test.rs index 47af800bb8..aa2edf237f 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/tests/linked_list_repeat_blackbox_test.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/tests/linked_list_repeat_blackbox_test.rs @@ -1,78 +1,76 @@ use benchmark_common::ExampleStruct; -use linked_list_repeat::ProxyTrait; -use multiversx_sc::types::{MultiValueEncoded, TokenIdentifier}; -use multiversx_sc_scenario::{api::StaticApi, scenario_model::*, *}; +use linked_list_repeat::linked_list_repeat_proxy; +use multiversx_sc_scenario::imports::*; -const WASM_PATH_EXPR: &str = "mxsc:output/linked-list-repeat.mxsc.json"; +const WASM_PATH: MxscPath = MxscPath::new("output/linked-list-repeat.mxsc.json"); +const LLR_ADDRESS: TestSCAddress = TestSCAddress::new("llr"); +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/benchmarks/mappers/linked-list-repeat"); - blockchain.register_contract(WASM_PATH_EXPR, linked_list_repeat::ContractBuilder); + blockchain.register_contract(WASM_PATH, linked_list_repeat::ContractBuilder); blockchain } fn setup() -> ScenarioWorld { let mut world = world(); - let llr_code = world.code_expression(WASM_PATH_EXPR); + world + .account(OWNER_ADDRESS) + .nonce(1) + .new_address(OWNER_ADDRESS, 1, LLR_ADDRESS); world - .set_state_step( - SetStateStep::new() - .put_account("address:owner", Account::new().nonce(1)) - .new_address("address:owner", 1, "sc:llr"), - ) - .sc_deploy( - ScDeployStep::new() - .from("address:owner") - .code(llr_code) - .expect(TxExpect::ok().no_result()), - ); + .tx() + .from(OWNER_ADDRESS) + .typed(linked_list_repeat_proxy::LinkedListRepeatProxy) + .init() + .code(WASM_PATH) + .run(); world } #[test] fn linked_list_repeat_blackbox_raw() { let mut world = setup(); - let mut contract = ContractInfo::>::new("sc:llr"); let num_repeats = 5usize; world - .sc_call( - ScCallStep::new() - .from("address:owner") - .to("sc:llr") - .call(contract.add(num_repeats, "test--")) - .expect(TxExpect::ok().no_result()), - ) - .sc_call( - ScCallStep::new() - .from("address:owner") - .to("sc:llr") - .call(contract.count("test--\x00\x00\x00\x04")) - .expect(TxExpect::ok().result("1")), - ) - .sc_query_use_result( - ScQueryStep::new().to("sc:llr").call(contract.bench()), - |tr: TypedResponse>| { - let result = tr.result.unwrap().into_iter().collect::>(); - assert_eq!(result.len(), num_repeats); - for (index, item) in result.iter().enumerate() { - let index_str = - String::from_utf8((index as u32).to_be_bytes().to_vec()).unwrap(); - let expected = format!("test--{}", index_str); - assert_eq!(item, &expected); - } - }, - ); + .tx() + .from(OWNER_ADDRESS) + .to(LLR_ADDRESS) + .typed(linked_list_repeat_proxy::LinkedListRepeatProxy) + .add(num_repeats, "test--") + .run(); + + world + .tx() + .from(OWNER_ADDRESS) + .to(LLR_ADDRESS) + .typed(linked_list_repeat_proxy::LinkedListRepeatProxy) + .count("test--\x00\x00\x00\x04") + .returns(ExpectValue(1u32)) + .run(); + + let items = world + .query() + .to(LLR_ADDRESS) + .typed(linked_list_repeat_proxy::LinkedListRepeatProxy) + .bench() + .returns(ReturnsResult) + .run(); + + for (index, item) in items.into_iter().enumerate() { + let index_str = String::from_utf8((index as u32).to_be_bytes().to_vec()).unwrap(); + let expected = format!("test--{}", index_str); + assert_eq!(item.to_string(), expected); + } } #[test] fn linked_list_repeat_struct_blackbox_raw() { let mut world = setup(); - let mut contract = ContractInfo::>::new("sc:llr"); let mut example = ExampleStruct { first_token_id: TokenIdentifier::from_esdt_bytes(b"str:TESTTOK-1234"), @@ -82,20 +80,22 @@ fn linked_list_repeat_struct_blackbox_raw() { second_token_nonce: 0, second_token_amount: multiversx_sc::types::BigUint::from(1_000_000_000_000_000_000u64), }; - world.sc_call( - ScCallStep::new() - .from("address:owner") - .to("sc:llr") - .call(contract.add_struct(5u32, example.clone())) - .expect(TxExpect::ok().no_result()), - ); + + world + .tx() + .from(OWNER_ADDRESS) + .to(LLR_ADDRESS) + .typed(linked_list_repeat_proxy::LinkedListRepeatProxy) + .add_struct(5u32, example.clone()) + .run(); example.first_token_nonce = 3; example.second_token_nonce = 3; - world.sc_call( - ScCallStep::new() - .from("address:owner") - .to("sc:llr") - .call(contract.count_struct(example)) - .expect(TxExpect::ok().result("1")), - ); + world + .tx() + .from(OWNER_ADDRESS) + .to(LLR_ADDRESS) + .typed(linked_list_repeat_proxy::LinkedListRepeatProxy) + .count_struct(example) + .returns(ExpectValue(1u32)) + .run(); } diff --git a/contracts/benchmarks/mappers/linked-list-repeat/tests/scenario_rs_test.rs b/contracts/benchmarks/mappers/linked-list-repeat/tests/scenario_rs_test.rs index c7b91be79e..442754a06b 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/tests/scenario_rs_test.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/tests/scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/benchmarks/mappers/linked-list-repeat"); blockchain.register_contract( "mxsc:output/linked-list-repeat.mxsc.json", diff --git a/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.lock index b81c08488a..a7c0ef294b 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.lock @@ -10,9 +10,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "benchmark-common" @@ -23,9 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -63,26 +63,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -92,7 +94,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -103,7 +105,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.toml index 8682d7b966..57ac205ace 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.linked-list-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs index 626c63d138..1e79aa533a 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/benchmarks/mappers/map-repeat/Cargo.toml b/contracts/benchmarks/mappers/map-repeat/Cargo.toml index 63d397512e..ecad093dd8 100644 --- a/contracts/benchmarks/mappers/map-repeat/Cargo.toml +++ b/contracts/benchmarks/mappers/map-repeat/Cargo.toml @@ -13,9 +13,9 @@ path = "../benchmark-common" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/map-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/map-repeat/meta/Cargo.toml index 9325ed7ae6..51ac2a8289 100644 --- a/contracts/benchmarks/mappers/map-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/map-repeat/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.map-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/benchmarks/mappers/map-repeat/meta/src/main.rs b/contracts/benchmarks/mappers/map-repeat/meta/src/main.rs index 0ff660f2a3..5f7e77ee71 100644 --- a/contracts/benchmarks/mappers/map-repeat/meta/src/main.rs +++ b/contracts/benchmarks/mappers/map-repeat/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/benchmarks/mappers/map-repeat/tests/scenario_rs_test.rs b/contracts/benchmarks/mappers/map-repeat/tests/scenario_rs_test.rs index 8ae30eaf45..ce7eabb8eb 100644 --- a/contracts/benchmarks/mappers/map-repeat/tests/scenario_rs_test.rs +++ b/contracts/benchmarks/mappers/map-repeat/tests/scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/benchmarks/mappers/map-repeat"); blockchain.register_contract( "mxsc:output/map-repeat.mxsc.json", diff --git a/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.lock index 54e27ced42..b4efda6121 100644 --- a/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.lock @@ -10,9 +10,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "benchmark-common" @@ -23,9 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -63,26 +63,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -92,7 +94,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -103,7 +105,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.toml index 62e8789c3b..377de005ec 100644 --- a/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.map-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/benchmarks/mappers/map-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/map-repeat/wasm/src/lib.rs index cd006d5384..3d670243ff 100644 --- a/contracts/benchmarks/mappers/map-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/map-repeat/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 8 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/benchmarks/mappers/queue-repeat/Cargo.toml b/contracts/benchmarks/mappers/queue-repeat/Cargo.toml index a9f7dd1a38..a1b4a04418 100644 --- a/contracts/benchmarks/mappers/queue-repeat/Cargo.toml +++ b/contracts/benchmarks/mappers/queue-repeat/Cargo.toml @@ -13,9 +13,9 @@ path = "../benchmark-common" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/queue-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/queue-repeat/meta/Cargo.toml index 29f1dc78c8..88e57259b9 100644 --- a/contracts/benchmarks/mappers/queue-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/queue-repeat/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.queue-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/benchmarks/mappers/queue-repeat/meta/src/main.rs b/contracts/benchmarks/mappers/queue-repeat/meta/src/main.rs index ea11f70b22..d80481790a 100644 --- a/contracts/benchmarks/mappers/queue-repeat/meta/src/main.rs +++ b/contracts/benchmarks/mappers/queue-repeat/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/benchmarks/mappers/queue-repeat/tests/scenario_rs_test.rs b/contracts/benchmarks/mappers/queue-repeat/tests/scenario_rs_test.rs index 4e7ac9ba66..9f4596ae21 100644 --- a/contracts/benchmarks/mappers/queue-repeat/tests/scenario_rs_test.rs +++ b/contracts/benchmarks/mappers/queue-repeat/tests/scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/benchmarks/mappers/queue-repeat"); blockchain.register_contract( "mxsc:output/queue-repeat.mxsc.json", diff --git a/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.lock index a92443bd08..0cea6bf94d 100644 --- a/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.lock @@ -10,9 +10,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "benchmark-common" @@ -23,9 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -47,26 +47,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -76,7 +78,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -87,7 +89,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,18 +105,18 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -137,9 +139,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.toml index 9c4d336e91..9bea063fa5 100644 --- a/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.queue-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs index 9eb5f3ac5b..887fb0c6e6 100644 --- a/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/benchmarks/mappers/set-repeat/Cargo.toml b/contracts/benchmarks/mappers/set-repeat/Cargo.toml index f62ee44aa2..e605ddc5be 100644 --- a/contracts/benchmarks/mappers/set-repeat/Cargo.toml +++ b/contracts/benchmarks/mappers/set-repeat/Cargo.toml @@ -13,9 +13,9 @@ path = "../benchmark-common" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/set-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/set-repeat/meta/Cargo.toml index 7e05b0d40c..5d1766c590 100644 --- a/contracts/benchmarks/mappers/set-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/set-repeat/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.set-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/benchmarks/mappers/set-repeat/meta/src/main.rs b/contracts/benchmarks/mappers/set-repeat/meta/src/main.rs index a74da46b49..a93edece6c 100644 --- a/contracts/benchmarks/mappers/set-repeat/meta/src/main.rs +++ b/contracts/benchmarks/mappers/set-repeat/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/benchmarks/mappers/set-repeat/tests/scenario_rs_test.rs b/contracts/benchmarks/mappers/set-repeat/tests/scenario_rs_test.rs index ba9fda4f46..ec2352ec65 100644 --- a/contracts/benchmarks/mappers/set-repeat/tests/scenario_rs_test.rs +++ b/contracts/benchmarks/mappers/set-repeat/tests/scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/benchmarks/mappers/set-repeat"); blockchain.register_contract( "mxsc:output/set-repeat.mxsc.json", diff --git a/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.lock index 5e5d756355..e1fa1f01cd 100644 --- a/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.lock @@ -10,9 +10,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "benchmark-common" @@ -23,9 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -47,26 +47,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -76,7 +78,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -87,7 +89,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,27 +105,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.toml index 7dcc58ebd4..4bd27ae74a 100644 --- a/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.set-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs index 26158eb9da..7a1a61db74 100644 --- a/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/benchmarks/mappers/single-value-repeat/Cargo.toml b/contracts/benchmarks/mappers/single-value-repeat/Cargo.toml index c4f974f557..f61040bdf7 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/Cargo.toml +++ b/contracts/benchmarks/mappers/single-value-repeat/Cargo.toml @@ -13,9 +13,9 @@ path = "../benchmark-common" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/single-value-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/single-value-repeat/meta/Cargo.toml index a10f248f31..f715ca18b6 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/single-value-repeat/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.single-value-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/benchmarks/mappers/single-value-repeat/meta/src/main.rs b/contracts/benchmarks/mappers/single-value-repeat/meta/src/main.rs index 2ac95acafb..6caf8e460b 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/meta/src/main.rs +++ b/contracts/benchmarks/mappers/single-value-repeat/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/benchmarks/mappers/single-value-repeat/tests/scenario_rs_test.rs b/contracts/benchmarks/mappers/single-value-repeat/tests/scenario_rs_test.rs index cf43c6d95f..d235f08b2e 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/tests/scenario_rs_test.rs +++ b/contracts/benchmarks/mappers/single-value-repeat/tests/scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/benchmarks/mappers/single-value-repeat"); blockchain.register_contract( "mxsc:output/single-value-repeat.mxsc.json", diff --git a/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.lock index 558c2921c6..5a39b2d833 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.lock @@ -10,9 +10,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "benchmark-common" @@ -23,9 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -47,26 +47,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -76,7 +78,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -87,7 +89,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,27 +105,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.toml index b738172a26..9f42c4a6b8 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.single-value-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/benchmarks/mappers/single-value-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/single-value-repeat/wasm/src/lib.rs index ced8d7e061..0c377e4821 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/single-value-repeat/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 8 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/benchmarks/mappers/vec-repeat/Cargo.toml b/contracts/benchmarks/mappers/vec-repeat/Cargo.toml index 68f1484056..37818e8a22 100644 --- a/contracts/benchmarks/mappers/vec-repeat/Cargo.toml +++ b/contracts/benchmarks/mappers/vec-repeat/Cargo.toml @@ -13,9 +13,9 @@ path = "../benchmark-common" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/vec-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/vec-repeat/meta/Cargo.toml index d3b013bb67..a8cd88703e 100644 --- a/contracts/benchmarks/mappers/vec-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/vec-repeat/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.vec-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/benchmarks/mappers/vec-repeat/meta/src/main.rs b/contracts/benchmarks/mappers/vec-repeat/meta/src/main.rs index 6beb56de58..2eb69e96fa 100644 --- a/contracts/benchmarks/mappers/vec-repeat/meta/src/main.rs +++ b/contracts/benchmarks/mappers/vec-repeat/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/benchmarks/mappers/vec-repeat/tests/scenario_rs_test.rs b/contracts/benchmarks/mappers/vec-repeat/tests/scenario_rs_test.rs index 49407163df..d47d38ec79 100644 --- a/contracts/benchmarks/mappers/vec-repeat/tests/scenario_rs_test.rs +++ b/contracts/benchmarks/mappers/vec-repeat/tests/scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/benchmarks/mappers/vec-repeat"); blockchain.register_contract( "mxsc:output/vec-repeat.mxsc.json", diff --git a/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.lock index 2feba1a867..6addb7a28e 100644 --- a/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.lock @@ -10,9 +10,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "benchmark-common" @@ -23,9 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -47,26 +47,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -76,7 +78,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -87,7 +89,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,27 +105,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -140,15 +142,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -161,6 +163,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "vec-repeat" version = "0.0.0" diff --git a/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.toml index fe03b05162..5b21c4fb5c 100644 --- a/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.vec-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs index 353338d425..6f915470d8 100644 --- a/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/benchmarks/send-tx-repeat/Cargo.toml b/contracts/benchmarks/send-tx-repeat/Cargo.toml index 5517cf4101..b32e5ba27a 100644 --- a/contracts/benchmarks/send-tx-repeat/Cargo.toml +++ b/contracts/benchmarks/send-tx-repeat/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/send_tx_repeat.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/benchmarks/send-tx-repeat/meta/Cargo.toml b/contracts/benchmarks/send-tx-repeat/meta/Cargo.toml index 13920dbf06..133eb29cd4 100644 --- a/contracts/benchmarks/send-tx-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/send-tx-repeat/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.send-tx-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/benchmarks/send-tx-repeat/meta/src/main.rs b/contracts/benchmarks/send-tx-repeat/meta/src/main.rs index 4243a30329..37a1002695 100644 --- a/contracts/benchmarks/send-tx-repeat/meta/src/main.rs +++ b/contracts/benchmarks/send-tx-repeat/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/benchmarks/send-tx-repeat/src/send_tx_repeat.rs b/contracts/benchmarks/send-tx-repeat/src/send_tx_repeat.rs index da74343a01..ade5321f68 100644 --- a/contracts/benchmarks/send-tx-repeat/src/send_tx_repeat.rs +++ b/contracts/benchmarks/send-tx-repeat/src/send_tx_repeat.rs @@ -11,7 +11,7 @@ pub trait SendTxRepeat { #[endpoint] fn repeat(&self, to: ManagedAddress, amount: BigUint, times: usize) { for _ in 0..times { - self.send().direct_egld(&to, &amount); + self.tx().to(&to).egld(&amount).transfer(); } } } diff --git a/contracts/benchmarks/send-tx-repeat/wasm/Cargo.lock b/contracts/benchmarks/send-tx-repeat/wasm/Cargo.lock index f9dfe9d5b2..362f56acd6 100755 --- a/contracts/benchmarks/send-tx-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/send-tx-repeat/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/send-tx-repeat/wasm/Cargo.toml b/contracts/benchmarks/send-tx-repeat/wasm/Cargo.toml index 8f631f3518..f02b983c3d 100644 --- a/contracts/benchmarks/send-tx-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/send-tx-repeat/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.send-tx-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/benchmarks/send-tx-repeat/wasm/src/lib.rs b/contracts/benchmarks/send-tx-repeat/wasm/src/lib.rs index 756fb62d43..acc9b4d8da 100644 --- a/contracts/benchmarks/send-tx-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/send-tx-repeat/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 3 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/benchmarks/str-repeat/Cargo.toml b/contracts/benchmarks/str-repeat/Cargo.toml index 123cfae104..52f8e11c18 100644 --- a/contracts/benchmarks/str-repeat/Cargo.toml +++ b/contracts/benchmarks/str-repeat/Cargo.toml @@ -8,11 +8,14 @@ publish = false [lib] path = "src/str_repeat.rs" +[features] +managed-buffer-builder-cached = ["multiversx-sc/managed-buffer-builder-cached"] + [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/benchmarks/str-repeat/meta/Cargo.toml b/contracts/benchmarks/str-repeat/meta/Cargo.toml index 5a5d4b5d28..a4ef451bd6 100644 --- a/contracts/benchmarks/str-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/str-repeat/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.str-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/benchmarks/str-repeat/meta/src/main.rs b/contracts/benchmarks/str-repeat/meta/src/main.rs index c2a54d0039..327abc92ad 100644 --- a/contracts/benchmarks/str-repeat/meta/src/main.rs +++ b/contracts/benchmarks/str-repeat/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/benchmarks/str-repeat/sc-config.toml b/contracts/benchmarks/str-repeat/sc-config.toml index a850f32470..964b5500c8 100644 --- a/contracts/benchmarks/str-repeat/sc-config.toml +++ b/contracts/benchmarks/str-repeat/sc-config.toml @@ -1,6 +1,16 @@ [settings] main = "str-repeat" -# the only purpose of this config is to specify the allocator [contracts.str-repeat] allocator = "leaking" + +[contracts.str-repeat-mb-builder-basic] +add-unlabelled = false +add-labels = ["mb-builder"] +add-endpoints = ["init"] + +[contracts.str-repeat-mb-builder-cached] +add-unlabelled = false +add-labels = ["mb-builder"] +add-endpoints = ["init"] +features = ["managed-buffer-builder-cached"] diff --git a/contracts/benchmarks/str-repeat/scenarios/mb_builder_basic.scen.json b/contracts/benchmarks/str-repeat/scenarios/mb_builder_basic.scen.json new file mode 100644 index 0000000000..81086d866e --- /dev/null +++ b/contracts/benchmarks/str-repeat/scenarios/mb_builder_basic.scen.json @@ -0,0 +1,80 @@ +{ + "name": "str-repeat", + "steps": [ + { + "step": "setState", + "accounts": { + "address:owner": { + "nonce": "0", + "balance": "0" + }, + "sc:contract": { + "code": "mxsc:../output/str-repeat-mb-builder-basic.mxsc.json" + } + } + }, + { + "step": "scCall", + "id": "benchmark-mb-builder-basic-10", + "comment": "code is smaller, so basic wins here", + "tx": { + "from": "address:owner", + "to": "sc:contract", + "function": "mb_builder_benchmark", + "arguments": [ + "0x01020304", + "10" + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": "*", + "status": "", + "gas": "8855882" + } + }, + { + "step": "scCall", + "id": "benchmark-mb-builder-basic-tipping-point", + "comment": "the caching optimization starts to compensate the larger code size", + "tx": { + "from": "address:owner", + "to": "sc:contract", + "function": "mb_builder_benchmark", + "arguments": [ + "0x01020304", + "22" + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": "*", + "status": "", + "gas": "8778242" + } + }, + { + "step": "scCall", + "id": "benchmark-mb-builder-basic", + "comment": "for many repeats, the cached version wins", + "tx": { + "from": "address:owner", + "to": "sc:contract", + "function": "mb_builder_benchmark", + "arguments": [ + "0x01020304", + "10000" + ], + "gasLimit": "10,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": "*", + "status": "", + "gas": "9934220582" + } + } + ] +} diff --git a/contracts/benchmarks/str-repeat/scenarios/mb_builder_cached.scen.json b/contracts/benchmarks/str-repeat/scenarios/mb_builder_cached.scen.json new file mode 100644 index 0000000000..9261fabd37 --- /dev/null +++ b/contracts/benchmarks/str-repeat/scenarios/mb_builder_cached.scen.json @@ -0,0 +1,80 @@ +{ + "name": "str-repeat", + "steps": [ + { + "step": "setState", + "accounts": { + "address:owner": { + "nonce": "0", + "balance": "0" + }, + "sc:contract": { + "code": "mxsc:../output/str-repeat-mb-builder-cached.mxsc.json" + } + } + }, + { + "step": "scCall", + "id": "benchmark-mb-builder-cached-10", + "comment": "code is smaller, so basic wins here", + "tx": { + "from": "address:owner", + "to": "sc:contract", + "function": "mb_builder_benchmark", + "arguments": [ + "0x01020304", + "10" + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": "*", + "status": "", + "gas": "8834532" + } + }, + { + "step": "scCall", + "id": "benchmark-mb-builder-cached-tipping-point", + "comment": "the caching optimization starts to compensate the larger code size", + "tx": { + "from": "address:owner", + "to": "sc:contract", + "function": "mb_builder_benchmark", + "arguments": [ + "0x01020304", + "22" + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": "*", + "status": "", + "gas": "8779332" + } + }, + { + "step": "scCall", + "id": "benchmark-mb-builder-cached", + "comment": "for many repeats, the cached version wins", + "tx": { + "from": "address:owner", + "to": "sc:contract", + "function": "mb_builder_benchmark", + "arguments": [ + "0x01020304", + "10000" + ], + "gasLimit": "10,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": "*", + "status": "", + "gas": "9938367902" + } + } + ] +} diff --git a/contracts/benchmarks/str-repeat/src/str_repeat.rs b/contracts/benchmarks/str-repeat/src/str_repeat.rs index 0cd6fb0325..81ad7fa874 100644 --- a/contracts/benchmarks/str-repeat/src/str_repeat.rs +++ b/contracts/benchmarks/str-repeat/src/str_repeat.rs @@ -25,4 +25,15 @@ pub trait StrRepeat { #[view(getByteArray)] #[storage_mapper("byteArray")] fn byte_array(&self) -> SingleValueMapper>; + + #[view] + #[label("mb-builder")] + fn mb_builder_benchmark(&self, payload: u32, num_repeats: usize) -> ManagedBuffer { + let mut builder = ManagedBufferBuilder::default(); + let payload_bytes = payload.to_be_bytes(); + for _ in 0..num_repeats { + builder.append_bytes(&payload_bytes); + } + builder.into_managed_buffer() + } } diff --git a/contracts/benchmarks/str-repeat/tests/scenario_go_test.rs b/contracts/benchmarks/str-repeat/tests/scenario_go_test.rs index e1be038d02..325d9ac866 100644 --- a/contracts/benchmarks/str-repeat/tests/scenario_go_test.rs +++ b/contracts/benchmarks/str-repeat/tests/scenario_go_test.rs @@ -4,6 +4,18 @@ fn world() -> ScenarioWorld { ScenarioWorld::vm_go() } +#[test] +#[ignore = "gas benchmark, too brittle to include permanently"] +fn mb_builder_basic_go() { + world().run("scenarios/mb_builder_basic.scen.json"); +} + +#[test] +#[ignore = "gas benchmark, too brittle to include permanently"] +fn mb_builder_cached_go() { + world().run("scenarios/mb_builder_cached.scen.json"); +} + #[test] fn str_repeat_go() { world().run("scenarios/str_repeat.scen.json"); diff --git a/contracts/benchmarks/str-repeat/tests/scenario_rs_test.rs b/contracts/benchmarks/str-repeat/tests/scenario_rs_test.rs index 42f585f314..4fcef41480 100644 --- a/contracts/benchmarks/str-repeat/tests/scenario_rs_test.rs +++ b/contracts/benchmarks/str-repeat/tests/scenario_rs_test.rs @@ -6,9 +6,27 @@ fn world() -> ScenarioWorld { "mxsc:output/str-repeat.mxsc.json", str_repeat::ContractBuilder, ); + blockchain.register_contract( + "mxsc:output/str-repeat-mb-builder-basic.mxsc.json", + str_repeat::ContractBuilder, + ); + blockchain.register_contract( + "mxsc:output/str-repeat-mb-builder-cached.mxsc.json", + str_repeat::ContractBuilder, + ); blockchain } +#[test] +fn mb_builder_basic_rs() { + world().run("scenarios/mb_builder_basic.scen.json"); +} + +#[test] +fn mb_builder_cached_rs() { + world().run("scenarios/mb_builder_cached.scen.json"); +} + #[test] fn str_repeat_rs() { world().run("scenarios/str_repeat.scen.json"); diff --git a/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-basic/Cargo.lock b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-basic/Cargo.lock new file mode 100644 index 0000000000..98f71f267e --- /dev/null +++ b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-basic/Cargo.lock @@ -0,0 +1,178 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "multiversx-sc" +version = "0.50.3" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.19.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.19.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.50.3" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.50.3" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "str-repeat" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "str-repeat-mb-builder-basic-wasm" +version = "0.0.0" +dependencies = [ + "multiversx-sc-wasm-adapter", + "str-repeat", +] + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-basic/Cargo.toml b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-basic/Cargo.toml new file mode 100644 index 0000000000..042b268ad4 --- /dev/null +++ b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-basic/Cargo.toml @@ -0,0 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "str-repeat-mb-builder-basic-wasm" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" + +[dependencies.str-repeat] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.50.3" +path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-basic/src/lib.rs b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-basic/src/lib.rs new file mode 100644 index 0000000000..68be3133c5 --- /dev/null +++ b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-basic/src/lib.rs @@ -0,0 +1,25 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 1 +// Async Callback (empty): 1 +// Total number of exported functions: 3 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + str_repeat + ( + init => init + mb_builder_benchmark => mb_builder_benchmark + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-cached/Cargo.lock b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-cached/Cargo.lock new file mode 100644 index 0000000000..37dd369183 --- /dev/null +++ b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-cached/Cargo.lock @@ -0,0 +1,178 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "multiversx-sc" +version = "0.50.3" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.19.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.19.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.50.3" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.50.3" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "str-repeat" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "str-repeat-mb-builder-cached-wasm" +version = "0.0.0" +dependencies = [ + "multiversx-sc-wasm-adapter", + "str-repeat", +] + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-cached/Cargo.toml b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-cached/Cargo.toml new file mode 100644 index 0000000000..9fdf4a5630 --- /dev/null +++ b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-cached/Cargo.toml @@ -0,0 +1,36 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "str-repeat-mb-builder-cached-wasm" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" + +[dependencies.str-repeat] +path = ".." +features = ["managed-buffer-builder-cached"] + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.50.3" +path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-cached/src/lib.rs b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-cached/src/lib.rs new file mode 100644 index 0000000000..68be3133c5 --- /dev/null +++ b/contracts/benchmarks/str-repeat/wasm-str-repeat-mb-builder-cached/src/lib.rs @@ -0,0 +1,25 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 1 +// Async Callback (empty): 1 +// Total number of exported functions: 3 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + str_repeat + ( + init => init + mb_builder_benchmark => mb_builder_benchmark + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/contracts/benchmarks/str-repeat/wasm/Cargo.lock b/contracts/benchmarks/str-repeat/wasm/Cargo.lock index 1486892d5c..5825dd6f10 100755 --- a/contracts/benchmarks/str-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/str-repeat/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -133,9 +135,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "str-repeat" @@ -154,9 +156,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/str-repeat/wasm/Cargo.toml b/contracts/benchmarks/str-repeat/wasm/Cargo.toml index 64354ce36c..892c42065e 100644 --- a/contracts/benchmarks/str-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/str-repeat/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.str-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/benchmarks/str-repeat/wasm/src/lib.rs b/contracts/benchmarks/str-repeat/wasm/src/lib.rs index 45af6112da..1d059d343c 100644 --- a/contracts/benchmarks/str-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/str-repeat/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 5 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(leaking); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/core/price-aggregator/Cargo.toml b/contracts/core/price-aggregator/Cargo.toml index 1dd51d5792..e90571b170 100644 --- a/contracts/core/price-aggregator/Cargo.toml +++ b/contracts/core/price-aggregator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-price-aggregator-sc" -version = "0.47.5" +version = "0.50.3" authors = [ "Claudiu-Marcel Bruda ", "MultiversX ", @@ -19,15 +19,15 @@ edition = "2021" path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dependencies] diff --git a/contracts/core/price-aggregator/meta/Cargo.toml b/contracts/core/price-aggregator/meta/Cargo.toml index 07bc777dc8..b2dcd6beaa 100644 --- a/contracts/core/price-aggregator/meta/Cargo.toml +++ b/contracts/core/price-aggregator/meta/Cargo.toml @@ -8,10 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/core/price-aggregator/meta/src/main.rs b/contracts/core/price-aggregator/meta/src/main.rs index 85ac9819bf..9601681127 100644 --- a/contracts/core/price-aggregator/meta/src/main.rs +++ b/contracts/core/price-aggregator/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/core/price-aggregator/sc-config.toml b/contracts/core/price-aggregator/sc-config.toml new file mode 100644 index 0000000000..56b3e816a6 --- /dev/null +++ b/contracts/core/price-aggregator/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "tests/price_aggregator_proxy.rs" \ No newline at end of file diff --git a/contracts/core/price-aggregator/scenarios/stress_submit_test.scen.json b/contracts/core/price-aggregator/scenarios/stress_submit_test.scen.json index 6542b59c39..e2b19c9966 100644 --- a/contracts/core/price-aggregator/scenarios/stress_submit_test.scen.json +++ b/contracts/core/price-aggregator/scenarios/stress_submit_test.scen.json @@ -1133,7 +1133,7 @@ "0x45474c44", "0x55534443", "0x5f", - "0x3beec6f9cf5130ed", + "0xd7fd71920be3e621", "0x" ], "gasLimit": "7,000,000" @@ -1154,7 +1154,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x50d924566a98aec8", + "0x5a032236cff2ff06", "0x" ], "gasLimit": "7,000,000" @@ -1175,7 +1175,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x097b928bb2d85516", + "0x2e874347688dffa1", "0x" ], "gasLimit": "7,000,000" @@ -1196,7 +1196,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x765c960a5c3c6b95", + "0x4c94033d5e15a73a", "0x" ], "gasLimit": "7,000,000" @@ -1217,7 +1217,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xf7426f44c20f404c", + "0x2bd5b88173750be6", "0x" ], "gasLimit": "7,000,000" @@ -1238,7 +1238,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xa5c69769ba606c2b", + "0xe4cb406e5f95d9d7", "0x" ], "gasLimit": "7,000,000" @@ -1259,7 +1259,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xe8f77e933d1f2517", + "0xfd4dd723ed0b256e", "0x" ], "gasLimit": "7,000,000" @@ -1280,7 +1280,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x94fba404681c1183", + "0x66b6bfe973064cfd", "0x" ], "gasLimit": "7,000,000" @@ -1301,7 +1301,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xdc506f08b25d3b71", + "0xbc6a51b940c5c479", "0x" ], "gasLimit": "7,000,000" @@ -1322,7 +1322,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xf5b0acb8ddff3752", + "0x47ca1962093887df", "0x" ], "gasLimit": "7,000,000" @@ -1343,7 +1343,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x39a7d356f768ea5e", + "0xa9657f2b7c255e3c", "0x" ], "gasLimit": "7,000,000" @@ -1364,7 +1364,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xaf145a7f797a48a1", + "0xadaf4aaa5e63f2e5", "0x" ], "gasLimit": "7,000,000" @@ -1385,7 +1385,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xb18143fe76eef718", + "0x153a1384b3d68656", "0x" ], "gasLimit": "7,000,000" @@ -1406,7 +1406,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x6f64a1ddec18e577", + "0x4ba5dda59b2ba4e9", "0x" ], "gasLimit": "7,000,000" @@ -1427,7 +1427,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x87ffce2a932db3d4", + "0x973e0d62157afb51", "0x" ], "gasLimit": "7,000,000" @@ -1448,7 +1448,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xe6642c7265c738c1", + "0xe18cb77b44399b45", "0x" ], "gasLimit": "7,000,000" @@ -1469,7 +1469,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xd6079c55087a67d5", + "0x30a1ed7ed6069074", "0x" ], "gasLimit": "7,000,000" @@ -1490,7 +1490,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x90f7bb0d816fb87d", + "0xfbd288d325739548", "0x" ], "gasLimit": "7,000,000" @@ -1511,7 +1511,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xa0ccc6f5f8c73ff2", + "0x83ad3ad74745e6f5", "0x" ], "gasLimit": "7,000,000" @@ -1532,7 +1532,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x258d38a35ccfd93d", + "0x0cc85234d5ea00b2", "0x" ], "gasLimit": "7,000,000" @@ -1553,7 +1553,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x903f62b19408019d", + "0x8dae036c75e9a62c", "0x" ], "gasLimit": "7,000,000" @@ -1574,7 +1574,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xc319aab79b2f512e", + "0x31549118c983eaa0", "0x" ], "gasLimit": "7,000,000" @@ -1595,7 +1595,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x4b41176cd679e194", + "0x8228096b6388b4bd", "0x" ], "gasLimit": "7,000,000" @@ -1616,7 +1616,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xaf3c4ad7cdcac230", + "0x2dc8b16251c44710", "0x" ], "gasLimit": "7,000,000" @@ -1637,7 +1637,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x2a8c4a82dfb68f13", + "0xbc66b6f85858d98c", "0x" ], "gasLimit": "7,000,000" @@ -1658,7 +1658,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x358e92c93a69a2f9", + "0x2937c9b0c1073c0b", "0x" ], "gasLimit": "7,000,000" @@ -1679,7 +1679,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xb4bd55d9eebad664", + "0xa2b7bd06214aabc4", "0x" ], "gasLimit": "7,000,000" @@ -1700,7 +1700,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x9061fc2440f4db51", + "0x61ae8ac001144476", "0x" ], "gasLimit": "7,000,000" @@ -1721,7 +1721,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xc8fde2d627d1b95a", + "0x5f6de265c643495f", "0x" ], "gasLimit": "7,000,000" @@ -1742,7 +1742,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xacede2c42f9bc928", + "0x67430307e2f864f0", "0x" ], "gasLimit": "7,000,000" @@ -1763,7 +1763,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xb0a4ecb8d46cfe86", + "0x7de010a49d52cd3f", "0x" ], "gasLimit": "7,000,000" @@ -1784,7 +1784,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xa8d8ee43a5c4ade8", + "0xb27799264f3b84ec", "0x" ], "gasLimit": "7,000,000" @@ -1805,7 +1805,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xe20bb0819b83cbb6", + "0x53d7a1ade83e0f2e", "0x" ], "gasLimit": "7,000,000" @@ -1826,7 +1826,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xb5566ca4a8a6da5b", + "0x2ec40e01673b8ad7", "0x" ], "gasLimit": "7,000,000" @@ -1847,7 +1847,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x30b4e318dbf9c0a1", + "0xfb616537f76f8ffb", "0x" ], "gasLimit": "7,000,000" @@ -1868,7 +1868,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x34cd5592ee7ab5f0", + "0x387268d229f4ec9a", "0x" ], "gasLimit": "7,000,000" @@ -1889,7 +1889,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x4908da8f754f9e29", + "0xdea0f1c84325ea3a", "0x" ], "gasLimit": "7,000,000" @@ -1910,7 +1910,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x460da40079bef875", + "0x12eb7cb637de6e86", "0x" ], "gasLimit": "7,000,000" @@ -1931,7 +1931,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x6eb6dd52e24341b6", + "0x5f6b1784511d622d", "0x" ], "gasLimit": "7,000,000" @@ -1952,7 +1952,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xa06bb000b0901e98", + "0x1a41106366209d8d", "0x" ], "gasLimit": "7,000,000" @@ -1973,7 +1973,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x4f83b3dd7f1dd80e", + "0x2324bca02526fec9", "0x" ], "gasLimit": "7,000,000" @@ -1994,7 +1994,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x169e4556e8cd5271", + "0xccf33fc47ef34300", "0x" ], "gasLimit": "7,000,000" @@ -2015,7 +2015,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xa45b9cfe7527301b", + "0xebfab26bff9c74a3", "0x" ], "gasLimit": "7,000,000" @@ -2036,7 +2036,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xe3a28965ea6a3ae4", + "0x116a45e410db659b", "0x" ], "gasLimit": "7,000,000" @@ -2057,7 +2057,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x4efa7be66acf5ded", + "0xc9bddc2b06ba1f1e", "0x" ], "gasLimit": "7,000,000" @@ -2078,7 +2078,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x5f75311f8cd29ea9", + "0xde7473b9bfdfe96c", "0x" ], "gasLimit": "7,000,000" @@ -2099,7 +2099,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xfc7c1268abc1d8e3", + "0x91c2ff3a5c73267e", "0x" ], "gasLimit": "7,000,000" @@ -2120,7 +2120,7 @@ "0x45474c44", "0x55534443", "0x64", - "0xd24cc52d844c6a40", + "0x95bb44dffc62bb47", "0x" ], "gasLimit": "7,000,000" @@ -2141,7 +2141,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x804fc08cd1c73c42", + "0x2f28d194b7659f9f", "0x" ], "gasLimit": "7,000,000" @@ -2162,7 +2162,7 @@ "0x45474c44", "0x55534443", "0x64", - "0x093077783f01d496", + "0xc1bd397146f3353e", "0x" ], "gasLimit": "7,000,000" diff --git a/contracts/core/price-aggregator/src/events.rs b/contracts/core/price-aggregator/src/events.rs index f2212815c9..d485e622db 100644 --- a/contracts/core/price-aggregator/src/events.rs +++ b/contracts/core/price-aggregator/src/events.rs @@ -3,7 +3,8 @@ multiversx_sc::derive_imports!(); use crate::price_aggregator_data::{TimestampedPrice, TokenPair}; -#[derive(TypeAbi, TopEncode)] +#[type_abi] +#[derive(TopEncode)] pub struct NewRoundEvent { price: BigUint, timestamp: u64, diff --git a/contracts/core/price-aggregator/src/price_aggregator_data.rs b/contracts/core/price-aggregator/src/price_aggregator_data.rs index 13249216ba..c348b67d22 100644 --- a/contracts/core/price-aggregator/src/price_aggregator_data.rs +++ b/contracts/core/price-aggregator/src/price_aggregator_data.rs @@ -1,13 +1,15 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi, Clone)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, Clone)] pub struct TokenPair { pub from: ManagedBuffer, pub to: ManagedBuffer, } -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct PriceFeed { pub round_id: u32, pub from: ManagedBuffer, @@ -17,14 +19,16 @@ pub struct PriceFeed { pub decimals: u8, } -#[derive(TopEncode, TopDecode, TypeAbi, Debug, PartialEq, Eq)] +#[type_abi] +#[derive(TopEncode, TopDecode, Debug, PartialEq, Eq)] pub struct TimestampedPrice { pub price: BigUint, pub timestamp: u64, pub decimals: u8, } -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi, Debug, PartialEq, Eq)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, Debug, PartialEq, Eq)] pub struct OracleStatus { pub accepted_submissions: u64, pub total_submissions: u64, diff --git a/contracts/core/price-aggregator/tests/price_aggregator_blackbox_test.rs b/contracts/core/price-aggregator/tests/price_aggregator_blackbox_test.rs index b1b28e4fcf..b0e1f54455 100644 --- a/contracts/core/price-aggregator/tests/price_aggregator_blackbox_test.rs +++ b/contracts/core/price-aggregator/tests/price_aggregator_blackbox_test.rs @@ -1,39 +1,31 @@ use multiversx_price_aggregator_sc::{ price_aggregator_data::{OracleStatus, TimestampedPrice, TokenPair}, - ContractObj, PriceAggregator, ProxyTrait as _, MAX_ROUND_DURATION_SECONDS, -}; -use multiversx_sc::{ - codec::multi_types::MultiValueVec, - types::{Address, EgldOrEsdtTokenIdentifier}, -}; -use multiversx_sc_modules::{pause::ProxyTrait, staking::ProxyTrait as _}; -use multiversx_sc_scenario::{ - api::StaticApi, - managed_address, managed_biguint, managed_buffer, - scenario_model::{Account, AddressValue, ScCallStep, ScDeployStep, SetStateStep, TxExpect}, - ContractInfo, DebugApi, ScenarioWorld, WhiteboxContract, + ContractObj, PriceAggregator, MAX_ROUND_DURATION_SECONDS, }; +use multiversx_sc_scenario::imports::*; + +mod price_aggregator_proxy; + const DECIMALS: u8 = 0; const EGLD_TICKER: &[u8] = b"EGLD"; const NR_ORACLES: usize = 4; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const PRICE_AGGREGATOR_ADDRESS_EXPR: &str = "sc:price-aggregator"; -const PRICE_AGGREGATOR_PATH_EXPR: &str = "mxsc:output/multiversx-price-aggregator-sc.mxsc.json"; const SLASH_AMOUNT: u64 = 10; const SLASH_QUORUM: usize = 3; const STAKE_AMOUNT: u64 = 20; const SUBMISSION_COUNT: usize = 3; const USD_TICKER: &[u8] = b"USDC"; -type PriceAggregatorContract = ContractInfo>; +const PRICE_AGGREGATOR_ADDRESS: TestSCAddress = TestSCAddress::new("price-aggregator"); +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const PRICE_AGGREGATOR_PATH: MxscPath = + MxscPath::new("output/multiversx-price-aggregator-sc.mxsc.json"); fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/core/price-aggregator"); blockchain.register_contract( - PRICE_AGGREGATOR_PATH_EXPR, + PRICE_AGGREGATOR_PATH, multiversx_price_aggregator_sc::ContractBuilder, ); @@ -43,7 +35,6 @@ fn world() -> ScenarioWorld { struct PriceAggregatorTestState { world: ScenarioWorld, oracles: Vec, - price_aggregator_contract: PriceAggregatorContract, price_aggregator_whitebox: WhiteboxContract>, } @@ -51,42 +42,34 @@ impl PriceAggregatorTestState { fn new() -> Self { let mut world = world(); - let mut set_state_step = SetStateStep::new() - .put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .new_address(OWNER_ADDRESS_EXPR, 1, PRICE_AGGREGATOR_ADDRESS_EXPR) - .block_timestamp(100); + world.account(OWNER_ADDRESS).nonce(1); + world.current_block().block_timestamp(100); + + world.new_address(OWNER_ADDRESS, 1, PRICE_AGGREGATOR_ADDRESS); let mut oracles = Vec::new(); for i in 1..=NR_ORACLES { - let address_expr = format!("address:oracle{}", i); - let address_value = AddressValue::from(address_expr.as_str()); - - set_state_step = set_state_step.put_account( - address_expr.as_str(), - Account::new().nonce(1).balance(STAKE_AMOUNT), - ); + let address_name = format!("oracle{i}"); + let address = TestAddress::new(&address_name); + let address_value = AddressValue::from(address); + world.account(address).nonce(1).balance(STAKE_AMOUNT); oracles.push(address_value); } - world.set_state_step(set_state_step); - let price_aggregator_contract = PriceAggregatorContract::new(PRICE_AGGREGATOR_ADDRESS_EXPR); let price_aggregator_whitebox = WhiteboxContract::new( - PRICE_AGGREGATOR_ADDRESS_EXPR, + PRICE_AGGREGATOR_ADDRESS, multiversx_price_aggregator_sc::contract_obj, ); Self { world, oracles, - price_aggregator_contract, price_aggregator_whitebox, } } fn deploy(&mut self) -> &mut Self { - let price_aggregator_code = self.world.code_expression(PRICE_AGGREGATOR_PATH_EXPR); - let oracles = MultiValueVec::from( self.oracles .iter() @@ -94,59 +77,69 @@ impl PriceAggregatorTestState { .collect::>(), ); - self.world.sc_deploy( - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(price_aggregator_code) - .call(self.price_aggregator_contract.init( - EgldOrEsdtTokenIdentifier::egld(), - STAKE_AMOUNT, - SLASH_AMOUNT, - SLASH_QUORUM, - SUBMISSION_COUNT, - oracles, - )), - ); + self.world + .tx() + .from(OWNER_ADDRESS) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .init( + EgldOrEsdtTokenIdentifier::egld(), + STAKE_AMOUNT, + SLASH_AMOUNT, + SLASH_QUORUM, + SUBMISSION_COUNT, + oracles, + ) + .code(PRICE_AGGREGATOR_PATH) + .run(); for address in self.oracles.iter() { - self.world.sc_call( - ScCallStep::new() - .from(address) - .egld_value(STAKE_AMOUNT) - .call(self.price_aggregator_contract.stake()), - ); + self.world + .tx() + .from(address) + .to(PRICE_AGGREGATOR_ADDRESS) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .stake() + .egld(STAKE_AMOUNT) + .run(); } self } fn set_pair_decimals(&mut self) { - self.world.sc_call( - ScCallStep::new().from(OWNER_ADDRESS_EXPR).call( - self.price_aggregator_contract - .set_pair_decimals(EGLD_TICKER, USD_TICKER, DECIMALS), - ), - ); + self.world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .set_pair_decimals(EGLD_TICKER, USD_TICKER, DECIMALS) + .run(); } fn unpause_endpoint(&mut self) { - self.world.sc_call( - ScCallStep::new() - .from(OWNER_ADDRESS_EXPR) - .call(self.price_aggregator_contract.unpause_endpoint()), - ); + self.world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .unpause_endpoint() + .run(); } fn submit(&mut self, from: &AddressValue, submission_timestamp: u64, price: u64) { - self.world.sc_call(ScCallStep::new().from(from).call( - self.price_aggregator_contract.submit( + self.world + .tx() + .from(from) + .to(PRICE_AGGREGATOR_ADDRESS) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .submit( EGLD_TICKER, USD_TICKER, submission_timestamp, price, DECIMALS, - ), - )); + ) + .run(); } fn submit_and_expect_err( @@ -156,27 +149,31 @@ impl PriceAggregatorTestState { price: u64, err_message: &str, ) { - self.world.sc_call( - ScCallStep::new() - .from(from) - .call(self.price_aggregator_contract.submit( - EGLD_TICKER, - USD_TICKER, - submission_timestamp, - price, - DECIMALS, - )) - .expect(TxExpect::user_error("str:".to_string() + err_message)), - ); + self.world + .tx() + .from(from) + .to(PRICE_AGGREGATOR_ADDRESS) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .submit( + EGLD_TICKER, + USD_TICKER, + submission_timestamp, + price, + DECIMALS, + ) + .with_result(ExpectStatus(4)) + .with_result(ExpectMessage(err_message)) + .run(); } fn vote_slash_member(&mut self, from: &AddressValue, member_to_slash: Address) { - self.world.sc_call( - ScCallStep::new().from(from).call( - self.price_aggregator_contract - .vote_slash_member(member_to_slash), - ), - ); + self.world + .tx() + .from(from) + .to(PRICE_AGGREGATOR_ADDRESS) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .vote_slash_member(member_to_slash) + .run(); } } @@ -277,7 +274,8 @@ fn test_price_aggregator_submit_round_ok() { let current_timestamp = 110; state .world - .set_state_step(SetStateStep::new().block_timestamp(current_timestamp)); + .current_block() + .block_timestamp(current_timestamp); // submit second state.submit(&state.oracles[1].clone(), 101, 11_000); @@ -334,7 +332,8 @@ fn test_price_aggregator_discarded_round() { let current_timestamp = 100 + MAX_ROUND_DURATION_SECONDS + 1; state .world - .set_state_step(SetStateStep::new().block_timestamp(current_timestamp)); + .current_block() + .block_timestamp(current_timestamp); // submit second - this will discard the previous submission state.submit(&state.oracles[1].clone(), current_timestamp - 1, 11_000); @@ -369,13 +368,14 @@ fn test_price_aggregator_slashing() { state.vote_slash_member(&state.oracles[2].clone(), state.oracles[1].to_address()); state.vote_slash_member(&state.oracles[3].clone(), state.oracles[1].to_address()); - state.world.sc_call( - ScCallStep::new().from(&state.oracles[0]).call( - state - .price_aggregator_contract - .slash_member(state.oracles[1].to_address()), - ), - ); + state + .world + .tx() + .from(&state.oracles[0]) + .to(PRICE_AGGREGATOR_ADDRESS) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .slash_member(state.oracles[1].to_address()) + .run(); // oracle 1 try submit after slashing state.submit_and_expect_err( diff --git a/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs b/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs new file mode 100644 index 0000000000..e96244d668 --- /dev/null +++ b/contracts/core/price-aggregator/tests/price_aggregator_proxy.rs @@ -0,0 +1,389 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct PriceAggregatorProxy; + +impl TxProxyTrait for PriceAggregatorProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = PriceAggregatorProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + PriceAggregatorProxyMethods { wrapped_tx: tx } + } +} + +pub struct PriceAggregatorProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl PriceAggregatorProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg, + Arg4: ProxyArg, + Arg5: ProxyArg>>, + >( + self, + staking_token: Arg0, + staking_amount: Arg1, + slash_amount: Arg2, + slash_quorum: Arg3, + submission_count: Arg4, + oracles: Arg5, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&staking_token) + .argument(&staking_amount) + .argument(&slash_amount) + .argument(&slash_quorum) + .argument(&submission_count) + .argument(&oracles) + .original_result() + } +} + +#[rustfmt::skip] +impl PriceAggregatorProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn change_amounts< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + staking_amount: Arg0, + slash_amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("changeAmounts") + .argument(&staking_amount) + .argument(&slash_amount) + .original_result() + } + + pub fn add_oracles< + Arg0: ProxyArg>>, + >( + self, + oracles: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("addOracles") + .argument(&oracles) + .original_result() + } + + /// Also receives submission count, + /// so the owner does not have to update it manually with setSubmissionCount before this call + pub fn remove_oracles< + Arg0: ProxyArg, + Arg1: ProxyArg>>, + >( + self, + submission_count: Arg0, + oracles: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("removeOracles") + .argument(&submission_count) + .argument(&oracles) + .original_result() + } + + pub fn submit< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + Arg4: ProxyArg, + >( + self, + from: Arg0, + to: Arg1, + submission_timestamp: Arg2, + price: Arg3, + decimals: Arg4, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("submit") + .argument(&from) + .argument(&to) + .argument(&submission_timestamp) + .argument(&price) + .argument(&decimals) + .original_result() + } + + pub fn submit_batch< + Arg0: ProxyArg, ManagedBuffer, u64, BigUint, u8>>>, + >( + self, + submissions: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("submitBatch") + .argument(&submissions) + .original_result() + } + + pub fn latest_round_data( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("latestRoundData") + .original_result() + } + + pub fn latest_price_feed< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + from: Arg0, + to: Arg1, + ) -> TxTypedCall, ManagedBuffer, u64, BigUint, u8>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("latestPriceFeed") + .argument(&from) + .argument(&to) + .original_result() + } + + pub fn latest_price_feed_optional< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + from: Arg0, + to: Arg1, + ) -> TxTypedCall, ManagedBuffer, u64, BigUint, u8>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("latestPriceFeedOptional") + .argument(&from) + .argument(&to) + .original_result() + } + + pub fn set_submission_count< + Arg0: ProxyArg, + >( + self, + submission_count: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("setSubmissionCount") + .argument(&submission_count) + .original_result() + } + + pub fn get_oracles( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getOracles") + .original_result() + } + + pub fn set_pair_decimals< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + from: Arg0, + to: Arg1, + decimals: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("setPairDecimals") + .argument(&from) + .argument(&to) + .argument(&decimals) + .original_result() + } + + pub fn get_pair_decimals< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + from: Arg0, + to: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getPairDecimals") + .argument(&from) + .argument(&to) + .original_result() + } + + pub fn submission_count( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("submission_count") + .original_result() + } + + pub fn pause_endpoint( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("pause") + .original_result() + } + + pub fn unpause_endpoint( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unpause") + .original_result() + } + + pub fn paused_status( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isPaused") + .original_result() + } + + pub fn stake( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("stake") + .original_result() + } + + pub fn unstake< + Arg0: ProxyArg>, + >( + self, + unstake_amount: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unstake") + .argument(&unstake_amount) + .original_result() + } + + pub fn vote_slash_member< + Arg0: ProxyArg>, + >( + self, + member_to_slash: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("voteSlashMember") + .argument(&member_to_slash) + .original_result() + } + + pub fn cancel_vote_slash_member< + Arg0: ProxyArg>, + >( + self, + member_to_slash: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("cancelVoteSlashMember") + .argument(&member_to_slash) + .original_result() + } + + pub fn slash_member< + Arg0: ProxyArg>, + >( + self, + member_to_slash: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("slashMember") + .argument(&member_to_slash) + .original_result() + } +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct PriceFeed +where + Api: ManagedTypeApi, +{ + pub round_id: u32, + pub from: ManagedBuffer, + pub to: ManagedBuffer, + pub timestamp: u64, + pub price: BigUint, + pub decimals: u8, +} + +#[type_abi] +#[derive(TopEncode)] +pub struct NewRoundEvent +where + Api: ManagedTypeApi, +{ + pub price: BigUint, + pub timestamp: u64, + pub decimals: u8, + pub block: u64, + pub epoch: u64, +} diff --git a/contracts/core/price-aggregator/tests/price_aggregator_stress_blackbox.rs b/contracts/core/price-aggregator/tests/price_aggregator_stress_blackbox.rs index 1170a4d964..660bbf1dda 100644 --- a/contracts/core/price-aggregator/tests/price_aggregator_stress_blackbox.rs +++ b/contracts/core/price-aggregator/tests/price_aggregator_stress_blackbox.rs @@ -1,39 +1,30 @@ use multiversx_price_aggregator_sc::{ price_aggregator_data::{OracleStatus, TokenPair}, - ContractObj, PriceAggregator, ProxyTrait as _, -}; -use multiversx_sc::{ - codec::multi_types::MultiValueVec, contract_base::ContractBase, - types::EgldOrEsdtTokenIdentifier, -}; -use multiversx_sc_modules::{pause::ProxyTrait, staking::ProxyTrait as _}; -use multiversx_sc_scenario::{ - api::StaticApi, - managed_address, managed_buffer, - scenario_model::{Account, AddressValue, ScCallStep, ScDeployStep, SetStateStep}, - ContractInfo, DebugApi, ScenarioWorld, WhiteboxContract, + ContractObj, PriceAggregator, }; +use multiversx_sc_scenario::imports::*; + const DECIMALS: u8 = 0; const EGLD_TICKER: &[u8] = b"EGLD"; const NR_ORACLES: usize = 50; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const PRICE_AGGREGATOR_ADDRESS_EXPR: &str = "sc:price-aggregator"; -const PRICE_AGGREGATOR_PATH_EXPR: &str = "mxsc:../output/multiversx-price-aggregator-sc.mxsc.json"; +const OWNER: TestAddress = TestAddress::new("owner"); +const PRICE_AGGREGATOR_ADDRESS: TestSCAddress = TestSCAddress::new("price-aggregator"); +const PRICE_AGGREGATOR_PATH: MxscPath = + MxscPath::new("../output/multiversx-price-aggregator-sc.mxsc.json"); const SLASH_AMOUNT: u64 = 10; const SLASH_QUORUM: usize = 3; const STAKE_AMOUNT: u64 = 20; const SUBMISSION_COUNT: usize = 50; const USD_TICKER: &[u8] = b"USDC"; -type PriceAggregatorContract = ContractInfo>; +mod price_aggregator_proxy; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/core/price-aggregator"); blockchain.register_contract( - PRICE_AGGREGATOR_PATH_EXPR, + PRICE_AGGREGATOR_PATH, multiversx_price_aggregator_sc::ContractBuilder, ); @@ -43,50 +34,45 @@ fn world() -> ScenarioWorld { struct PriceAggregatorTestState { world: ScenarioWorld, oracles: Vec, - price_aggregator_contract: PriceAggregatorContract, price_aggregator_whitebox: WhiteboxContract>, } impl PriceAggregatorTestState { fn new() -> Self { let mut world = world(); + world.start_trace(); - let mut set_state_step = SetStateStep::new() - .put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .new_address(OWNER_ADDRESS_EXPR, 1, PRICE_AGGREGATOR_ADDRESS_EXPR) + world + .account(OWNER) + .nonce(1) + .new_address(OWNER, 1, PRICE_AGGREGATOR_ADDRESS) + .current_block() .block_timestamp(100); let mut oracles = Vec::new(); for i in 1..=NR_ORACLES { - let address_expr = format!("address:oracle{}", i); - let address_value = AddressValue::from(address_expr.as_str()); + let address_expr = format!("oracle{}", i); + let address: TestAddress = TestAddress::new(address_expr.as_str()); + let address_value = AddressValue::from(address.eval_to_expr().as_str()); - set_state_step = set_state_step.put_account( - address_expr.as_str(), - Account::new().nonce(1).balance(STAKE_AMOUNT), - ); + world.account(address).nonce(1).balance(STAKE_AMOUNT); oracles.push(address_value); } - world.start_trace().set_state_step(set_state_step); - let price_aggregator_contract = PriceAggregatorContract::new(PRICE_AGGREGATOR_ADDRESS_EXPR); let price_aggregator_whitebox = WhiteboxContract::new( - PRICE_AGGREGATOR_ADDRESS_EXPR, + PRICE_AGGREGATOR_ADDRESS, multiversx_price_aggregator_sc::contract_obj, ); Self { world, oracles, - price_aggregator_contract, price_aggregator_whitebox, } } fn deploy(&mut self) -> &mut Self { - let price_aggregator_code = self.world.code_expression(PRICE_AGGREGATOR_PATH_EXPR); - let oracles = MultiValueVec::from( self.oracles .iter() @@ -94,65 +80,73 @@ impl PriceAggregatorTestState { .collect::>(), ); - self.world.sc_deploy( - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(price_aggregator_code) - .call(self.price_aggregator_contract.init( - EgldOrEsdtTokenIdentifier::egld(), - STAKE_AMOUNT, - SLASH_AMOUNT, - SLASH_QUORUM, - SUBMISSION_COUNT, - oracles, - )) - .gas_limit("120,000,000"), - ); + self.world + .tx() + .from(OWNER) + .gas(120_000_000u64) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .init( + EgldOrEsdtTokenIdentifier::egld(), + STAKE_AMOUNT, + SLASH_AMOUNT, + SLASH_QUORUM, + SUBMISSION_COUNT, + oracles, + ) + .code(PRICE_AGGREGATOR_PATH) + .run(); for address in self.oracles.iter() { - self.world.sc_call( - ScCallStep::new() - .from(address) - .egld_value(STAKE_AMOUNT) - .call(self.price_aggregator_contract.stake()) - .gas_limit("5,000,000"), - ); + self.world + .tx() + .from(&address.to_address()) + .to(PRICE_AGGREGATOR_ADDRESS) + .gas(5_000_000u64) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .stake() + .egld(STAKE_AMOUNT) + .run(); } self } fn set_pair_decimals(&mut self) { - self.world.sc_call( - ScCallStep::new().from(OWNER_ADDRESS_EXPR).call( - self.price_aggregator_contract - .set_pair_decimals(EGLD_TICKER, USD_TICKER, DECIMALS), - ), - ); + self.world + .tx() + .from(OWNER) + .to(PRICE_AGGREGATOR_ADDRESS) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .set_pair_decimals(EGLD_TICKER, USD_TICKER, DECIMALS) + .run(); } fn unpause_endpoint(&mut self) { - self.world.sc_call( - ScCallStep::new() - .from(OWNER_ADDRESS_EXPR) - .call(self.price_aggregator_contract.unpause_endpoint()) - .gas_limit("5,000,000"), - ); + self.world + .tx() + .from(OWNER) + .to(PRICE_AGGREGATOR_ADDRESS) + .gas(5_000_000u64) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .unpause_endpoint() + .run(); } fn submit(&mut self, from: &AddressValue, submission_timestamp: u64, price: u64) { - self.world.sc_call( - ScCallStep::new() - .from(from) - .call(self.price_aggregator_contract.submit( - EGLD_TICKER, - USD_TICKER, - submission_timestamp, - price, - DECIMALS, - )) - .gas_limit("7,000,000"), - ); + self.world + .tx() + .from(&from.to_address()) + .to(PRICE_AGGREGATOR_ADDRESS) + .gas(7_000_000u64) + .typed(price_aggregator_proxy::PriceAggregatorProxy) + .submit( + EGLD_TICKER, + USD_TICKER, + submission_timestamp, + price, + DECIMALS, + ) + .run(); } } diff --git a/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs b/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs index a2a432127e..180301b610 100644 --- a/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs +++ b/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs @@ -2,14 +2,11 @@ use multiversx_price_aggregator_sc::{ price_aggregator_data::{OracleStatus, TimestampedPrice, TokenPair}, PriceAggregator, MAX_ROUND_DURATION_SECONDS, }; -use multiversx_sc::types::{EgldOrEsdtTokenIdentifier, MultiValueEncoded}; use multiversx_sc_modules::{ pause::EndpointWrappers as PauseEndpointWrappers, staking::EndpointWrappers as StakingEndpointWrappers, }; -use multiversx_sc_scenario::{ - managed_address, managed_biguint, managed_buffer, scenario_model::*, WhiteboxContract, *, -}; +use multiversx_sc_scenario::imports::*; pub const DECIMALS: u8 = 0; pub const EGLD_TICKER: &[u8] = b"EGLD"; @@ -27,7 +24,6 @@ const PRICE_AGGREGATOR_PATH_EXPR: &str = "mxsc:output/multiversx-price-aggregato fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/core/price-aggregator"); blockchain.register_contract( PRICE_AGGREGATOR_PATH_EXPR, multiversx_price_aggregator_sc::ContractBuilder, diff --git a/contracts/core/price-aggregator/wasm/Cargo.lock b/contracts/core/price-aggregator/wasm/Cargo.lock index 3c49a61d3a..f05dbe8ca8 100644 --- a/contracts/core/price-aggregator/wasm/Cargo.lock +++ b/contracts/core/price-aggregator/wasm/Cargo.lock @@ -10,21 +10,21 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "cfg-if" @@ -40,9 +40,9 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -65,28 +65,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "multiversx-price-aggregator-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "arrayvec", "getrandom", @@ -105,26 +105,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -134,7 +136,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -145,14 +147,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -168,9 +170,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -189,18 +191,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -247,15 +249,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -268,6 +270,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -276,9 +284,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -286,9 +294,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -301,9 +309,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -311,9 +319,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -324,6 +332,6 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" diff --git a/contracts/core/price-aggregator/wasm/Cargo.toml b/contracts/core/price-aggregator/wasm/Cargo.toml index c39965acb9..115fc66661 100644 --- a/contracts/core/price-aggregator/wasm/Cargo.toml +++ b/contracts/core/price-aggregator/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.multiversx-price-aggregator-sc] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/core/price-aggregator/wasm/src/lib.rs b/contracts/core/price-aggregator/wasm/src/lib.rs index 54fe29d855..667c425afd 100644 --- a/contracts/core/price-aggregator/wasm/src/lib.rs +++ b/contracts/core/price-aggregator/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 23 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/core/wegld-swap/Cargo.toml b/contracts/core/wegld-swap/Cargo.toml index 5cce44f08e..458f7b19e2 100644 --- a/contracts/core/wegld-swap/Cargo.toml +++ b/contracts/core/wegld-swap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-wegld-swap-sc" -version = "0.47.5" +version = "0.50.3" authors = [ "Dorin Iancu ", @@ -20,13 +20,13 @@ edition = "2021" path = "src/wegld.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/core/wegld-swap/meta/Cargo.toml b/contracts/core/wegld-swap/meta/Cargo.toml index 222f0692d6..35cce5da6e 100644 --- a/contracts/core/wegld-swap/meta/Cargo.toml +++ b/contracts/core/wegld-swap/meta/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "multiversx-wegld-swap-sc-meta" version = "0.0.0" -authors = [ "Dorin Iancu ",] +authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -11,10 +11,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/core/wegld-swap/meta/src/main.rs b/contracts/core/wegld-swap/meta/src/main.rs index c3eb0f142e..9f4ea3ba2a 100644 --- a/contracts/core/wegld-swap/meta/src/main.rs +++ b/contracts/core/wegld-swap/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/core/wegld-swap/sc-config.toml b/contracts/core/wegld-swap/sc-config.toml new file mode 100644 index 0000000000..27465ed64a --- /dev/null +++ b/contracts/core/wegld-swap/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "../../examples/multisig/interact/src/wegld_proxy.rs" diff --git a/contracts/core/wegld-swap/src/wegld.rs b/contracts/core/wegld-swap/src/wegld.rs index 4b12bbc80a..4a38cab09e 100644 --- a/contracts/core/wegld-swap/src/wegld.rs +++ b/contracts/core/wegld-swap/src/wegld.rs @@ -23,9 +23,10 @@ pub trait EgldEsdtSwap: multiversx_sc_modules::pause::PauseModule { self.send() .esdt_local_mint(&wrapped_egld_token_id, 0, &payment_amount); - let caller = self.blockchain().get_caller(); - self.send() - .direct_esdt(&caller, &wrapped_egld_token_id, 0, &payment_amount); + self.tx() + .to(ToCaller) + .single_esdt(&wrapped_egld_token_id, 0, &payment_amount) + .transfer(); EsdtTokenPayment::new(wrapped_egld_token_id, 0, payment_amount.clone_value()) } @@ -50,7 +51,7 @@ pub trait EgldEsdtSwap: multiversx_sc_modules::pause::PauseModule { // 1 wrapped eGLD = 1 eGLD, so we pay back the same amount let caller = self.blockchain().get_caller(); - self.send().direct_egld(&caller, &payment_amount); + self.tx().to(&caller).egld(&payment_amount).transfer(); } #[view(getLockedEgldBalance)] diff --git a/contracts/core/wegld-swap/tests/wegld_swap_scenario_rs_test.rs b/contracts/core/wegld-swap/tests/wegld_swap_scenario_rs_test.rs index 01770e4b2e..a93bedb10f 100644 --- a/contracts/core/wegld-swap/tests/wegld_swap_scenario_rs_test.rs +++ b/contracts/core/wegld-swap/tests/wegld_swap_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/core/wegld-swap"); blockchain.register_contract( "mxsc:output/multiversx-wegld-swap-sc.mxsc.json", diff --git a/contracts/core/wegld-swap/wasm/Cargo.toml b/contracts/core/wegld-swap/wasm/Cargo.toml index f622d5d6b9..edc984e5ea 100644 --- a/contracts/core/wegld-swap/wasm/Cargo.toml +++ b/contracts/core/wegld-swap/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.multiversx-wegld-swap-sc] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/core/wegld-swap/wasm/src/lib.rs b/contracts/core/wegld-swap/wasm/src/lib.rs index 40848a69a7..efb2e9bd60 100644 --- a/contracts/core/wegld-swap/wasm/src/lib.rs +++ b/contracts/core/wegld-swap/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 9 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/adder/Cargo.toml b/contracts/examples/adder/Cargo.toml index 409f471ee5..f95bfef533 100644 --- a/contracts/examples/adder/Cargo.toml +++ b/contracts/examples/adder/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/adder.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/adder/interact/Cargo.toml b/contracts/examples/adder/interact/Cargo.toml index 5ff9488dbf..a8ba1a8577 100644 --- a/contracts/examples/adder/interact/Cargo.toml +++ b/contracts/examples/adder/interact/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "adder-interact" +name = "basic-interact" version = "0.0.0" authors = ["Ovidiu Stinga "] edition = "2021" publish = false [[bin]] -name = "adder-interact" -path = "src/adder_interact.rs" +name = "basic-interact" +path = "src/basic_interact.rs" [dependencies] clap = { version = "4.4.7", features = ["derive"] } @@ -18,5 +18,5 @@ toml = "0.8.6" path = ".." [dependencies.multiversx-sc-snippets] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/snippets" diff --git a/contracts/examples/adder/interact/config.toml b/contracts/examples/adder/interact/config.toml index b7fe10a560..61ac8dbf87 100644 --- a/contracts/examples/adder/interact/config.toml +++ b/contracts/examples/adder/interact/config.toml @@ -1 +1 @@ -gateway = 'https://testnet-gateway.multiversx.com' +gateway = 'https://devnet-gateway.multiversx.com' diff --git a/contracts/examples/adder/interact/src/adder_interact.rs b/contracts/examples/adder/interact/src/adder_interact.rs deleted file mode 100644 index 10df4ddf61..0000000000 --- a/contracts/examples/adder/interact/src/adder_interact.rs +++ /dev/null @@ -1,201 +0,0 @@ -mod adder_interact_cli; -mod adder_interact_config; -mod adder_interact_state; - -use adder::ProxyTrait; -use adder_interact_config::Config; -use adder_interact_state::State; -use clap::Parser; -use multiversx_sc_snippets::{ - env_logger, - multiversx_sc::{storage::mappers::SingleValue, types::Address}, - multiversx_sc_scenario::{ - api::StaticApi, - bech32, - mandos_system::ScenarioRunner, - num_bigint::BigUint, - scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext}, - scenario_model::{ - BytesValue, ScCallStep, ScDeployStep, ScQueryStep, Scenario, TransferStep, TxExpect, - }, - standalone::retrieve_account_as_scenario_set_state, - test_wallets, ContractInfo, - }, - tokio, Interactor, StepBuffer, -}; - -const INTERACTOR_SCENARIO_TRACE_PATH: &str = "interactor_trace.scen.json"; - -#[tokio::main] -async fn main() { - env_logger::init(); - - let mut adder_interact = AdderInteract::init().await; - - let cli = adder_interact_cli::InteractCli::parse(); - match &cli.command { - Some(adder_interact_cli::InteractCliCommand::Add(args)) => { - adder_interact.add(args.value).await; - }, - Some(adder_interact_cli::InteractCliCommand::Deploy) => { - adder_interact.deploy().await; - }, - Some(adder_interact_cli::InteractCliCommand::Feed) => { - adder_interact.feed_contract_egld().await; - }, - Some(adder_interact_cli::InteractCliCommand::MultiDeploy(args)) => { - adder_interact.multi_deploy(&args.count).await; - }, - Some(adder_interact_cli::InteractCliCommand::Sum) => { - adder_interact.print_sum().await; - }, - None => {}, - } -} - -#[allow(unused)] -struct AdderInteract { - interactor: Interactor, - wallet_address: Address, - adder_code: BytesValue, - state: State, -} - -impl AdderInteract { - async fn init() -> Self { - let config = Config::load_config(); - let mut interactor = Interactor::new(config.gateway()) - .await - .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) - .await; - let wallet_address = interactor.register_wallet(test_wallets::mike()); - let adder_code = BytesValue::interpret_from( - "mxsc:../output/adder.mxsc.json", - &InterpreterContext::default(), - ); - - Self { - interactor, - wallet_address, - adder_code, - state: State::load_state(), - } - } - - async fn set_state(&mut self) { - println!("wallet address: {}", bech32::encode(&self.wallet_address)); - let scenario_raw = retrieve_account_as_scenario_set_state( - Config::load_config().gateway().to_string(), - bech32::encode(&self.wallet_address), - true, - ) - .await; - - let scenario = Scenario::interpret_from(scenario_raw, &InterpreterContext::default()); - - self.interactor.pre_runners.run_scenario(&scenario); - self.interactor.post_runners.run_scenario(&scenario); - } - - async fn deploy(&mut self) { - self.set_state().await; - - self.interactor - .sc_deploy_use_result( - ScDeployStep::new() - .call(self.state.default_adder().init(BigUint::from(0u64))) - .from(&self.wallet_address) - .code(&self.adder_code), - |new_address, tr| { - tr.result.unwrap_or_else(|err| { - panic!( - "deploy failed: status: {}, message: {}", - err.status, err.message - ) - }); - - let new_address_bech32 = bech32::encode(&new_address); - println!("new address: {new_address_bech32}"); - - let new_address_expr = format!("bech32:{new_address_bech32}"); - self.state.set_adder_address(&new_address_expr); - }, - ) - .await; - } - - async fn multi_deploy(&mut self, count: &u8) { - if *count == 0 { - println!("count must be greater than 0"); - return; - } - - self.set_state().await; - println!("deploying {count} contracts..."); - - let mut steps = Vec::new(); - for _ in 0..*count { - let typed_sc_deploy = ScDeployStep::new() - .call(self.state.default_adder().init(0u32)) - .from(&self.wallet_address) - .code(&self.adder_code) - .gas_limit("70,000,000"); - - steps.push(typed_sc_deploy); - } - - self.interactor - .multi_sc_exec(StepBuffer::from_sc_deploy_vec(&mut steps)) - .await; - - for step in steps.iter() { - // warning: multi deploy not yet fully supported - // only works with last deployed address - // will be addressed in future versions - let new_deployed_address = step.response().new_deployed_address.clone(); - if let Some(new_address) = new_deployed_address { - let new_address_bech32 = bech32::encode(&new_address); - println!("new address: {new_address_bech32}"); - } else { - println!("deploy failed"); - return; - } - } - } - - async fn feed_contract_egld(&mut self) { - let _ = self - .interactor - .transfer( - TransferStep::new() - .from(&self.wallet_address) - .to(self.state.adder()) - .egld_value("0,050000000000000000"), - ) - .await; - } - - async fn add(&mut self, value: u64) { - self.interactor - .sc_call( - ScCallStep::new() - .call(self.state.adder().add(value)) - .from(&self.wallet_address) - .expect( - TxExpect::ok().additional_error_message("performing add failed with: "), - ), - ) - .await; - - println!("successfully performed add"); - } - - async fn print_sum(&mut self) { - self.interactor - .sc_query_use_result(ScQueryStep::new().call(self.state.adder().sum()), |tr| { - let sum: SingleValue = tr.result.unwrap(); - println!("sum: {}", sum.into()); - }) - .await; - } -} diff --git a/contracts/examples/adder/interact/src/basic_interact.rs b/contracts/examples/adder/interact/src/basic_interact.rs new file mode 100644 index 0000000000..ee11ac5844 --- /dev/null +++ b/contracts/examples/adder/interact/src/basic_interact.rs @@ -0,0 +1,169 @@ +mod basic_interact_cli; +mod basic_interact_config; +mod basic_interact_state; + +use adder::adder_proxy; +use basic_interact_config::Config; +use basic_interact_state::State; +use clap::Parser; + +use multiversx_sc_snippets::imports::*; + +const INTERACTOR_SCENARIO_TRACE_PATH: &str = "interactor_trace.scen.json"; + +#[tokio::main] +async fn main() { + env_logger::init(); + + let mut basic_interact = AdderInteract::init().await; + + let cli = basic_interact_cli::InteractCli::parse(); + match &cli.command { + Some(basic_interact_cli::InteractCliCommand::Add(args)) => { + basic_interact.add(args.value).await; + }, + Some(basic_interact_cli::InteractCliCommand::Deploy) => { + basic_interact.deploy().await; + }, + Some(basic_interact_cli::InteractCliCommand::Feed) => { + basic_interact.feed_contract_egld().await; + }, + Some(basic_interact_cli::InteractCliCommand::MultiDeploy(args)) => { + basic_interact.multi_deploy(&args.count).await; + }, + Some(basic_interact_cli::InteractCliCommand::Sum) => { + basic_interact.print_sum().await; + }, + None => {}, + } +} + +#[allow(unused)] +struct AdderInteract { + interactor: Interactor, + wallet_address: Bech32Address, + adder_code: BytesValue, + state: State, +} + +impl AdderInteract { + async fn init() -> Self { + let config = Config::load_config(); + let mut interactor = Interactor::new(config.gateway()) + .await + .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) + .await; + let wallet_address = interactor.register_wallet(test_wallets::mike()); + let adder_code = BytesValue::interpret_from( + "mxsc:../output/adder.mxsc.json", + &InterpreterContext::default(), + ); + + Self { + interactor, + wallet_address: wallet_address.into(), + adder_code, + state: State::load_state(), + } + } + + async fn set_state(&mut self) { + println!("wallet address: {}", self.wallet_address); + self.interactor.retrieve_account(&self.wallet_address).await; + } + + async fn deploy(&mut self) { + // warning: multi deploy not yet fully supported + // only works with last deployed address + + self.set_state().await; + + let new_address = self + .interactor + .tx() + .from(&self.wallet_address) + .typed(adder_proxy::AdderProxy) + .init(0u32) + .code(&self.adder_code) + .returns(ReturnsNewBech32Address) + .prepare_async() + .run() + .await; + + println!("new address: {new_address}"); + self.state.set_adder_address(new_address); + } + + async fn multi_deploy(&mut self, count: &u8) { + if *count == 0 { + println!("count must be greater than 0"); + return; + } + + self.set_state().await; + println!("deploying {count} contracts..."); + + let mut buffer = self.interactor.homogenous_call_buffer(); + for _ in 0..*count { + buffer.push_tx(|tx| { + tx.from(&self.wallet_address) + .typed(adder_proxy::AdderProxy) + .init(0u32) + .code(&self.adder_code) + .gas(NumExpr("70,000,000")) + .returns(ReturnsNewBech32Address) + }); + } + + let results = buffer.run().await; + + // warning: multi deploy not yet fully supported + // only works with last deployed address + + for new_address in results { + println!("new address: {new_address}"); + + self.state.set_adder_address(new_address); + } + } + + async fn feed_contract_egld(&mut self) { + self.interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_adder_address()) + .egld(NumExpr("0,050000000000000000")) + .prepare_async() + .run() + .await; + } + + async fn add(&mut self, value: u64) { + self.interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_adder_address()) + .typed(adder_proxy::AdderProxy) + .add(value) + .prepare_async() + .run() + .await; + + println!("successfully performed add"); + } + + async fn print_sum(&mut self) { + let sum = self + .interactor + .query() + .to(self.state.current_adder_address()) + .typed(adder_proxy::AdderProxy) + .sum() + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + println!("sum: {sum}"); + } +} diff --git a/contracts/examples/adder/interact/src/adder_interact_cli.rs b/contracts/examples/adder/interact/src/basic_interact_cli.rs similarity index 100% rename from contracts/examples/adder/interact/src/adder_interact_cli.rs rename to contracts/examples/adder/interact/src/basic_interact_cli.rs diff --git a/contracts/examples/adder/interact/src/adder_interact_config.rs b/contracts/examples/adder/interact/src/basic_interact_config.rs similarity index 100% rename from contracts/examples/adder/interact/src/adder_interact_config.rs rename to contracts/examples/adder/interact/src/basic_interact_config.rs diff --git a/contracts/examples/adder/interact/src/adder_interact_state.rs b/contracts/examples/adder/interact/src/basic_interact_state.rs similarity index 56% rename from contracts/examples/adder/interact/src/adder_interact_state.rs rename to contracts/examples/adder/interact/src/basic_interact_state.rs index 445eb52075..41453e36fd 100644 --- a/contracts/examples/adder/interact/src/adder_interact_state.rs +++ b/contracts/examples/adder/interact/src/basic_interact_state.rs @@ -1,23 +1,17 @@ -use crate::{ContractInfo, StaticApi}; +use multiversx_sc_snippets::imports::*; use serde::{Deserialize, Serialize}; use std::{ io::{Read, Write}, path::Path, }; -/// Default adder address -const DEFAULT_ADDER_ADDRESS: &str = - "0x0000000000000000000000000000000000000000000000000000000000000000"; - /// State file const STATE_FILE: &str = "state.toml"; -pub type AdderContract = ContractInfo>; - /// Multisig Interact state #[derive(Debug, Default, Serialize, Deserialize)] pub struct State { - adder_address: Option, + adder_address: Option, } impl State { @@ -34,22 +28,15 @@ impl State { } /// Sets the adder address - pub fn set_adder_address(&mut self, address: &str) { - self.adder_address = Some(String::from(address)); + pub fn set_adder_address(&mut self, address: Bech32Address) { + self.adder_address = Some(address); } /// Returns the adder contract - pub fn adder(&self) -> AdderContract { - AdderContract::new( - self.adder_address - .clone() - .expect("no known adder contract, deploy first"), - ) - } - - /// Returns the adder contract with default address - pub fn default_adder(&self) -> AdderContract { - AdderContract::new(DEFAULT_ADDER_ADDRESS) + pub fn current_adder_address(&self) -> &Bech32Address { + self.adder_address + .as_ref() + .expect("no known adder contract, deploy first") } } diff --git a/contracts/examples/adder/meta/Cargo.toml b/contracts/examples/adder/meta/Cargo.toml index caf3b453e2..964ddb176f 100644 --- a/contracts/examples/adder/meta/Cargo.toml +++ b/contracts/examples/adder/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.adder] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/adder/meta/src/main.rs b/contracts/examples/adder/meta/src/main.rs index a6cf7d2836..f37dd97362 100644 --- a/contracts/examples/adder/meta/src/main.rs +++ b/contracts/examples/adder/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/adder/mxsc-template.toml b/contracts/examples/adder/mxsc-template.toml index 59d08379d0..490557cc50 100644 --- a/contracts/examples/adder/mxsc-template.toml +++ b/contracts/examples/adder/mxsc-template.toml @@ -14,5 +14,11 @@ files_include = [ "tests", "Cargo.toml", "README.md", + "sc-config.toml", "multiversx.json", + "interact/Cargo.toml", + "interact/config.toml", + "interact/.gitignore", + "interact/src", ] +has_interactor = true diff --git a/contracts/examples/adder/sc-config.toml b/contracts/examples/adder/sc-config.toml new file mode 100644 index 0000000000..b56f82b429 --- /dev/null +++ b/contracts/examples/adder/sc-config.toml @@ -0,0 +1,4 @@ +[settings] + +[[proxy]] +path = "src/adder_proxy.rs" diff --git a/contracts/examples/adder/src/adder.rs b/contracts/examples/adder/src/adder.rs index ff08501b42..307f4112f5 100644 --- a/contracts/examples/adder/src/adder.rs +++ b/contracts/examples/adder/src/adder.rs @@ -2,6 +2,8 @@ use multiversx_sc::imports::*; +pub mod adder_proxy; + /// One of the simplest smart contracts possible, /// it holds a single variable in storage, which anyone can increment. #[multiversx_sc::contract] diff --git a/contracts/examples/adder/src/adder_proxy.rs b/contracts/examples/adder/src/adder_proxy.rs new file mode 100644 index 0000000000..fd79b14ac8 --- /dev/null +++ b/contracts/examples/adder/src/adder_proxy.rs @@ -0,0 +1,114 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct AdderProxy; + +impl TxProxyTrait for AdderProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = AdderProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + AdderProxyMethods { wrapped_tx: tx } + } +} + +pub struct AdderProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl AdderProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + >( + self, + initial_value: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&initial_value) + .original_result() + } +} + +#[rustfmt::skip] +impl AdderProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade< + Arg0: ProxyArg>, + >( + self, + initial_value: Arg0, + ) -> TxTypedUpgrade { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .argument(&initial_value) + .original_result() + } +} + +#[rustfmt::skip] +impl AdderProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn sum( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getSum") + .original_result() + } + + /// Add desired amount to the storage variable. + pub fn add< + Arg0: ProxyArg>, + >( + self, + value: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("add") + .argument(&value) + .original_result() + } +} diff --git a/contracts/examples/adder/tests/adder_blackbox_test.rs b/contracts/examples/adder/tests/adder_blackbox_test.rs index 92dba83b12..9f155c4e3a 100644 --- a/contracts/examples/adder/tests/adder_blackbox_test.rs +++ b/contracts/examples/adder/tests/adder_blackbox_test.rs @@ -1,53 +1,80 @@ -use multiversx_sc_scenario::{scenario_model::*, *}; +use multiversx_sc_scenario::imports::*; -const ADDER_PATH_EXPR: &str = "mxsc:output/adder.mxsc.json"; +use adder::*; + +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const ADDER_ADDRESS: TestSCAddress = TestSCAddress::new("adder"); +const CODE_PATH: MxscPath = MxscPath::new("output/adder.mxsc.json"); fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/adder"); - blockchain.register_contract(ADDER_PATH_EXPR, adder::ContractBuilder); + blockchain.register_contract(CODE_PATH, adder::ContractBuilder); blockchain } #[test] -fn adder_blackbox_raw() { +fn adder_blackbox() { let mut world = world(); - let adder_code = world.code_expression(ADDER_PATH_EXPR); + + world.start_trace(); + + world.account(OWNER_ADDRESS).nonce(1); + + let new_address = world + .tx() + .from(OWNER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .init(5u32) + .code(CODE_PATH) + .new_address(ADDER_ADDRESS) + .returns(ReturnsNewAddress) + .run(); + + assert_eq!(new_address, ADDER_ADDRESS.to_address()); + + world + .query() + .to(ADDER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .sum() + .returns(ExpectValue(5u32)) + .run(); + + world + .tx() + .from(OWNER_ADDRESS) + .to(ADDER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .add(1u32) + .run(); world - .set_state_step( - SetStateStep::new() - .put_account("address:owner", Account::new().nonce(1)) - .new_address("address:owner", 1, "sc:adder"), - ) - .sc_deploy( - ScDeployStep::new() - .from("address:owner") - .code(adder_code) - .argument("5") - .expect(TxExpect::ok().no_result()), - ) - .sc_query( - ScQueryStep::new() - .to("sc:adder") - .function("getSum") - .expect(TxExpect::ok().result("5")), - ) - .sc_call( - ScCallStep::new() - .from("address:owner") - .to("sc:adder") - .function("add") - .argument("3") - .expect(TxExpect::ok().no_result()), - ) - .check_state_step( - CheckStateStep::new() - .put_account("address:owner", CheckAccount::new()) - .put_account( - "sc:adder", - CheckAccount::new().check_storage("str:sum", "8"), - ), - ); + .query() + .to(ADDER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .sum() + .returns(ExpectValue(6u32)) + .run(); + + world.check_account(OWNER_ADDRESS); + + world + .check_account(ADDER_ADDRESS) + .check_storage("str:sum", "6"); + + world + .tx() + .from(OWNER_ADDRESS) + .to(ADDER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .upgrade(100u64) + .code(CODE_PATH) + .run(); + + world + .check_account(ADDER_ADDRESS) + .check_storage("str:sum", "100"); + + world.write_scenario_trace("trace1.scen.json"); } diff --git a/contracts/examples/adder/tests/adder_blackbox_with_values_test.rs b/contracts/examples/adder/tests/adder_blackbox_with_values_test.rs deleted file mode 100644 index 159b71cf14..0000000000 --- a/contracts/examples/adder/tests/adder_blackbox_with_values_test.rs +++ /dev/null @@ -1,59 +0,0 @@ -use adder::*; -use multiversx_sc::storage::mappers::SingleValue; -use multiversx_sc_scenario::{api::StaticApi, num_bigint::BigUint, scenario_model::*, *}; - -const ADDER_PATH_EXPR: &str = "mxsc:output/adder.mxsc.json"; - -fn world() -> ScenarioWorld { - let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/adder"); - - blockchain.register_contract(ADDER_PATH_EXPR, adder::ContractBuilder); - blockchain -} - -#[test] -fn adder_blackbox_with_values() { - let mut world = world(); - let owner_address = "address:owner"; - let mut adder_contract = ContractInfo::>::new("sc:adder"); - let adder_code = world.code_expression(ADDER_PATH_EXPR); - - world - .start_trace() - .set_state_step( - SetStateStep::new() - .put_account(owner_address, Account::new().nonce(1)) - .new_address(owner_address, 1, "sc:adder"), - ) - .sc_deploy_use_result( - ScDeployStep::new() - .from(owner_address) - .code(adder_code) - .call(adder_contract.init(5u32)), - |new_address, _: TypedResponse<()>| { - assert_eq!(new_address, adder_contract.to_address()); - }, - ) - .sc_query( - ScQueryStep::new() - .to(&adder_contract) - .call(adder_contract.sum()) - .expect_value(SingleValue::from(BigUint::from(5u32))), - ) - .sc_call( - ScCallStep::new() - .from(owner_address) - .to(&adder_contract) - .call(adder_contract.add(3u32)), - ) - .check_state_step( - CheckStateStep::new() - .put_account(owner_address, CheckAccount::new()) - .put_account( - &adder_contract, - CheckAccount::new().check_storage("str:sum", "8"), - ), - ) - .write_scenario_trace("trace1.scen.json"); -} diff --git a/contracts/examples/adder/tests/adder_scenario_rs_test.rs b/contracts/examples/adder/tests/adder_scenario_rs_test.rs index c467100633..f9ee7a3a1c 100644 --- a/contracts/examples/adder/tests/adder_scenario_rs_test.rs +++ b/contracts/examples/adder/tests/adder_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/adder"); blockchain.register_contract("mxsc:output/adder.mxsc.json", adder::ContractBuilder); blockchain diff --git a/contracts/examples/adder/tests/adder_test.rs b/contracts/examples/adder/tests/adder_unit_test.rs similarity index 100% rename from contracts/examples/adder/tests/adder_test.rs rename to contracts/examples/adder/tests/adder_unit_test.rs diff --git a/contracts/examples/adder/tests/adder_whitebox_test.rs b/contracts/examples/adder/tests/adder_whitebox_test.rs index d068aa1b1d..9e7abe4a51 100644 --- a/contracts/examples/adder/tests/adder_whitebox_test.rs +++ b/contracts/examples/adder/tests/adder_whitebox_test.rs @@ -1,11 +1,10 @@ use adder::*; -use multiversx_sc_scenario::{scenario_model::*, *}; +use multiversx_sc_scenario::imports::*; const ADDER_PATH_EXPR: &str = "mxsc:output/adder.mxsc.json"; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/adder"); blockchain.register_contract("mxsc:output/adder.mxsc.json", adder::ContractBuilder); blockchain diff --git a/contracts/examples/adder/wasm/Cargo.lock b/contracts/examples/adder/wasm/Cargo.lock index ee2b588c5d..2eaa0f5a3e 100755 --- a/contracts/examples/adder/wasm/Cargo.lock +++ b/contracts/examples/adder/wasm/Cargo.lock @@ -25,15 +25,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/adder/wasm/Cargo.toml b/contracts/examples/adder/wasm/Cargo.toml index 04be870421..2ca9584c8b 100644 --- a/contracts/examples/adder/wasm/Cargo.toml +++ b/contracts/examples/adder/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.adder] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/adder/wasm/src/lib.rs b/contracts/examples/adder/wasm/src/lib.rs index 13bb12ad6e..19ea33c7e1 100644 --- a/contracts/examples/adder/wasm/src/lib.rs +++ b/contracts/examples/adder/wasm/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 3 +// Upgrade: 1 +// Endpoints: 2 // Async Callback (empty): 1 // Total number of exported functions: 5 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -20,8 +19,8 @@ multiversx_sc_wasm_adapter::endpoints! { adder ( init => init - getSum => sum upgrade => upgrade + getSum => sum add => add ) } diff --git a/contracts/examples/bonding-curve-contract/Cargo.toml b/contracts/examples/bonding-curve-contract/Cargo.toml index 0b5939281e..52578184f5 100644 --- a/contracts/examples/bonding-curve-contract/Cargo.toml +++ b/contracts/examples/bonding-curve-contract/Cargo.toml @@ -9,14 +9,14 @@ publish = false path = "src/bonding_curve_contract.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/bonding-curve-contract/meta/Cargo.toml b/contracts/examples/bonding-curve-contract/meta/Cargo.toml index 91b330f0ab..e9b82637a6 100644 --- a/contracts/examples/bonding-curve-contract/meta/Cargo.toml +++ b/contracts/examples/bonding-curve-contract/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.bonding-curve-contract] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/bonding-curve-contract/meta/src/main.rs b/contracts/examples/bonding-curve-contract/meta/src/main.rs index 3dbf1a6723..18eedf0a32 100644 --- a/contracts/examples/bonding-curve-contract/meta/src/main.rs +++ b/contracts/examples/bonding-curve-contract/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/bonding-curve-contract/wasm/Cargo.lock b/contracts/examples/bonding-curve-contract/wasm/Cargo.lock index 4764163b77..68ea29d2b0 100644 --- a/contracts/examples/bonding-curve-contract/wasm/Cargo.lock +++ b/contracts/examples/bonding-curve-contract/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bonding-curve-contract" @@ -56,26 +56,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +87,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,14 +98,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/bonding-curve-contract/wasm/Cargo.toml b/contracts/examples/bonding-curve-contract/wasm/Cargo.toml index d95c21a85d..b0da11ce01 100644 --- a/contracts/examples/bonding-curve-contract/wasm/Cargo.toml +++ b/contracts/examples/bonding-curve-contract/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.bonding-curve-contract] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/bonding-curve-contract/wasm/src/lib.rs b/contracts/examples/bonding-curve-contract/wasm/src/lib.rs index ca35cf266b..9c9061f01f 100644 --- a/contracts/examples/bonding-curve-contract/wasm/src/lib.rs +++ b/contracts/examples/bonding-curve-contract/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 12 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/check-pause/Cargo.toml b/contracts/examples/check-pause/Cargo.toml index 956cff6046..1a2334ea09 100644 --- a/contracts/examples/check-pause/Cargo.toml +++ b/contracts/examples/check-pause/Cargo.toml @@ -12,14 +12,14 @@ path = "src/check_pause.rs" num-bigint = "0.4" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/check-pause/meta/Cargo.toml b/contracts/examples/check-pause/meta/Cargo.toml index db3e95ad78..2601f0bd94 100644 --- a/contracts/examples/check-pause/meta/Cargo.toml +++ b/contracts/examples/check-pause/meta/Cargo.toml @@ -8,7 +8,7 @@ authors = ["Alin Cruceat "] [dependencies.check-pause] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/check-pause/meta/src/main.rs b/contracts/examples/check-pause/meta/src/main.rs index 50f10f59cb..d37ef9c9b0 100644 --- a/contracts/examples/check-pause/meta/src/main.rs +++ b/contracts/examples/check-pause/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/check-pause/wasm/Cargo.lock b/contracts/examples/check-pause/wasm/Cargo.lock index 659770d735..264fedbbf0 100644 --- a/contracts/examples/check-pause/wasm/Cargo.lock +++ b/contracts/examples/check-pause/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "check-pause" @@ -56,26 +56,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +87,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,14 +98,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/check-pause/wasm/Cargo.toml b/contracts/examples/check-pause/wasm/Cargo.toml index 619a7270c4..941fc29f67 100644 --- a/contracts/examples/check-pause/wasm/Cargo.toml +++ b/contracts/examples/check-pause/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.check-pause] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/check-pause/wasm/src/lib.rs b/contracts/examples/check-pause/wasm/src/lib.rs index 550768b6ee..5bf4ed5b95 100644 --- a/contracts/examples/check-pause/wasm/src/lib.rs +++ b/contracts/examples/check-pause/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 6 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/crowdfunding-esdt/Cargo.toml b/contracts/examples/crowdfunding-esdt/Cargo.toml index 5a5a94d5a3..51ab699206 100644 --- a/contracts/examples/crowdfunding-esdt/Cargo.toml +++ b/contracts/examples/crowdfunding-esdt/Cargo.toml @@ -9,11 +9,11 @@ publish = false path = "src/crowdfunding_esdt.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dev-dependencies] diff --git a/contracts/examples/crowdfunding-esdt/meta/Cargo.toml b/contracts/examples/crowdfunding-esdt/meta/Cargo.toml index b5bef9909d..fb5196e7e8 100644 --- a/contracts/examples/crowdfunding-esdt/meta/Cargo.toml +++ b/contracts/examples/crowdfunding-esdt/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.crowdfunding-esdt] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/crowdfunding-esdt/meta/src/main.rs b/contracts/examples/crowdfunding-esdt/meta/src/main.rs index 7635e097f5..cd0281368b 100644 --- a/contracts/examples/crowdfunding-esdt/meta/src/main.rs +++ b/contracts/examples/crowdfunding-esdt/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/crowdfunding-esdt/sc-config.toml b/contracts/examples/crowdfunding-esdt/sc-config.toml new file mode 100644 index 0000000000..16f6430728 --- /dev/null +++ b/contracts/examples/crowdfunding-esdt/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "src/crowdfunding_esdt_proxy.rs" diff --git a/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs b/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs index 8fa04d2e46..1dea493562 100644 --- a/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs +++ b/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs @@ -1,8 +1,10 @@ #![no_std] use multiversx_sc::{derive_imports::*, imports::*}; +pub mod crowdfunding_esdt_proxy; -#[derive(TopEncode, TopDecode, TypeAbi, PartialEq, Eq, Clone, Copy, Debug)] +#[type_abi] +#[derive(TopEncode, TopDecode, PartialEq, Eq, Clone, Copy, Debug)] pub enum Status { FundingPeriod, Successful, @@ -73,8 +75,10 @@ pub trait Crowdfunding { let token_identifier = self.cf_token_identifier().get(); let sc_balance = self.get_current_funds(); - self.send() - .direct(&caller, &token_identifier, 0, &sc_balance); + self.tx() + .to(&caller) + .egld_or_single_esdt(&token_identifier, 0, &sc_balance) + .transfer(); }, Status::Failed => { let caller = self.blockchain().get_caller(); @@ -84,7 +88,10 @@ pub trait Crowdfunding { let token_identifier = self.cf_token_identifier().get(); self.deposit(&caller).clear(); - self.send().direct(&caller, &token_identifier, 0, &deposit); + self.tx() + .to(&caller) + .egld_or_single_esdt(&token_identifier, 0, &deposit) + .transfer(); } }, } diff --git a/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt_proxy.rs b/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt_proxy.rs new file mode 100644 index 0000000000..aabd42cc08 --- /dev/null +++ b/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt_proxy.rs @@ -0,0 +1,157 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct CrowdfundingProxy; + +impl TxProxyTrait for CrowdfundingProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = CrowdfundingProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + CrowdfundingProxyMethods { wrapped_tx: tx } + } +} + +pub struct CrowdfundingProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl CrowdfundingProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + target: Arg0, + deadline: Arg1, + token_identifier: Arg2, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&target) + .argument(&deadline) + .argument(&token_identifier) + .original_result() + } +} + +#[rustfmt::skip] +impl CrowdfundingProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn fund( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("fund") + .original_result() + } + + pub fn status( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("status") + .original_result() + } + + pub fn get_current_funds( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getCurrentFunds") + .original_result() + } + + pub fn claim( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("claim") + .original_result() + } + + pub fn target( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getTarget") + .original_result() + } + + pub fn deadline( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getDeadline") + .original_result() + } + + pub fn deposit< + Arg0: ProxyArg>, + >( + self, + donor: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getDeposit") + .argument(&donor) + .original_result() + } + + pub fn cf_token_identifier( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getCrowdfundingTokenIdentifier") + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode, PartialEq, Eq, Clone, Copy, Debug)] +pub enum Status { + FundingPeriod, + Successful, + Failed, +} diff --git a/contracts/examples/crowdfunding-esdt/tests/crowdfunding_esdt_blackbox_test.rs b/contracts/examples/crowdfunding-esdt/tests/crowdfunding_esdt_blackbox_test.rs index c6387e5c43..d00e263607 100644 --- a/contracts/examples/crowdfunding-esdt/tests/crowdfunding_esdt_blackbox_test.rs +++ b/contracts/examples/crowdfunding-esdt/tests/crowdfunding_esdt_blackbox_test.rs @@ -1,157 +1,116 @@ -use crowdfunding_esdt::{ProxyTrait as _, Status}; -use multiversx_sc::{ - storage::mappers::SingleValue, - types::{Address, EgldOrEsdtTokenIdentifier}, -}; -use multiversx_sc_scenario::{ - api::StaticApi, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, ScDeployStep, ScQueryStep, - SetStateStep, TxExpect, - }, - ContractInfo, ScenarioWorld, -}; -use num_bigint::BigUint; +use crowdfunding_esdt::crowdfunding_esdt_proxy; -const CF_DEADLINE: u64 = 7 * 24 * 60 * 60; // 1 week in seconds -const CF_TOKEN_ID: &[u8] = b"CROWD-123456"; -const CF_TOKEN_ID_EXPR: &str = "str:CROWD-123456"; -const CROWDFUNDING_ESDT_ADDRESS_EXPR: &str = "sc:crowdfunding-esdt"; -const CROWDFUNDING_ESDT_PATH_EXPR: &str = "mxsc:output/crowdfunding-esdt.mxsc.json"; -const FIRST_USER_ADDRESS_EXPR: &str = "address:first-user"; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const SECOND_USER_ADDRESS_EXPR: &str = "address:second-user"; +use multiversx_sc_scenario::imports::*; -type CrowdfundingESDTContract = ContractInfo>; +const CF_DEADLINE: u64 = 7 * 24 * 60 * 60; // 1 week in seconds +const CF_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("CROWD-123456"); +const FIRST_USER_ADDRESS: TestAddress = TestAddress::new("first-user"); +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const SECOND_USER_ADDRESS: TestAddress = TestAddress::new("second-user"); +const CODE_PATH: MxscPath = MxscPath::new("output/crowdfunding-esdt.mxsc.json"); +const CROWDFUNDING_ADDRESS: TestSCAddress = TestSCAddress::new("crowdfunding-esdt"); fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/crowdfunding-esdt"); - blockchain.register_contract( - CROWDFUNDING_ESDT_PATH_EXPR, - crowdfunding_esdt::ContractBuilder, - ); + blockchain.register_contract(CODE_PATH, crowdfunding_esdt::ContractBuilder); blockchain } struct CrowdfundingESDTTestState { world: ScenarioWorld, - crowdfunding_esdt_contract: CrowdfundingESDTContract, - first_user_address: Address, - second_user_address: Address, } impl CrowdfundingESDTTestState { fn new() -> Self { let mut world = world(); - world.set_state_step( - SetStateStep::new() - .put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .new_address(OWNER_ADDRESS_EXPR, 1, CROWDFUNDING_ESDT_ADDRESS_EXPR) - .put_account( - FIRST_USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .balance("1_000") - .esdt_balance(CF_TOKEN_ID_EXPR, "1_000"), - ) - .put_account( - SECOND_USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(CF_TOKEN_ID_EXPR, "1_000"), - ), - ); - - let crowdfunding_esdt_contract = - CrowdfundingESDTContract::new(CROWDFUNDING_ESDT_ADDRESS_EXPR); - - let first_user_address = AddressValue::from(FIRST_USER_ADDRESS_EXPR).to_address(); - let second_user_address = AddressValue::from(SECOND_USER_ADDRESS_EXPR).to_address(); - - Self { - world, - crowdfunding_esdt_contract, - first_user_address, - second_user_address, - } - } + world.account(OWNER_ADDRESS).nonce(1); - fn deploy(&mut self) -> &mut Self { - let crowdfunding_esdt_code = self.world.code_expression(CROWDFUNDING_ESDT_PATH_EXPR); - - self.world.sc_deploy( - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(crowdfunding_esdt_code) - .call(self.crowdfunding_esdt_contract.init( - 2_000u32, - CF_DEADLINE, - EgldOrEsdtTokenIdentifier::esdt(CF_TOKEN_ID), - )), - ); - - self - } + world + .account(FIRST_USER_ADDRESS) + .nonce(1) + .balance(1000) + .esdt_balance(CF_TOKEN_ID, 1000); - fn fund(&mut self, address: &str, amount: &str) -> &mut Self { - self.world.sc_call( - ScCallStep::new() - .from(address) - .esdt_transfer(CF_TOKEN_ID_EXPR, 0, amount) - .call(self.crowdfunding_esdt_contract.fund()), - ); + world + .account(SECOND_USER_ADDRESS) + .nonce(1) + .esdt_balance(CF_TOKEN_ID, 1000); - self + Self { world } } - fn check_deposit(&mut self, donor: Address, amount: u64) -> &mut Self { - self.world.sc_query( - ScQueryStep::new() - .call(self.crowdfunding_esdt_contract.deposit(&donor)) - .expect_value(SingleValue::from(BigUint::from(amount))), - ); - - self + fn deploy(&mut self) { + self.world + .tx() + .from(OWNER_ADDRESS) + .typed(crowdfunding_esdt_proxy::CrowdfundingProxy) + .init( + 2_000u32, + CF_DEADLINE, + EgldOrEsdtTokenIdentifier::esdt(CF_TOKEN_ID), + ) + .code(CODE_PATH) + .new_address(CROWDFUNDING_ADDRESS) + .run(); } - fn check_status(&mut self, expected_value: Status) -> &mut Self { - self.world.sc_query( - ScQueryStep::new() - .call(self.crowdfunding_esdt_contract.status()) - .expect_value(expected_value), - ); - - self + fn fund(&mut self, address: TestAddress, amount: u64) { + self.world + .tx() + .from(address) + .to(CROWDFUNDING_ADDRESS) + .typed(crowdfunding_esdt_proxy::CrowdfundingProxy) + .fund() + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(CF_TOKEN_ID), + 0u64, + &multiversx_sc::proxy_imports::BigUint::from(amount), + ) + .run(); } - fn claim(&mut self, address: &str) -> &mut Self { - self.world.sc_call( - ScCallStep::new() - .from(address) - .call(self.crowdfunding_esdt_contract.claim()), - ); - - self + fn check_deposit(&mut self, donor: TestAddress, amount: u64) { + self.world + .query() + .to(CROWDFUNDING_ADDRESS) + .typed(crowdfunding_esdt_proxy::CrowdfundingProxy) + .deposit(donor) + .returns(ExpectValue(amount)) + .run(); } - fn check_esdt_balance(&mut self, address_expr: &str, balance_expr: &str) -> &mut Self { + fn check_status(&mut self, expected_value: crowdfunding_esdt_proxy::Status) { self.world - .check_state_step(CheckStateStep::new().put_account( - address_expr, - CheckAccount::new().esdt_balance(CF_TOKEN_ID_EXPR, balance_expr), - )); + .query() + .to(CROWDFUNDING_ADDRESS) + .typed(crowdfunding_esdt_proxy::CrowdfundingProxy) + .status() + .returns(ExpectValue(expected_value)) + .run(); + } - self + fn claim(&mut self, address: TestAddress) { + self.world + .tx() + .from(address) + .to(CROWDFUNDING_ADDRESS) + .typed(crowdfunding_esdt_proxy::CrowdfundingProxy) + .claim() + .run(); } - fn set_block_timestamp(&mut self, block_timestamp_expr: u64) -> &mut Self { + fn check_esdt_balance(&mut self, address: TestAddress, balance: u64) { self.world - .set_state_step(SetStateStep::new().block_timestamp(block_timestamp_expr)); + .check_account(address) + .esdt_balance(CF_TOKEN_ID, balance); + } - self + fn set_block_timestamp(&mut self, block_timestamp_expr: u64) { + self.world + .current_block() + .block_timestamp(block_timestamp_expr); } } @@ -160,8 +119,8 @@ fn test_fund() { let mut state = CrowdfundingESDTTestState::new(); state.deploy(); - state.fund(FIRST_USER_ADDRESS_EXPR, "1000"); - state.check_deposit(state.first_user_address.clone(), 1_000); + state.fund(FIRST_USER_ADDRESS, 1_000u64); + state.check_deposit(FIRST_USER_ADDRESS, 1_000u64); } #[test] @@ -169,7 +128,7 @@ fn test_status() { let mut state = CrowdfundingESDTTestState::new(); state.deploy(); - state.check_status(Status::FundingPeriod); + state.check_status(crowdfunding_esdt_proxy::Status::FundingPeriod); } #[test] @@ -177,22 +136,18 @@ fn test_sc_error() { let mut state = CrowdfundingESDTTestState::new(); state.deploy(); - state.world.sc_call( - ScCallStep::new() - .from(FIRST_USER_ADDRESS_EXPR) - .egld_value("1_000") - .call(state.crowdfunding_esdt_contract.fund()) - .expect(TxExpect::user_error("str:wrong token")), - ); - state.world.sc_query( - ScQueryStep::new() - .call( - state - .crowdfunding_esdt_contract - .deposit(&state.first_user_address), - ) - .expect(TxExpect::ok().result("0x")), - ); + state + .world + .tx() + .from(FIRST_USER_ADDRESS) + .to(CROWDFUNDING_ADDRESS) + .typed(crowdfunding_esdt_proxy::CrowdfundingProxy) + .fund() + .egld(1000) + .with_result(ExpectError(4, "wrong token")) + .run(); + + state.check_deposit(FIRST_USER_ADDRESS, 0); } #[test] @@ -201,35 +156,35 @@ fn test_successful_cf() { state.deploy(); // first user fund - state.fund(FIRST_USER_ADDRESS_EXPR, "1_000"); - state.check_deposit(state.first_user_address.clone(), 1_000); + state.fund(FIRST_USER_ADDRESS, 1_000u64); + state.check_deposit(FIRST_USER_ADDRESS, 1_000); // second user fund - state.fund(SECOND_USER_ADDRESS_EXPR, "1_000"); - state.check_deposit(state.second_user_address.clone(), 1_000); + state.fund(SECOND_USER_ADDRESS, 1000); + state.check_deposit(SECOND_USER_ADDRESS, 1_000); // set block timestamp after deadline state.set_block_timestamp(CF_DEADLINE + 1); // check status successful - state.check_status(Status::Successful); - - // user try claim - state.world.sc_call( - ScCallStep::new() - .from(FIRST_USER_ADDRESS_EXPR) - .call(state.crowdfunding_esdt_contract.claim()) - .expect(TxExpect::user_error( - "str:only owner can claim successful funding", - )), - ); + state.check_status(crowdfunding_esdt_proxy::Status::Successful); + + state + .world + .tx() + .from(FIRST_USER_ADDRESS) + .to(CROWDFUNDING_ADDRESS) + .typed(crowdfunding_esdt_proxy::CrowdfundingProxy) + .claim() + .with_result(ExpectError(4, "only owner can claim successful funding")) + .run(); // owner claim - state.claim(OWNER_ADDRESS_EXPR); + state.claim(OWNER_ADDRESS); - state.check_esdt_balance(OWNER_ADDRESS_EXPR, "2_000"); - state.check_esdt_balance(FIRST_USER_ADDRESS_EXPR, "0"); - state.check_esdt_balance(SECOND_USER_ADDRESS_EXPR, "0"); + state.check_esdt_balance(OWNER_ADDRESS, 2000); + state.check_esdt_balance(FIRST_USER_ADDRESS, 0); + state.check_esdt_balance(SECOND_USER_ADDRESS, 0); } #[test] @@ -238,26 +193,26 @@ fn test_failed_cf() { state.deploy(); // first user fund - state.fund(FIRST_USER_ADDRESS_EXPR, "300"); - state.check_deposit(state.first_user_address.clone(), 300u64); + state.fund(FIRST_USER_ADDRESS, 300); + state.check_deposit(FIRST_USER_ADDRESS, 300u64); // second user fund - state.fund(SECOND_USER_ADDRESS_EXPR, "600"); - state.check_deposit(state.second_user_address.clone(), 600u64); + state.fund(SECOND_USER_ADDRESS, 600); + state.check_deposit(SECOND_USER_ADDRESS, 600u64); // set block timestamp after deadline state.set_block_timestamp(CF_DEADLINE + 1); // check status failed - state.check_status(Status::Failed); + state.check_status(crowdfunding_esdt_proxy::Status::Failed); // first user claim - state.claim(FIRST_USER_ADDRESS_EXPR); + state.claim(FIRST_USER_ADDRESS); // second user claim - state.claim(SECOND_USER_ADDRESS_EXPR); + state.claim(SECOND_USER_ADDRESS); - state.check_esdt_balance(OWNER_ADDRESS_EXPR, "0"); - state.check_esdt_balance(FIRST_USER_ADDRESS_EXPR, "1_000"); - state.check_esdt_balance(SECOND_USER_ADDRESS_EXPR, "1_000"); + state.check_esdt_balance(OWNER_ADDRESS, 0); + state.check_esdt_balance(FIRST_USER_ADDRESS, 1000); + state.check_esdt_balance(SECOND_USER_ADDRESS, 1000); } diff --git a/contracts/examples/crowdfunding-esdt/tests/crowdfunding_esdt_scenario_rs_test.rs b/contracts/examples/crowdfunding-esdt/tests/crowdfunding_esdt_scenario_rs_test.rs index b26e2488e8..64a88906b2 100644 --- a/contracts/examples/crowdfunding-esdt/tests/crowdfunding_esdt_scenario_rs_test.rs +++ b/contracts/examples/crowdfunding-esdt/tests/crowdfunding_esdt_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/crowdfunding-esdt"); blockchain.register_contract( "mxsc:output/crowdfunding-esdt.mxsc.json", diff --git a/contracts/examples/crowdfunding-esdt/wasm/Cargo.lock b/contracts/examples/crowdfunding-esdt/wasm/Cargo.lock index 06a703eb14..2f4c595365 100644 --- a/contracts/examples/crowdfunding-esdt/wasm/Cargo.lock +++ b/contracts/examples/crowdfunding-esdt/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "crowdfunding-esdt" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/crowdfunding-esdt/wasm/Cargo.toml b/contracts/examples/crowdfunding-esdt/wasm/Cargo.toml index 877d8761fb..fc9eedb465 100644 --- a/contracts/examples/crowdfunding-esdt/wasm/Cargo.toml +++ b/contracts/examples/crowdfunding-esdt/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.crowdfunding-esdt] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/crowdfunding-esdt/wasm/src/lib.rs b/contracts/examples/crowdfunding-esdt/wasm/src/lib.rs index 6a27253313..eb3d65740b 100644 --- a/contracts/examples/crowdfunding-esdt/wasm/src/lib.rs +++ b/contracts/examples/crowdfunding-esdt/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/crypto-bubbles/Cargo.toml b/contracts/examples/crypto-bubbles/Cargo.toml index f63a8b8af5..5fbe867d85 100644 --- a/contracts/examples/crypto-bubbles/Cargo.toml +++ b/contracts/examples/crypto-bubbles/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/crypto_bubbles.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/crypto-bubbles/meta/Cargo.toml b/contracts/examples/crypto-bubbles/meta/Cargo.toml index 1defd419e1..50438e8b93 100644 --- a/contracts/examples/crypto-bubbles/meta/Cargo.toml +++ b/contracts/examples/crypto-bubbles/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.crypto-bubbles] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/crypto-bubbles/meta/src/main.rs b/contracts/examples/crypto-bubbles/meta/src/main.rs index 7f34c36f5e..c268a4df82 100644 --- a/contracts/examples/crypto-bubbles/meta/src/main.rs +++ b/contracts/examples/crypto-bubbles/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs b/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs index da481fd273..35b687f2cc 100644 --- a/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs +++ b/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs @@ -38,7 +38,7 @@ pub trait CryptoBubbles { *balance -= amount; }); - self.send().direct_egld(player, amount); + self.tx().to(player).egld(amount).transfer(); self.withdraw_event(player, amount); } diff --git a/contracts/examples/crypto-bubbles/tests/crypto_bubbles_scenario_rs_test.rs b/contracts/examples/crypto-bubbles/tests/crypto_bubbles_scenario_rs_test.rs index 7beee20ecb..134133a68b 100644 --- a/contracts/examples/crypto-bubbles/tests/crypto_bubbles_scenario_rs_test.rs +++ b/contracts/examples/crypto-bubbles/tests/crypto_bubbles_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/crypto-bubbles"); blockchain.register_contract( "mxsc:output/crypto-bubbles.mxsc.json", diff --git a/contracts/examples/crypto-bubbles/wasm/Cargo.lock b/contracts/examples/crypto-bubbles/wasm/Cargo.lock index f2c55800ed..ac6ca1b14b 100755 --- a/contracts/examples/crypto-bubbles/wasm/Cargo.lock +++ b/contracts/examples/crypto-bubbles/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "crypto-bubbles" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/crypto-bubbles/wasm/Cargo.toml b/contracts/examples/crypto-bubbles/wasm/Cargo.toml index 5f8975e177..451f424304 100644 --- a/contracts/examples/crypto-bubbles/wasm/Cargo.toml +++ b/contracts/examples/crypto-bubbles/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.crypto-bubbles] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/crypto-bubbles/wasm/src/lib.rs b/contracts/examples/crypto-bubbles/wasm/src/lib.rs index 97bc42e80e..925de32570 100644 --- a/contracts/examples/crypto-bubbles/wasm/src/lib.rs +++ b/contracts/examples/crypto-bubbles/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 8 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/crypto-kitties/common/kitty/Cargo.toml b/contracts/examples/crypto-kitties/common/kitty/Cargo.toml index 495b1894ff..5508f1bedc 100644 --- a/contracts/examples/crypto-kitties/common/kitty/Cargo.toml +++ b/contracts/examples/crypto-kitties/common/kitty/Cargo.toml @@ -9,7 +9,7 @@ publish = false path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/base" [dependencies.random] diff --git a/contracts/examples/crypto-kitties/common/kitty/src/color.rs b/contracts/examples/crypto-kitties/common/kitty/src/color.rs index 0b02aecf49..37a97b1dfc 100644 --- a/contracts/examples/crypto-kitties/common/kitty/src/color.rs +++ b/contracts/examples/crypto-kitties/common/kitty/src/color.rs @@ -2,7 +2,8 @@ use multiversx_sc::derive_imports::*; use random::*; -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, Clone, TypeAbi, Default)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, Clone, Default)] pub struct Color { pub r: u8, pub g: u8, @@ -36,3 +37,9 @@ impl Randomizeable for Color { } } } + +impl Color { + pub fn as_u64(&self) -> u64 { + ((self.r.to_be() as u64) << 4 | self.r.to_be() as u64) << 4 | self.r.to_be() as u64 + } +} diff --git a/contracts/examples/crypto-kitties/common/kitty/src/kitty.rs b/contracts/examples/crypto-kitties/common/kitty/src/kitty.rs new file mode 100644 index 0000000000..d234cac9f6 --- /dev/null +++ b/contracts/examples/crypto-kitties/common/kitty/src/kitty.rs @@ -0,0 +1,89 @@ +use crate::{Color, KittyGenes}; + +use multiversx_sc::derive_imports::*; + +const SECONDS_PER_MINUTE: u64 = 60; +const MAX_COOLDOWN: u64 = 60 * 60 * 24 * 7; // 7 days +const MAX_TIREDNESS: u16 = 20; + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct Kitty { + pub genes: KittyGenes, + pub birth_time: u64, // timestamp + pub cooldown_end: u64, // timestamp, used for pregnancy timer and siring cooldown + pub matron_id: u32, + pub sire_id: u32, + pub siring_with_id: u32, // for pregnant cats, 0 otherwise + pub nr_children: u16, // cooldown period increases exponentially with every breeding/siring + pub generation: u16, // max(sire_gen, matron_gen) + 1. Generation also influences cooldown. +} + +impl Kitty { + pub fn new( + genes: KittyGenes, + birth_time: u64, + matron_id: u32, + sire_id: u32, + generation: u16, + ) -> Self { + Kitty { + genes, + birth_time, + cooldown_end: 0, + matron_id, + sire_id, + siring_with_id: 0, + nr_children: 0, + generation, + } + } +} + +impl Kitty { + pub fn get_next_cooldown_time(&self) -> u64 { + let tiredness = self.nr_children + self.generation / 2; + if tiredness > MAX_TIREDNESS { + return MAX_COOLDOWN; + } + + let cooldown = SECONDS_PER_MINUTE << tiredness; // 2^(tiredness) minutes + if cooldown > MAX_COOLDOWN { + MAX_COOLDOWN + } else { + cooldown + } + } + + pub fn get_fur_color(&self) -> Color { + self.genes.fur_color.clone() + } + + pub fn get_eye_color(&self) -> Color { + self.genes.eye_color.clone() + } + + pub fn get_meow_power(&self) -> u8 { + self.genes.meow_power + } + + pub fn is_pregnant(&self) -> bool { + self.siring_with_id != 0 + } +} + +// The default Kitty, which is not a valid kitty. Used for Kitty with ID 0 +impl Default for Kitty { + fn default() -> Self { + Kitty { + genes: KittyGenes::default(), + birth_time: 0, + cooldown_end: u64::MAX, + matron_id: 0, + sire_id: 0, + siring_with_id: 0, + nr_children: 0, + generation: 0, + } + } +} diff --git a/contracts/examples/crypto-kitties/common/kitty/src/kitty_genes.rs b/contracts/examples/crypto-kitties/common/kitty/src/kitty_genes.rs index 4deb4100e6..61d6623bf9 100644 --- a/contracts/examples/crypto-kitties/common/kitty/src/kitty_genes.rs +++ b/contracts/examples/crypto-kitties/common/kitty/src/kitty_genes.rs @@ -3,7 +3,8 @@ use multiversx_sc::derive_imports::*; use super::color::*; use random::*; -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, Clone, TypeAbi, Default)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, Clone, Default)] pub struct KittyGenes { pub fur_color: Color, pub eye_color: Color, @@ -19,3 +20,10 @@ impl Randomizeable for KittyGenes { } } } + +impl KittyGenes { + pub fn get_as_u64(&self) -> u64 { + (self.fur_color.as_u64() << 12 | self.eye_color.as_u64()) << 4 + | self.meow_power.to_be() as u64 + } +} diff --git a/contracts/examples/crypto-kitties/common/kitty/src/lib.rs b/contracts/examples/crypto-kitties/common/kitty/src/lib.rs index c06f376e8d..863944215c 100644 --- a/contracts/examples/crypto-kitties/common/kitty/src/lib.rs +++ b/contracts/examples/crypto-kitties/common/kitty/src/lib.rs @@ -1,94 +1,9 @@ #![no_std] -use multiversx_sc::derive_imports::*; +mod color; +mod kitty; +mod kitty_genes; -const SECONDS_PER_MINUTE: u64 = 60; -const MAX_COOLDOWN: u64 = 60 * 60 * 24 * 7; // 7 days -const MAX_TIREDNESS: u16 = 20; - -pub mod color; -pub mod kitty_genes; - -use color::*; -use kitty_genes::*; - -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] -pub struct Kitty { - pub genes: KittyGenes, - pub birth_time: u64, // timestamp - pub cooldown_end: u64, // timestamp, used for pregnancy timer and siring cooldown - pub matron_id: u32, - pub sire_id: u32, - pub siring_with_id: u32, // for pregnant cats, 0 otherwise - pub nr_children: u16, // cooldown period increases exponentially with every breeding/siring - pub generation: u16, // max(sire_gen, matron_gen) + 1. Generation also influences cooldown. -} - -impl Kitty { - pub fn new( - genes: KittyGenes, - birth_time: u64, - matron_id: u32, - sire_id: u32, - generation: u16, - ) -> Self { - Kitty { - genes, - birth_time, - cooldown_end: 0, - matron_id, - sire_id, - siring_with_id: 0, - nr_children: 0, - generation, - } - } -} - -impl Kitty { - pub fn get_next_cooldown_time(&self) -> u64 { - let tiredness = self.nr_children + self.generation / 2; - if tiredness > MAX_TIREDNESS { - return MAX_COOLDOWN; - } - - let cooldown = SECONDS_PER_MINUTE << tiredness; // 2^(tiredness) minutes - if cooldown > MAX_COOLDOWN { - MAX_COOLDOWN - } else { - cooldown - } - } - - pub fn get_fur_color(&self) -> Color { - self.genes.fur_color.clone() - } - - pub fn get_eye_color(&self) -> Color { - self.genes.eye_color.clone() - } - - pub fn get_meow_power(&self) -> u8 { - self.genes.meow_power - } - - pub fn is_pregnant(&self) -> bool { - self.siring_with_id != 0 - } -} - -// The default Kitty, which is not a valid kitty. Used for Kitty with ID 0 -impl Default for Kitty { - fn default() -> Self { - Kitty { - genes: KittyGenes::default(), - birth_time: 0, - cooldown_end: u64::MAX, - matron_id: 0, - sire_id: 0, - siring_with_id: 0, - nr_children: 0, - generation: 0, - } - } -} +pub use color::Color; +pub use kitty::Kitty; +pub use kitty_genes::KittyGenes; diff --git a/contracts/examples/crypto-kitties/common/random/Cargo.toml b/contracts/examples/crypto-kitties/common/random/Cargo.toml index 2cc2fc4bd9..1ae1c308f7 100644 --- a/contracts/examples/crypto-kitties/common/random/Cargo.toml +++ b/contracts/examples/crypto-kitties/common/random/Cargo.toml @@ -8,5 +8,5 @@ edition = "2021" path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/base" diff --git a/contracts/examples/crypto-kitties/kitty-auction/Cargo.toml b/contracts/examples/crypto-kitties/kitty-auction/Cargo.toml index 646835ce94..f71784afd8 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-auction/Cargo.toml @@ -17,9 +17,9 @@ version = "0.0.0" path = "../kitty-ownership" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/examples/crypto-kitties/kitty-auction/meta/Cargo.toml b/contracts/examples/crypto-kitties/kitty-auction/meta/Cargo.toml index 2adc1e4a32..020d0c7b69 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/meta/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-auction/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.kitty-auction] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/crypto-kitties/kitty-auction/meta/src/main.rs b/contracts/examples/crypto-kitties/kitty-auction/meta/src/main.rs index 805ea84af4..70f1f93905 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/meta/src/main.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/crypto-kitties/kitty-auction/src/auction.rs b/contracts/examples/crypto-kitties/kitty-auction/src/auction.rs index fda71eb13d..261def0cf0 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/src/auction.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/src/auction.rs @@ -11,7 +11,8 @@ pub enum AuctionType { Siring, } -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct Auction { pub auction_type: AuctionType, pub starting_price: BigUint, diff --git a/contracts/examples/crypto-kitties/kitty-auction/src/kitty_ownership_proxy.rs b/contracts/examples/crypto-kitties/kitty-auction/src/kitty_ownership_proxy.rs new file mode 100644 index 0000000000..bc9c123f8e --- /dev/null +++ b/contracts/examples/crypto-kitties/kitty-auction/src/kitty_ownership_proxy.rs @@ -0,0 +1,360 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct KittyOwnershipProxy; + +impl TxProxyTrait for KittyOwnershipProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = KittyOwnershipProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + KittyOwnershipProxyMethods { wrapped_tx: tx } + } +} + +pub struct KittyOwnershipProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl KittyOwnershipProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + Arg2: ProxyArg>>, + >( + self, + birth_fee: Arg0, + opt_gene_science_contract_address: Arg1, + opt_kitty_auction_contract_address: Arg2, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&birth_fee) + .argument(&opt_gene_science_contract_address) + .argument(&opt_kitty_auction_contract_address) + .original_result() + } +} + +#[rustfmt::skip] +impl KittyOwnershipProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn set_gene_science_contract_address_endpoint< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("setGeneScienceContractAddress") + .argument(&address) + .original_result() + } + + pub fn set_kitty_auction_contract_address_endpoint< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("setKittyAuctionContractAddress") + .argument(&address) + .original_result() + } + + pub fn claim( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("claim") + .original_result() + } + + pub fn total_supply( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("totalSupply") + .original_result() + } + + pub fn balance_of< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("balanceOf") + .argument(&address) + .original_result() + } + + pub fn owner_of< + Arg0: ProxyArg, + >( + self, + kitty_id: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("ownerOf") + .argument(&kitty_id) + .original_result() + } + + pub fn approve< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + to: Arg0, + kitty_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("approve") + .argument(&to) + .argument(&kitty_id) + .original_result() + } + + pub fn transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + to: Arg0, + kitty_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer") + .argument(&to) + .argument(&kitty_id) + .original_result() + } + + pub fn transfer_from< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + from: Arg0, + to: Arg1, + kitty_id: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer_from") + .argument(&from) + .argument(&to) + .argument(&kitty_id) + .original_result() + } + + pub fn tokens_of_owner< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("tokensOfOwner") + .argument(&address) + .original_result() + } + + pub fn allow_auctioning< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + by: Arg0, + kitty_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("allowAuctioning") + .argument(&by) + .argument(&kitty_id) + .original_result() + } + + pub fn approve_siring_and_return_kitty< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + approved_address: Arg0, + kitty_owner: Arg1, + kitty_id: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("approveSiringAndReturnKitty") + .argument(&approved_address) + .argument(&kitty_owner) + .argument(&kitty_id) + .original_result() + } + + pub fn create_gen_zero_kitty( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("createGenZeroKitty") + .original_result() + } + + pub fn get_kitty_by_id_endpoint< + Arg0: ProxyArg, + >( + self, + kitty_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getKittyById") + .argument(&kitty_id) + .original_result() + } + + pub fn is_ready_to_breed< + Arg0: ProxyArg, + >( + self, + kitty_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isReadyToBreed") + .argument(&kitty_id) + .original_result() + } + + pub fn is_pregnant< + Arg0: ProxyArg, + >( + self, + kitty_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isPregnant") + .argument(&kitty_id) + .original_result() + } + + pub fn can_breed_with< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + matron_id: Arg0, + sire_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("canBreedWith") + .argument(&matron_id) + .argument(&sire_id) + .original_result() + } + + pub fn approve_siring< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + address: Arg0, + kitty_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("approveSiring") + .argument(&address) + .argument(&kitty_id) + .original_result() + } + + pub fn breed_with< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + matron_id: Arg0, + sire_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("breedWith") + .argument(&matron_id) + .argument(&sire_id) + .original_result() + } + + pub fn give_birth< + Arg0: ProxyArg, + >( + self, + matron_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("giveBirth") + .argument(&matron_id) + .original_result() + } + + pub fn birth_fee( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("birthFee") + .original_result() + } +} diff --git a/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs b/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs index af7c7c1736..60a30c382e 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs @@ -4,6 +4,7 @@ use multiversx_sc::imports::*; pub mod auction; use auction::*; +pub mod kitty_ownership_proxy; #[multiversx_sc::contract] pub trait KittyAuction { @@ -45,11 +46,12 @@ pub trait KittyAuction { "Kitty Ownership contract address not set!" ); - self.kitty_ownership_proxy(kitty_ownership_contract_address) + self.tx() + .to(&kitty_ownership_contract_address) + .typed(kitty_ownership_proxy::KittyOwnershipProxy) .create_gen_zero_kitty() - .async_call() - .with_callback(self.callbacks().create_gen_zero_kitty_callback()) - .call_and_exit() + .callback(self.callbacks().create_gen_zero_kitty_callback()) + .async_call_and_exit(); } // views @@ -183,8 +185,10 @@ pub trait KittyAuction { // refund losing bid if !auction.current_winner.is_zero() { - self.send() - .direct_egld(&auction.current_winner, &auction.current_bid); + self.tx() + .to(&auction.current_winner) + .egld(&auction.current_bid) + .transfer(); } // update auction bid and winner @@ -238,10 +242,11 @@ pub trait KittyAuction { let kitty_ownership_contract_address = self.get_kitty_ownership_contract_address_or_default(); if !kitty_ownership_contract_address.is_zero() { - self.kitty_ownership_proxy(kitty_ownership_contract_address) - .allow_auctioning(caller.clone(), kitty_id) - .async_call() - .with_callback(self.callbacks().allow_auctioning_callback( + self.tx() + .to(&kitty_ownership_contract_address) + .typed(kitty_ownership_proxy::KittyOwnershipProxy) + .allow_auctioning(&caller, kitty_id) + .callback(self.callbacks().allow_auctioning_callback( auction_type, kitty_id, starting_price, @@ -249,7 +254,7 @@ pub trait KittyAuction { deadline, caller, )) - .call_and_exit(); + .async_call_and_exit(); } } @@ -274,11 +279,12 @@ pub trait KittyAuction { let kitty_ownership_contract_address = self.get_kitty_ownership_contract_address_or_default(); if !kitty_ownership_contract_address.is_zero() { - self.kitty_ownership_proxy(kitty_ownership_contract_address) + self.tx() + .to(&kitty_ownership_contract_address) + .typed(kitty_ownership_proxy::KittyOwnershipProxy) .transfer(address, kitty_id) - .async_call() - .with_callback(self.callbacks().transfer_callback(kitty_id)) - .call_and_exit() + .callback(self.callbacks().transfer_callback(kitty_id)) + .async_call_and_exit(); } } @@ -291,12 +297,13 @@ pub trait KittyAuction { let kitty_ownership_contract_address = self.get_kitty_ownership_contract_address_or_default(); if !kitty_ownership_contract_address.is_zero() { - self.kitty_ownership_proxy(kitty_ownership_contract_address) + self.tx() + .to(&kitty_ownership_contract_address) + .typed(kitty_ownership_proxy::KittyOwnershipProxy) .approve_siring_and_return_kitty(approved_address, kitty_owner, kitty_id) // not a mistake, same callback for transfer and approveSiringAndReturnKitty - .async_call() - .with_callback(self.callbacks().transfer_callback(kitty_id)) - .call_and_exit() + .callback(self.callbacks().transfer_callback(kitty_id)) + .async_call_and_exit(); } } @@ -356,8 +363,10 @@ pub trait KittyAuction { if auction.kitty_owner != self.blockchain().get_sc_address() && !auction.current_winner.is_zero() { - self.send() - .direct_egld(&auction.kitty_owner, &auction.current_bid); + self.tx() + .to(&auction.kitty_owner) + .egld(&auction.current_bid) + .transfer(); } }, ManagedAsyncCallResult::Err(_) => { @@ -403,11 +412,6 @@ pub trait KittyAuction { } } - // proxy - - #[proxy] - fn kitty_ownership_proxy(&self, to: ManagedAddress) -> kitty_ownership::Proxy; - // storage // general diff --git a/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.lock b/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.lock index 844e92ad69..568debe608 100755 --- a/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.lock +++ b/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -84,26 +84,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -113,7 +115,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -124,7 +126,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -140,27 +142,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -184,15 +186,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -204,3 +206,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.toml b/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.toml index 3a7e4400aa..d177d0dd77 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.kitty-auction] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/crypto-kitties/kitty-auction/wasm/src/lib.rs b/contracts/examples/crypto-kitties/kitty-auction/wasm/src/lib.rs index 7101d00f12..6d115b6c92 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/wasm/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 11 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/crypto-kitties/kitty-genetic-alg/Cargo.toml b/contracts/examples/crypto-kitties/kitty-genetic-alg/Cargo.toml index 8c94bfe0de..ffdbd89068 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/Cargo.toml @@ -18,9 +18,9 @@ version = "0.0.0" path = "../common/random" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/Cargo.toml b/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/Cargo.toml index 8e09c03447..9b058ec764 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.kitty-genetic-alg] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/src/main.rs b/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/src/main.rs index f76b8cd276..fe50a0adc3 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/src/main.rs +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/crypto-kitties/kitty-genetic-alg/sc-config.toml b/contracts/examples/crypto-kitties/kitty-genetic-alg/sc-config.toml new file mode 100644 index 0000000000..f18c45d308 --- /dev/null +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/sc-config.toml @@ -0,0 +1,8 @@ +[[proxy]] +path = "../kitty-ownership/src/kitty_genetic_alg_proxy.rs" +[[proxy.path-rename]] +from = "kitty::kitty" +to = "kitty" +[[proxy.path-rename]] +from = "kitty_genes" +to = "kitty" diff --git a/contracts/examples/crypto-kitties/kitty-genetic-alg/src/lib.rs b/contracts/examples/crypto-kitties/kitty-genetic-alg/src/lib.rs index aab6154cec..adc555585a 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/src/lib.rs @@ -1,6 +1,6 @@ #![no_std] -use kitty::{kitty_genes::*, Kitty}; +use kitty::{Kitty, KittyGenes}; use random::Random; #[multiversx_sc::contract] diff --git a/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.lock b/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.lock index 3b48261415..f1106a069c 100755 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.lock +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -65,26 +65,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -94,7 +96,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -105,7 +107,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -121,27 +123,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -165,15 +167,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -185,3 +187,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.toml b/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.toml index a7105ac21c..0579218716 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.kitty-genetic-alg] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/src/lib.rs b/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/src/lib.rs index 3bee7743a1..822a3104af 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 3 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/crypto-kitties/kitty-ownership/Cargo.toml b/contracts/examples/crypto-kitties/kitty-ownership/Cargo.toml index cbd78aed52..99c37e0334 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-ownership/Cargo.toml @@ -21,9 +21,9 @@ version = "0.0.0" path = "../kitty-genetic-alg" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/examples/crypto-kitties/kitty-ownership/meta/Cargo.toml b/contracts/examples/crypto-kitties/kitty-ownership/meta/Cargo.toml index fe5c579c57..25b9c6249f 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/meta/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-ownership/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.kitty-ownership] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/crypto-kitties/kitty-ownership/meta/src/main.rs b/contracts/examples/crypto-kitties/kitty-ownership/meta/src/main.rs index c359ae2aa3..5eb09861d7 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/meta/src/main.rs +++ b/contracts/examples/crypto-kitties/kitty-ownership/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/crypto-kitties/kitty-ownership/sc-config.toml b/contracts/examples/crypto-kitties/kitty-ownership/sc-config.toml new file mode 100644 index 0000000000..8af6863e4b --- /dev/null +++ b/contracts/examples/crypto-kitties/kitty-ownership/sc-config.toml @@ -0,0 +1,11 @@ +[[proxy]] +path = "../kitty-auction/src/kitty_ownership_proxy.rs" +[[proxy.path-rename]] +from = "kitty::kitty" +to = "kitty" + +[[proxy]] +path = "../../crypto-zombies/src/kitty_ownership_proxy.rs" +[[proxy.path-rename]] +from = "kitty::kitty" +to = "crate::kitty_obj" diff --git a/contracts/examples/crypto-kitties/kitty-ownership/src/kitty_genetic_alg_proxy.rs b/contracts/examples/crypto-kitties/kitty-ownership/src/kitty_genetic_alg_proxy.rs new file mode 100644 index 0000000000..2388d92f1b --- /dev/null +++ b/contracts/examples/crypto-kitties/kitty-ownership/src/kitty_genetic_alg_proxy.rs @@ -0,0 +1,80 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct KittyGeneticAlgProxy; + +impl TxProxyTrait for KittyGeneticAlgProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = KittyGeneticAlgProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + KittyGeneticAlgProxyMethods { wrapped_tx: tx } + } +} + +pub struct KittyGeneticAlgProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl KittyGeneticAlgProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl KittyGeneticAlgProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn generate_kitty_genes< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + matron: Arg0, + sire: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("generateKittyGenes") + .argument(&matron) + .argument(&sire) + .original_result() + } +} diff --git a/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs b/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs index 2514592465..dbde8aed52 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-ownership/src/lib.rs @@ -1,11 +1,12 @@ #![no_std] #![allow(clippy::suspicious_operation_groupings)] +pub mod kitty_genetic_alg_proxy; +use kitty::{Kitty, KittyGenes}; use multiversx_sc::imports::*; use core::cmp::max; -use kitty::{kitty_genes::*, Kitty}; use random::*; #[multiversx_sc::contract] @@ -52,7 +53,7 @@ pub trait KittyOwnership { .blockchain() .get_sc_balance(&EgldOrEsdtTokenIdentifier::egld(), 0); - self.send().direct_egld(&caller, &egld_balance); + self.tx().to(&caller).egld(&egld_balance).transfer(); } // views/endpoints - ERC721 required @@ -335,14 +336,16 @@ pub trait KittyOwnership { let gene_science_contract_address = self.get_gene_science_contract_address_or_default(); if !gene_science_contract_address.is_zero() { - self.kitty_genetic_alg_proxy(gene_science_contract_address) + let caller = self.blockchain().get_caller(); + self.tx() + .to(&gene_science_contract_address) + .typed(kitty_genetic_alg_proxy::KittyGeneticAlgProxy) .generate_kitty_genes(matron, sire) - .async_call() - .with_callback( + .callback( self.callbacks() - .generate_kitty_genes_callback(matron_id, self.blockchain().get_caller()), + .generate_kitty_genes_callback(matron_id, caller), ) - .call_and_exit() + .async_call_and_exit(); } else { sc_panic!("Gene science contract address not set!") } @@ -569,7 +572,7 @@ pub trait KittyOwnership { // send birth fee to caller let fee = self.birth_fee().get(); - self.send().direct_egld(&original_caller, &fee); + self.tx().to(&original_caller).egld(&fee).transfer(); }, ManagedAsyncCallResult::Err(_) => { // this can only fail if the kitty_genes contract address is invalid @@ -578,11 +581,6 @@ pub trait KittyOwnership { } } - // proxy - - #[proxy] - fn kitty_genetic_alg_proxy(&self, to: ManagedAddress) -> kitty_genetic_alg::Proxy; - // storage - General #[storage_mapper("geneScienceContractAddress")] diff --git a/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.lock b/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.lock index 2305919360..2109c57392 100755 --- a/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.lock +++ b/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -75,26 +75,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -104,7 +106,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -115,7 +117,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -131,27 +133,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -175,15 +177,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -195,3 +197,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.toml b/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.toml index d81e2aec49..c84fc452ff 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.kitty-ownership] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/crypto-kitties/kitty-ownership/wasm/src/lib.rs b/contracts/examples/crypto-kitties/kitty-ownership/wasm/src/lib.rs index 9154e40f13..9a5ffdaba8 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/wasm/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-ownership/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 23 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/crypto-zombies/Cargo.toml b/contracts/examples/crypto-zombies/Cargo.toml index 3f30e8030e..9914391892 100644 --- a/contracts/examples/crypto-zombies/Cargo.toml +++ b/contracts/examples/crypto-zombies/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/crypto-zombies/meta/Cargo.toml b/contracts/examples/crypto-zombies/meta/Cargo.toml index 396fb6584e..4217bec978 100644 --- a/contracts/examples/crypto-zombies/meta/Cargo.toml +++ b/contracts/examples/crypto-zombies/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.crypto-zombies] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/crypto-zombies/meta/src/main.rs b/contracts/examples/crypto-zombies/meta/src/main.rs index 0956e125b8..641824afd5 100644 --- a/contracts/examples/crypto-zombies/meta/src/main.rs +++ b/contracts/examples/crypto-zombies/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/crypto-zombies/sc-config.toml b/contracts/examples/crypto-zombies/sc-config.toml new file mode 100644 index 0000000000..d1f317be2c --- /dev/null +++ b/contracts/examples/crypto-zombies/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "src/proxy_crypto_zombies.rs" diff --git a/contracts/examples/crypto-zombies/src/crypto_kitties_proxy.rs b/contracts/examples/crypto-zombies/src/kitty_obj.rs similarity index 64% rename from contracts/examples/crypto-zombies/src/crypto_kitties_proxy.rs rename to contracts/examples/crypto-zombies/src/kitty_obj.rs index ea4d366994..5ba10f51e5 100644 --- a/contracts/examples/crypto-zombies/src/crypto_kitties_proxy.rs +++ b/contracts/examples/crypto-zombies/src/kitty_obj.rs @@ -1,6 +1,6 @@ use multiversx_sc::derive_imports::*; - -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct Kitty { pub genes: KittyGenes, pub birth_time: u64, // timestamp @@ -12,35 +12,31 @@ pub struct Kitty { pub generation: u16, // max(sire_gen, matron_gen) + 1. Generation also influences cooldown. } -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct KittyGenes { pub fur_color: Color, pub eye_color: Color, pub meow_power: u8, // the higher the value, the louder the cat } -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct Color { pub r: u8, pub g: u8, pub b: u8, } -#[multiversx_sc::proxy] -pub trait CryptoKitties { - #[endpoint] - fn get_kitty_by_id_endpoint(&self, kitty_id: u32) -> Kitty; -} - impl KittyGenes { pub fn get_as_u64(&self) -> u64 { - (self.fur_color.as_u64() << 12 | self.eye_color.as_u64()) << 4 + (self.fur_color.as_u64() << 24 | self.eye_color.as_u64()) << 8 | self.meow_power.to_be() as u64 } } impl Color { pub fn as_u64(&self) -> u64 { - ((self.r.to_be() as u64) << 4 | self.r.to_be() as u64) << 4 | self.r.to_be() as u64 + ((self.r.to_be() as u64) << 8 | self.r.to_be() as u64) << 8 | self.r.to_be() as u64 } } diff --git a/contracts/examples/crypto-zombies/src/kitty_ownership_proxy.rs b/contracts/examples/crypto-zombies/src/kitty_ownership_proxy.rs new file mode 100644 index 0000000000..3673b97ea5 --- /dev/null +++ b/contracts/examples/crypto-zombies/src/kitty_ownership_proxy.rs @@ -0,0 +1,360 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct KittyOwnershipProxy; + +impl TxProxyTrait for KittyOwnershipProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = KittyOwnershipProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + KittyOwnershipProxyMethods { wrapped_tx: tx } + } +} + +pub struct KittyOwnershipProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl KittyOwnershipProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + Arg2: ProxyArg>>, + >( + self, + birth_fee: Arg0, + opt_gene_science_contract_address: Arg1, + opt_kitty_auction_contract_address: Arg2, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&birth_fee) + .argument(&opt_gene_science_contract_address) + .argument(&opt_kitty_auction_contract_address) + .original_result() + } +} + +#[rustfmt::skip] +impl KittyOwnershipProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn set_gene_science_contract_address_endpoint< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("setGeneScienceContractAddress") + .argument(&address) + .original_result() + } + + pub fn set_kitty_auction_contract_address_endpoint< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("setKittyAuctionContractAddress") + .argument(&address) + .original_result() + } + + pub fn claim( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("claim") + .original_result() + } + + pub fn total_supply( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("totalSupply") + .original_result() + } + + pub fn balance_of< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("balanceOf") + .argument(&address) + .original_result() + } + + pub fn owner_of< + Arg0: ProxyArg, + >( + self, + kitty_id: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("ownerOf") + .argument(&kitty_id) + .original_result() + } + + pub fn approve< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + to: Arg0, + kitty_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("approve") + .argument(&to) + .argument(&kitty_id) + .original_result() + } + + pub fn transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + to: Arg0, + kitty_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer") + .argument(&to) + .argument(&kitty_id) + .original_result() + } + + pub fn transfer_from< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + from: Arg0, + to: Arg1, + kitty_id: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer_from") + .argument(&from) + .argument(&to) + .argument(&kitty_id) + .original_result() + } + + pub fn tokens_of_owner< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("tokensOfOwner") + .argument(&address) + .original_result() + } + + pub fn allow_auctioning< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + by: Arg0, + kitty_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("allowAuctioning") + .argument(&by) + .argument(&kitty_id) + .original_result() + } + + pub fn approve_siring_and_return_kitty< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + approved_address: Arg0, + kitty_owner: Arg1, + kitty_id: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("approveSiringAndReturnKitty") + .argument(&approved_address) + .argument(&kitty_owner) + .argument(&kitty_id) + .original_result() + } + + pub fn create_gen_zero_kitty( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("createGenZeroKitty") + .original_result() + } + + pub fn get_kitty_by_id_endpoint< + Arg0: ProxyArg, + >( + self, + kitty_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getKittyById") + .argument(&kitty_id) + .original_result() + } + + pub fn is_ready_to_breed< + Arg0: ProxyArg, + >( + self, + kitty_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isReadyToBreed") + .argument(&kitty_id) + .original_result() + } + + pub fn is_pregnant< + Arg0: ProxyArg, + >( + self, + kitty_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isPregnant") + .argument(&kitty_id) + .original_result() + } + + pub fn can_breed_with< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + matron_id: Arg0, + sire_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("canBreedWith") + .argument(&matron_id) + .argument(&sire_id) + .original_result() + } + + pub fn approve_siring< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + address: Arg0, + kitty_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("approveSiring") + .argument(&address) + .argument(&kitty_id) + .original_result() + } + + pub fn breed_with< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + matron_id: Arg0, + sire_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("breedWith") + .argument(&matron_id) + .argument(&sire_id) + .original_result() + } + + pub fn give_birth< + Arg0: ProxyArg, + >( + self, + matron_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("giveBirth") + .argument(&matron_id) + .original_result() + } + + pub fn birth_fee( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("birthFee") + .original_result() + } +} diff --git a/contracts/examples/crypto-zombies/src/lib.rs b/contracts/examples/crypto-zombies/src/lib.rs index f2f47688ad..a79de4fcb0 100644 --- a/contracts/examples/crypto-zombies/src/lib.rs +++ b/contracts/examples/crypto-zombies/src/lib.rs @@ -2,7 +2,9 @@ use multiversx_sc::imports::*; -mod crypto_kitties_proxy; +pub mod kitty_obj; +pub mod kitty_ownership_proxy; +pub mod proxy_crypto_zombies; mod storage; mod zombie; mod zombie_attack; diff --git a/contracts/examples/crypto-zombies/src/proxy_crypto_zombies.rs b/contracts/examples/crypto-zombies/src/proxy_crypto_zombies.rs new file mode 100644 index 0000000000..2a35082180 --- /dev/null +++ b/contracts/examples/crypto-zombies/src/proxy_crypto_zombies.rs @@ -0,0 +1,305 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct CryptoZombiesProxy; + +impl TxProxyTrait for CryptoZombiesProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = CryptoZombiesProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + CryptoZombiesProxyMethods { wrapped_tx: tx } + } +} + +pub struct CryptoZombiesProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl CryptoZombiesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl CryptoZombiesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade( + self, + ) -> TxTypedUpgrade { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .original_result() + } +} + +#[rustfmt::skip] +impl CryptoZombiesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn set_crypto_kitties_sc_address< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("set_crypto_kitties_sc_address") + .argument(&address) + .original_result() + } + + pub fn generate_random_dna( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("generate_random_dna") + .original_result() + } + + pub fn create_random_zombie< + Arg0: ProxyArg>, + >( + self, + name: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("create_random_zombie") + .argument(&name) + .original_result() + } + + pub fn is_ready< + Arg0: ProxyArg, + >( + self, + zombie_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("is_ready") + .argument(&zombie_id) + .original_result() + } + + pub fn feed_on_kitty< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + zombie_id: Arg0, + kitty_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("feed_on_kitty") + .argument(&zombie_id) + .argument(&kitty_id) + .original_result() + } + + pub fn dna_digits( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("dna_digits") + .original_result() + } + + pub fn zombie_last_index( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("zombie_last_index") + .original_result() + } + + pub fn zombies< + Arg0: ProxyArg, + >( + self, + id: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("zombies") + .argument(&id) + .original_result() + } + + pub fn zombie_owner< + Arg0: ProxyArg, + >( + self, + id: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("zombie_owner") + .argument(&id) + .original_result() + } + + pub fn crypto_kitties_sc_address( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("crypto_kitties_sc_address") + .original_result() + } + + pub fn cooldown_time( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("cooldown_time") + .original_result() + } + + pub fn owned_zombies< + Arg0: ProxyArg>, + >( + self, + owner: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("owned_zombies") + .argument(&owner) + .original_result() + } + + pub fn level_up< + Arg0: ProxyArg, + >( + self, + zombie_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("level_up") + .argument(&zombie_id) + .original_result() + } + + pub fn withdraw( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("withdraw") + .original_result() + } + + pub fn change_name< + Arg0: ProxyArg, + Arg1: ProxyArg>, + >( + self, + zombie_id: Arg0, + name: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("change_name") + .argument(&zombie_id) + .argument(&name) + .original_result() + } + + pub fn change_dna< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + zombie_id: Arg0, + dna: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("change_dna") + .argument(&zombie_id) + .argument(&dna) + .original_result() + } + + pub fn attack< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + zombie_id: Arg0, + target_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("attack") + .argument(&zombie_id) + .argument(&target_id) + .original_result() + } +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct Zombie +where + Api: ManagedTypeApi, +{ + pub name: ManagedBuffer, + pub dna: u64, + pub level: u16, + pub ready_time: u64, + pub win_count: usize, + pub loss_count: usize, +} diff --git a/contracts/examples/crypto-zombies/src/storage.rs b/contracts/examples/crypto-zombies/src/storage.rs index 608456b688..6670547064 100644 --- a/contracts/examples/crypto-zombies/src/storage.rs +++ b/contracts/examples/crypto-zombies/src/storage.rs @@ -5,39 +5,39 @@ use crate::zombie::Zombie; #[multiversx_sc::module] pub trait Storage { #[view] - #[storage_mapper("dna_digits")] + #[storage_mapper("dnaDigits")] fn dna_digits(&self) -> SingleValueMapper; #[view] - #[storage_mapper("zombies_count")] - fn zombies_count(&self) -> SingleValueMapper; + #[storage_mapper("zombieLastIndex")] + fn zombie_last_index(&self) -> SingleValueMapper; #[view] #[storage_mapper("zombies")] fn zombies(&self, id: &usize) -> SingleValueMapper>; #[view] - #[storage_mapper("zombie_owner")] + #[storage_mapper("zombieOwner")] fn zombie_owner(&self, id: &usize) -> SingleValueMapper; #[view] - #[storage_mapper("crypto_kitties_sc_address")] + #[storage_mapper("cryptoKittiesScAddress")] fn crypto_kitties_sc_address(&self) -> SingleValueMapper; #[view] - #[storage_mapper("cooldown_time")] + #[storage_mapper("cooldownTime")] fn cooldown_time(&self) -> SingleValueMapper; #[view] - #[storage_mapper("owned_zombies")] + #[storage_mapper("ownedZombies")] fn owned_zombies(&self, owner: &ManagedAddress) -> UnorderedSetMapper; - #[storage_mapper("attack_victory_probability")] + #[storage_mapper("attackVictoryProbability")] fn attack_victory_probability(&self) -> SingleValueMapper; - #[storage_mapper("level_up_fee")] + #[storage_mapper("levelUpFee")] fn level_up_fee(&self) -> SingleValueMapper; - #[storage_mapper("collected_fees")] + #[storage_mapper("collectedFees")] fn collected_fees(&self) -> SingleValueMapper; } diff --git a/contracts/examples/crypto-zombies/src/zombie.rs b/contracts/examples/crypto-zombies/src/zombie.rs index 414c343f28..bfe3fd22ad 100644 --- a/contracts/examples/crypto-zombies/src/zombie.rs +++ b/contracts/examples/crypto-zombies/src/zombie.rs @@ -1,6 +1,7 @@ use multiversx_sc::{derive_imports::*, imports::*}; -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct Zombie { pub name: ManagedBuffer, pub dna: u64, diff --git a/contracts/examples/crypto-zombies/src/zombie_factory.rs b/contracts/examples/crypto-zombies/src/zombie_factory.rs index 3ee8339b9c..996c339e82 100644 --- a/contracts/examples/crypto-zombies/src/zombie_factory.rs +++ b/contracts/examples/crypto-zombies/src/zombie_factory.rs @@ -5,7 +5,7 @@ use crate::{storage, zombie::Zombie}; #[multiversx_sc::module] pub trait ZombieFactory: storage::Storage { fn create_zombie(&self, owner: ManagedAddress, name: ManagedBuffer, dna: u64) { - self.zombies_count().update(|id| { + self.zombie_last_index().update(|id| { self.new_zombie_event(*id, &name, dna); self.zombies(id).set(Zombie { name, @@ -40,7 +40,7 @@ pub trait ZombieFactory: storage::Storage { self.create_zombie(caller, name, rand_dna); } - #[event("new_zombie_event")] + #[event("newZombieEvent")] fn new_zombie_event( &self, #[indexed] zombie_id: usize, diff --git a/contracts/examples/crypto-zombies/src/zombie_feeding.rs b/contracts/examples/crypto-zombies/src/zombie_feeding.rs index e27b3e69ad..8061e5f7f6 100644 --- a/contracts/examples/crypto-zombies/src/zombie_feeding.rs +++ b/contracts/examples/crypto-zombies/src/zombie_feeding.rs @@ -1,9 +1,6 @@ use multiversx_sc::imports::*; -use crate::{ - crypto_kitties_proxy::{self, Kitty}, - storage, zombie_factory, zombie_helper, -}; +use crate::{kitty_obj::Kitty, kitty_ownership_proxy, storage, zombie_factory, zombie_helper}; #[multiversx_sc::module] pub trait ZombieFeeding: @@ -56,12 +53,11 @@ pub trait ZombieFeeding: #[endpoint] fn feed_on_kitty(&self, zombie_id: usize, kitty_id: u32) { let crypto_kitties_sc_address = self.crypto_kitties_sc_address().get(); - self.kitty_proxy(crypto_kitties_sc_address) + self.tx() + .to(&crypto_kitties_sc_address) + .typed(kitty_ownership_proxy::KittyOwnershipProxy) .get_kitty_by_id_endpoint(kitty_id) - .async_call() - .with_callback(self.callbacks().get_kitty_callback(zombie_id)) - .call_and_exit(); + .callback(self.callbacks().get_kitty_callback(zombie_id)) + .async_call_and_exit(); } - #[proxy] - fn kitty_proxy(&self, to: ManagedAddress) -> crypto_kitties_proxy::Proxy; } diff --git a/contracts/examples/crypto-zombies/src/zombie_helper.rs b/contracts/examples/crypto-zombies/src/zombie_helper.rs index 000ffda770..c38edc9ea0 100644 --- a/contracts/examples/crypto-zombies/src/zombie_helper.rs +++ b/contracts/examples/crypto-zombies/src/zombie_helper.rs @@ -31,7 +31,10 @@ pub trait ZombieHelper: storage::Storage { fn withdraw(&self) { let caller_address = self.blockchain().get_caller(); let collected_fees = self.collected_fees().get(); - self.send().direct_egld(&caller_address, &collected_fees); + self.tx() + .to(&caller_address) + .egld(&collected_fees) + .transfer(); self.collected_fees().clear(); } diff --git a/contracts/examples/crypto-zombies/wasm/Cargo.lock b/contracts/examples/crypto-zombies/wasm/Cargo.lock index 9425f7d3fe..f6e58e8520 100755 --- a/contracts/examples/crypto-zombies/wasm/Cargo.lock +++ b/contracts/examples/crypto-zombies/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "crypto-zombies" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/crypto-zombies/wasm/Cargo.toml b/contracts/examples/crypto-zombies/wasm/Cargo.toml index 3234a023e6..5afd6abf09 100644 --- a/contracts/examples/crypto-zombies/wasm/Cargo.toml +++ b/contracts/examples/crypto-zombies/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.crypto-zombies] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/crypto-zombies/wasm/src/lib.rs b/contracts/examples/crypto-zombies/wasm/src/lib.rs index 44f5f426c8..932b3865a6 100644 --- a/contracts/examples/crypto-zombies/wasm/src/lib.rs +++ b/contracts/examples/crypto-zombies/wasm/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 18 +// Upgrade: 1 +// Endpoints: 17 // Async Callback: 1 // Total number of exported functions: 20 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -27,7 +26,7 @@ multiversx_sc_wasm_adapter::endpoints! { is_ready => is_ready feed_on_kitty => feed_on_kitty dna_digits => dna_digits - zombies_count => zombies_count + zombie_last_index => zombie_last_index zombies => zombies zombie_owner => zombie_owner crypto_kitties_sc_address => crypto_kitties_sc_address diff --git a/contracts/examples/digital-cash/Cargo.toml b/contracts/examples/digital-cash/Cargo.toml index c9a21caba1..aa8c6a03c6 100644 --- a/contracts/examples/digital-cash/Cargo.toml +++ b/contracts/examples/digital-cash/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/digital_cash.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/digital-cash/meta/Cargo.toml b/contracts/examples/digital-cash/meta/Cargo.toml index 42e08a4777..fb6598dae8 100644 --- a/contracts/examples/digital-cash/meta/Cargo.toml +++ b/contracts/examples/digital-cash/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.digital-cash] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/digital-cash/meta/src/main.rs b/contracts/examples/digital-cash/meta/src/main.rs index 9f6b55a146..80034d4166 100644 --- a/contracts/examples/digital-cash/meta/src/main.rs +++ b/contracts/examples/digital-cash/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/digital-cash/sc-config.toml b/contracts/examples/digital-cash/sc-config.toml new file mode 100644 index 0000000000..39234c29d8 --- /dev/null +++ b/contracts/examples/digital-cash/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "src/digital_cash_proxy.rs" diff --git a/contracts/examples/digital-cash/src/deposit_info.rs b/contracts/examples/digital-cash/src/deposit_info.rs index 9fb14661ea..daef136feb 100644 --- a/contracts/examples/digital-cash/src/deposit_info.rs +++ b/contracts/examples/digital-cash/src/deposit_info.rs @@ -1,6 +1,7 @@ use multiversx_sc::{derive_imports::*, imports::*}; -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct DepositInfo { pub depositor_address: ManagedAddress, pub esdt_funds: ManagedVec>, @@ -24,7 +25,8 @@ where } } -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct Fee { pub num_token_to_transfer: usize, pub value: EgldOrEsdtTokenPayment, diff --git a/contracts/examples/digital-cash/src/digital_cash.rs b/contracts/examples/digital-cash/src/digital_cash.rs index b46c2b7331..c1d96c9132 100644 --- a/contracts/examples/digital-cash/src/digital_cash.rs +++ b/contracts/examples/digital-cash/src/digital_cash.rs @@ -5,6 +5,7 @@ use multiversx_sc::imports::*; mod constants; mod deposit_info; +pub mod digital_cash_proxy; mod helpers; mod pay_fee_and_fund; mod signature_operations; @@ -54,15 +55,17 @@ pub trait DigitalCash: continue; } if token == EgldOrEsdtTokenIdentifier::egld() { - self.send().direct_egld(&caller_address, &fee); + self.tx().to(&caller_address).egld(&fee).transfer(); } else { let collected_fee = EsdtTokenPayment::new(token.unwrap_esdt(), 0, fee); collected_esdt_fees.push(collected_fee); } } if !collected_esdt_fees.is_empty() { - self.send() - .direct_multi(&caller_address, &collected_esdt_fees); + self.tx() + .to(&caller_address) + .payment(&collected_esdt_fees) + .transfer(); } } diff --git a/contracts/examples/digital-cash/src/digital_cash_proxy.rs b/contracts/examples/digital-cash/src/digital_cash_proxy.rs new file mode 100644 index 0000000000..e2893794b9 --- /dev/null +++ b/contracts/examples/digital-cash/src/digital_cash_proxy.rs @@ -0,0 +1,269 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct DigitalCashProxy; + +impl TxProxyTrait for DigitalCashProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = DigitalCashProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + DigitalCashProxyMethods { wrapped_tx: tx } + } +} + +pub struct DigitalCashProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl DigitalCashProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + fee: Arg0, + token: Arg1, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&fee) + .argument(&token) + .original_result() + } +} + +#[rustfmt::skip] +impl DigitalCashProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn whitelist_fee_token< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + fee: Arg0, + token: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("whitelistFeeToken") + .argument(&fee) + .argument(&token) + .original_result() + } + + pub fn blacklist_fee_token< + Arg0: ProxyArg>, + >( + self, + token: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("blacklistFeeToken") + .argument(&token) + .original_result() + } + + pub fn claim_fees( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("claimFees") + .original_result() + } + + pub fn get_amount< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + address: Arg0, + token: Arg1, + nonce: Arg2, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getAmount") + .argument(&address) + .argument(&token) + .argument(&nonce) + .original_result() + } + + pub fn pay_fee_and_fund_esdt< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + address: Arg0, + valability: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("payFeeAndFundESDT") + .argument(&address) + .argument(&valability) + .original_result() + } + + pub fn pay_fee_and_fund_egld< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + address: Arg0, + valability: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("payFeeAndFundEGLD") + .argument(&address) + .argument(&valability) + .original_result() + } + + pub fn fund< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + address: Arg0, + valability: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("fund") + .argument(&address) + .argument(&valability) + .original_result() + } + + pub fn deposit_fees< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("depositFees") + .argument(&address) + .original_result() + } + + pub fn withdraw< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("withdraw") + .argument(&address) + .original_result() + } + + pub fn claim< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + address: Arg0, + signature: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("claim") + .argument(&address) + .argument(&signature) + .original_result() + } + + pub fn forward< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + address: Arg0, + forward_address: Arg1, + signature: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward") + .argument(&address) + .argument(&forward_address) + .argument(&signature) + .original_result() + } + + pub fn deposit< + Arg0: ProxyArg>, + >( + self, + donor: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("deposit") + .argument(&donor) + .original_result() + } +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct DepositInfo +where + Api: ManagedTypeApi, +{ + pub depositor_address: ManagedAddress, + pub esdt_funds: ManagedVec>, + pub egld_funds: BigUint, + pub valability: u64, + pub expiration_round: u64, + pub fees: Fee, +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct Fee +where + Api: ManagedTypeApi, +{ + pub num_token_to_transfer: usize, + pub value: EgldOrEsdtTokenPayment, +} diff --git a/contracts/examples/digital-cash/src/helpers.rs b/contracts/examples/digital-cash/src/helpers.rs index d300e35d08..aa5c4efadc 100644 --- a/contracts/examples/digital-cash/src/helpers.rs +++ b/contracts/examples/digital-cash/src/helpers.rs @@ -9,11 +9,13 @@ use crate::{ pub trait HelpersModule: storage::StorageModule { fn send_fee_to_address(&self, fee: &EgldOrEsdtTokenPayment, address: &ManagedAddress) { if fee.token_identifier == EgldOrEsdtTokenIdentifier::egld() { - self.send().direct_egld(address, &fee.amount); + self.tx().to(address).egld(&fee.amount).transfer(); } else { let esdt_fee = fee.clone().unwrap_esdt(); - self.send() - .direct_esdt(address, &esdt_fee.token_identifier, 0, &esdt_fee.amount); + self.tx() + .to(address) + .single_esdt(&esdt_fee.token_identifier, 0, &esdt_fee.amount) + .transfer(); } } diff --git a/contracts/examples/digital-cash/src/signature_operations.rs b/contracts/examples/digital-cash/src/signature_operations.rs index 3da7143f88..9c68951f05 100644 --- a/contracts/examples/digital-cash/src/signature_operations.rs +++ b/contracts/examples/digital-cash/src/signature_operations.rs @@ -33,13 +33,17 @@ pub trait SignatureOperationsModule: storage::StorageModule + helpers::HelpersMo } if egld_funds > 0 { - self.send() - .direct_egld(&deposit.depositor_address, &egld_funds); + self.tx() + .to(&deposit.depositor_address) + .egld(&egld_funds) + .transfer(); } if !esdt_funds.is_empty() { - self.send() - .direct_multi(&deposit.depositor_address, &esdt_funds); + self.tx() + .to(&deposit.depositor_address) + .payment(esdt_funds) + .transfer(); } } @@ -71,12 +75,16 @@ pub trait SignatureOperationsModule: storage::StorageModule + helpers::HelpersMo .update(|collected_fees| *collected_fees += fee_cost); if deposit.egld_funds > 0 { - self.send() - .direct_egld(&caller_address, &deposit.egld_funds); + self.tx() + .to(&caller_address) + .egld(&deposit.egld_funds) + .transfer(); } if !deposit.esdt_funds.is_empty() { - self.send() - .direct_multi(&caller_address, &deposit.esdt_funds); + self.tx() + .to(&caller_address) + .payment(&deposit.esdt_funds) + .transfer(); } if deposited_fee.amount > 0 { self.send_fee_to_address(&deposited_fee, &deposit.depositor_address); diff --git a/contracts/examples/digital-cash/tests/digital_cash_scenario_rs_test.rs b/contracts/examples/digital-cash/tests/digital_cash_scenario_rs_test.rs index 8dcff32a11..b210c4952a 100644 --- a/contracts/examples/digital-cash/tests/digital_cash_scenario_rs_test.rs +++ b/contracts/examples/digital-cash/tests/digital_cash_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/digital-cash"); blockchain.register_contract( "mxsc:output/digital-cash.mxsc.json", diff --git a/contracts/examples/digital-cash/wasm/Cargo.lock b/contracts/examples/digital-cash/wasm/Cargo.lock index d01e7ca5d3..704a0b832f 100644 --- a/contracts/examples/digital-cash/wasm/Cargo.lock +++ b/contracts/examples/digital-cash/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "digital-cash" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/digital-cash/wasm/Cargo.toml b/contracts/examples/digital-cash/wasm/Cargo.toml index ec1d9efa8f..2d51de2b43 100644 --- a/contracts/examples/digital-cash/wasm/Cargo.toml +++ b/contracts/examples/digital-cash/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.digital-cash] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/digital-cash/wasm/src/lib.rs b/contracts/examples/digital-cash/wasm/src/lib.rs index 728d658a67..b010630ba6 100644 --- a/contracts/examples/digital-cash/wasm/src/lib.rs +++ b/contracts/examples/digital-cash/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 14 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/empty/Cargo.toml b/contracts/examples/empty/Cargo.toml index a8403c0d71..03eeadd1d2 100644 --- a/contracts/examples/empty/Cargo.toml +++ b/contracts/examples/empty/Cargo.toml @@ -9,11 +9,11 @@ publish = false path = "src/empty.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dev-dependencies] diff --git a/contracts/examples/empty/meta/Cargo.toml b/contracts/examples/empty/meta/Cargo.toml index 47a8dbdfd0..f2feb5a778 100644 --- a/contracts/examples/empty/meta/Cargo.toml +++ b/contracts/examples/empty/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.empty] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/empty/meta/src/main.rs b/contracts/examples/empty/meta/src/main.rs index a3d16d95b7..a55dac23e4 100644 --- a/contracts/examples/empty/meta/src/main.rs +++ b/contracts/examples/empty/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/empty/tests/empty_scenario_rs_test.rs b/contracts/examples/empty/tests/empty_scenario_rs_test.rs index d4f9a9b3ab..7f84325dbe 100644 --- a/contracts/examples/empty/tests/empty_scenario_rs_test.rs +++ b/contracts/examples/empty/tests/empty_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/empty"); blockchain.register_contract("mxsc:output/empty.mxsc.json", empty::ContractBuilder); blockchain diff --git a/contracts/examples/empty/wasm/Cargo.lock b/contracts/examples/empty/wasm/Cargo.lock index ed51dd0f2d..e25d3d7e82 100755 --- a/contracts/examples/empty/wasm/Cargo.lock +++ b/contracts/examples/empty/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "empty" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/empty/wasm/Cargo.toml b/contracts/examples/empty/wasm/Cargo.toml index 9a551ecd8a..5f50f9dbf8 100644 --- a/contracts/examples/empty/wasm/Cargo.toml +++ b/contracts/examples/empty/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.empty] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/empty/wasm/src/lib.rs b/contracts/examples/empty/wasm/src/lib.rs index 33ca3e1cfd..2d1910c9bd 100644 --- a/contracts/examples/empty/wasm/src/lib.rs +++ b/contracts/examples/empty/wasm/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 1 +// Upgrade: 1 +// Endpoints: 0 // Async Callback (empty): 1 // Total number of exported functions: 3 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/esdt-transfer-with-fee/Cargo.toml b/contracts/examples/esdt-transfer-with-fee/Cargo.toml index a930ff827c..f15ee18079 100644 --- a/contracts/examples/esdt-transfer-with-fee/Cargo.toml +++ b/contracts/examples/esdt-transfer-with-fee/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/esdt_transfer_with_fee.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/esdt-transfer-with-fee/meta/Cargo.toml b/contracts/examples/esdt-transfer-with-fee/meta/Cargo.toml index 5f0ac8e76f..30269c91cc 100644 --- a/contracts/examples/esdt-transfer-with-fee/meta/Cargo.toml +++ b/contracts/examples/esdt-transfer-with-fee/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.esdt-transfer-with-fee] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/esdt-transfer-with-fee/meta/src/main.rs b/contracts/examples/esdt-transfer-with-fee/meta/src/main.rs index da77d93289..b700a37abf 100644 --- a/contracts/examples/esdt-transfer-with-fee/meta/src/main.rs +++ b/contracts/examples/esdt-transfer-with-fee/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs b/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs index 6133e5500f..de883ef83a 100644 --- a/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs +++ b/contracts/examples/esdt-transfer-with-fee/src/esdt_transfer_with_fee.rs @@ -40,8 +40,7 @@ pub trait EsdtTransferWithFee { } self.paid_fees().clear(); - let caller = self.blockchain().get_caller(); - self.send().direct_multi(&caller, &fees); + self.tx().to(ToCaller).payment(fees).transfer(); } #[payable("*")] @@ -82,7 +81,7 @@ pub trait EsdtTransferWithFee { }, } } - self.send().direct_multi(&address, &new_payments); + self.tx().to(&address).payment(new_payments).transfer(); } fn get_payment_after_fees( diff --git a/contracts/examples/esdt-transfer-with-fee/tests/esdt_transfer_with_fee_scenario_rs_test.rs b/contracts/examples/esdt-transfer-with-fee/tests/esdt_transfer_with_fee_scenario_rs_test.rs index 2dd7248b2a..48bc41cff0 100644 --- a/contracts/examples/esdt-transfer-with-fee/tests/esdt_transfer_with_fee_scenario_rs_test.rs +++ b/contracts/examples/esdt-transfer-with-fee/tests/esdt_transfer_with_fee_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/esdt-transfer-with-fee"); blockchain.register_contract( "mxsc:output/esdt-transfer-with-fee.mxsc.json", diff --git a/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.lock b/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.lock index 4a29f51769..c6c6875688 100644 --- a/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.lock +++ b/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.toml b/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.toml index dd7d97cdb8..7c44a7328f 100644 --- a/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.toml +++ b/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.esdt-transfer-with-fee] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/esdt-transfer-with-fee/wasm/src/lib.rs b/contracts/examples/esdt-transfer-with-fee/wasm/src/lib.rs index 879ee2a1af..cd2ccdbd51 100644 --- a/contracts/examples/esdt-transfer-with-fee/wasm/src/lib.rs +++ b/contracts/examples/esdt-transfer-with-fee/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 8 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/factorial/Cargo.toml b/contracts/examples/factorial/Cargo.toml index a8e1caf074..9ebbe153e3 100644 --- a/contracts/examples/factorial/Cargo.toml +++ b/contracts/examples/factorial/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/factorial.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/factorial/meta/Cargo.toml b/contracts/examples/factorial/meta/Cargo.toml index 6cdefc436d..9112d4c849 100644 --- a/contracts/examples/factorial/meta/Cargo.toml +++ b/contracts/examples/factorial/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.factorial] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/factorial/meta/src/main.rs b/contracts/examples/factorial/meta/src/main.rs index b7e3589c2e..9e424513d7 100644 --- a/contracts/examples/factorial/meta/src/main.rs +++ b/contracts/examples/factorial/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/factorial/tests/factorial_scenario_rs_test.rs b/contracts/examples/factorial/tests/factorial_scenario_rs_test.rs index 5f55080950..679c1a2d92 100644 --- a/contracts/examples/factorial/tests/factorial_scenario_rs_test.rs +++ b/contracts/examples/factorial/tests/factorial_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/factorial"); blockchain.register_contract( "mxsc:output/factorial.mxsc.json", diff --git a/contracts/examples/factorial/wasm/Cargo.lock b/contracts/examples/factorial/wasm/Cargo.lock index 93ca6d814f..068bc65f8d 100755 --- a/contracts/examples/factorial/wasm/Cargo.lock +++ b/contracts/examples/factorial/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/factorial/wasm/Cargo.toml b/contracts/examples/factorial/wasm/Cargo.toml index 8889a9b7ae..497fe648d4 100644 --- a/contracts/examples/factorial/wasm/Cargo.toml +++ b/contracts/examples/factorial/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.factorial] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/factorial/wasm/src/lib.rs b/contracts/examples/factorial/wasm/src/lib.rs index 7819e0b34f..5bf5db395c 100644 --- a/contracts/examples/factorial/wasm/src/lib.rs +++ b/contracts/examples/factorial/wasm/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 2 +// Upgrade: 1 +// Endpoints: 1 // Async Callback (empty): 1 // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/fractional-nfts/Cargo.toml b/contracts/examples/fractional-nfts/Cargo.toml index a64f7f323d..4950e5405c 100644 --- a/contracts/examples/fractional-nfts/Cargo.toml +++ b/contracts/examples/fractional-nfts/Cargo.toml @@ -9,13 +9,13 @@ publish = false path = "src/fractional_nfts.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/fractional-nfts/meta/Cargo.toml b/contracts/examples/fractional-nfts/meta/Cargo.toml index 24ca9dc1c9..2ec515bbc0 100644 --- a/contracts/examples/fractional-nfts/meta/Cargo.toml +++ b/contracts/examples/fractional-nfts/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.fractional-nfts] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/fractional-nfts/meta/src/main.rs b/contracts/examples/fractional-nfts/meta/src/main.rs index 52ba34ff9b..02ab671c13 100644 --- a/contracts/examples/fractional-nfts/meta/src/main.rs +++ b/contracts/examples/fractional-nfts/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/fractional-nfts/src/fractional_nfts.rs b/contracts/examples/fractional-nfts/src/fractional_nfts.rs index c715edae82..16f1c87aed 100644 --- a/contracts/examples/fractional-nfts/src/fractional_nfts.rs +++ b/contracts/examples/fractional-nfts/src/fractional_nfts.rs @@ -5,6 +5,7 @@ use multiversx_sc::imports::*; use multiversx_sc_modules::default_issue_callbacks; mod fractional_uri_info; use fractional_uri_info::FractionalUriInfo; +pub mod nft_marketplace_proxy; #[multiversx_sc::contract] pub trait FractionalNfts: default_issue_callbacks::DefaultIssueCallbacksModule { @@ -39,10 +40,11 @@ pub trait FractionalNfts: default_issue_callbacks::DefaultIssueCallbacksModule { token_nonce: u64, ) { let caller = self.blockchain().get_caller(); - self.marketplace_proxy(marketplace_address) + self.tx() + .to(&marketplace_address) + .typed(nft_marketplace_proxy::NftMarketplaceProxy) .claim_tokens(caller, token_id, token_nonce) - .async_call() - .call_and_exit() + .async_call_and_exit(); } #[payable("*")] @@ -85,13 +87,14 @@ pub trait FractionalNfts: default_issue_callbacks::DefaultIssueCallbacksModule { &uris, ); - let caller = self.blockchain().get_caller(); - self.send().direct_esdt( - &caller, - fractional_token, - fractional_nonce, - &initial_fractional_amount, - ); + self.tx() + .to(ToCaller) + .single_esdt( + fractional_token, + fractional_nonce, + &initial_fractional_amount, + ) + .transfer(); } #[payable("*")] @@ -123,37 +126,18 @@ pub trait FractionalNfts: default_issue_callbacks::DefaultIssueCallbacksModule { ); let original = fractional_info.original_payment; - let caller = self.blockchain().get_caller(); - self.send().direct_esdt( - &caller, - &original.token_identifier, - original.token_nonce, - &original.amount, - ); + + self.tx() + .to(ToCaller) + .single_esdt( + &original.token_identifier, + original.token_nonce, + &original.amount, + ) + .transfer(); } #[view(getFractionalToken)] #[storage_mapper("fractional_token")] fn fractional_token(&self) -> NonFungibleTokenMapper; - - #[proxy] - fn marketplace_proxy( - &self, - sc_address: ManagedAddress, - ) -> nft_marketplace_proxy::Proxy; -} - -mod nft_marketplace_proxy { - use multiversx_sc::imports::*; - - #[multiversx_sc::proxy] - pub trait NftMarketplace { - #[endpoint(claimTokens)] - fn claim_tokens( - &self, - claim_destination: &ManagedAddress, - token_id: &EgldOrEsdtTokenIdentifier, - token_nonce: u64, - ) -> MultiValue2>; - } } diff --git a/contracts/examples/fractional-nfts/src/fractional_uri_info.rs b/contracts/examples/fractional-nfts/src/fractional_uri_info.rs index 4b41271a72..e6ebdba4f2 100644 --- a/contracts/examples/fractional-nfts/src/fractional_uri_info.rs +++ b/contracts/examples/fractional-nfts/src/fractional_uri_info.rs @@ -26,7 +26,7 @@ impl FractionalUriInfo { let serializer = ManagedSerializer::new(); serializer.top_decode_from_managed_buffer_custom_message( &first_uri, - b"Invalid Fractional URI info", + "Invalid Fractional URI info", ) } diff --git a/contracts/examples/fractional-nfts/src/nft_marketplace_proxy.rs b/contracts/examples/fractional-nfts/src/nft_marketplace_proxy.rs new file mode 100644 index 0000000000..7b45fa08e2 --- /dev/null +++ b/contracts/examples/fractional-nfts/src/nft_marketplace_proxy.rs @@ -0,0 +1,57 @@ +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct NftMarketplaceProxy; + +impl TxProxyTrait for NftMarketplaceProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = NftMarketplaceProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + NftMarketplaceProxyMethods { wrapped_tx: tx } + } +} + +pub struct NftMarketplaceProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl NftMarketplaceProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn claim_tokens< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + claim_destination: Arg0, + token_id: Arg1, + token_nonce: Arg2, + ) -> TxTypedCall, ManagedVec>>> { + self.wrapped_tx + .raw_call("claimTokens") + .argument(&claim_destination) + .argument(&token_id) + .argument(&token_nonce) + .original_result() + } +} diff --git a/contracts/examples/fractional-nfts/wasm/Cargo.lock b/contracts/examples/fractional-nfts/wasm/Cargo.lock index 8cb705ce82..68f96fa8e0 100644 --- a/contracts/examples/fractional-nfts/wasm/Cargo.lock +++ b/contracts/examples/fractional-nfts/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -56,26 +56,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +87,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,14 +98,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/fractional-nfts/wasm/Cargo.toml b/contracts/examples/fractional-nfts/wasm/Cargo.toml index ae8fa6d005..387fcc7ee4 100644 --- a/contracts/examples/fractional-nfts/wasm/Cargo.toml +++ b/contracts/examples/fractional-nfts/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.fractional-nfts] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/fractional-nfts/wasm/src/lib.rs b/contracts/examples/fractional-nfts/wasm/src/lib.rs index 2af55430fa..567d172c78 100644 --- a/contracts/examples/fractional-nfts/wasm/src/lib.rs +++ b/contracts/examples/fractional-nfts/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 6 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/lottery-esdt/Cargo.toml b/contracts/examples/lottery-esdt/Cargo.toml index 75cb2cdb2f..a54808e6ca 100644 --- a/contracts/examples/lottery-esdt/Cargo.toml +++ b/contracts/examples/lottery-esdt/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/lottery.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/lottery-esdt/meta/Cargo.toml b/contracts/examples/lottery-esdt/meta/Cargo.toml index fe025f1fbf..7e9ec5ec69 100644 --- a/contracts/examples/lottery-esdt/meta/Cargo.toml +++ b/contracts/examples/lottery-esdt/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.lottery-esdt] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/lottery-esdt/meta/src/main.rs b/contracts/examples/lottery-esdt/meta/src/main.rs index 65c466719d..e1da5acd0b 100644 --- a/contracts/examples/lottery-esdt/meta/src/main.rs +++ b/contracts/examples/lottery-esdt/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/lottery-esdt/src/lottery.rs b/contracts/examples/lottery-esdt/src/lottery.rs index 48a94b14b2..3c5d9040b1 100644 --- a/contracts/examples/lottery-esdt/src/lottery.rs +++ b/contracts/examples/lottery-esdt/src/lottery.rs @@ -291,19 +291,19 @@ pub trait Lottery { &BigUint::from(info.prize_distribution.get(i)), ); - self.send() - .direct(&winner_address, &info.token_identifier, 0, &prize); + self.tx() + .to(&winner_address) + .egld_or_single_esdt(&info.token_identifier, 0, &prize) + .transfer(); info.prize_pool -= prize; } // send leftover to first place let first_place_winner = ticket_holders_mapper.get(winning_tickets[0]); - self.send().direct( - &first_place_winner, - &info.token_identifier, - 0, - &info.prize_pool, - ); + self.tx() + .to(&first_place_winner) + .egld_or_single_esdt(&info.token_identifier, 0, &info.prize_pool) + .transfer(); } fn clear_storage(&self, lottery_name: &ManagedBuffer) { diff --git a/contracts/examples/lottery-esdt/tests/lottery_esdt_scenario_rs_test.rs b/contracts/examples/lottery-esdt/tests/lottery_esdt_scenario_rs_test.rs index 5fc5e76eba..4d6cf07266 100644 --- a/contracts/examples/lottery-esdt/tests/lottery_esdt_scenario_rs_test.rs +++ b/contracts/examples/lottery-esdt/tests/lottery_esdt_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/lottery-esdt"); blockchain.register_contract( "mxsc:output/lottery-esdt.mxsc.json", diff --git a/contracts/examples/lottery-esdt/wasm/Cargo.lock b/contracts/examples/lottery-esdt/wasm/Cargo.lock index a597e353be..071b76839d 100755 --- a/contracts/examples/lottery-esdt/wasm/Cargo.lock +++ b/contracts/examples/lottery-esdt/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/lottery-esdt/wasm/Cargo.toml b/contracts/examples/lottery-esdt/wasm/Cargo.toml index c0395a9569..543adef193 100644 --- a/contracts/examples/lottery-esdt/wasm/Cargo.toml +++ b/contracts/examples/lottery-esdt/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.lottery-esdt] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/lottery-esdt/wasm/src/lib.rs b/contracts/examples/lottery-esdt/wasm/src/lib.rs index 71be1abb68..a1184cee72 100644 --- a/contracts/examples/lottery-esdt/wasm/src/lib.rs +++ b/contracts/examples/lottery-esdt/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 9 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/multisig/Cargo.toml b/contracts/examples/multisig/Cargo.toml index 784f5b8bfd..f3b84f9529 100644 --- a/contracts/examples/multisig/Cargo.toml +++ b/contracts/examples/multisig/Cargo.toml @@ -9,15 +9,15 @@ publish = false path = "src/multisig.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dev-dependencies.adder] @@ -27,7 +27,7 @@ path = "../adder" path = "../factorial" [dev-dependencies.multiversx-wegld-swap-sc] -version = "0.47.5" +version = "0.50.3" path = "../../core/wegld-swap" [dev-dependencies] diff --git a/contracts/examples/multisig/interact/Cargo.toml b/contracts/examples/multisig/interact/Cargo.toml index 3720db003d..44c63436bc 100644 --- a/contracts/examples/multisig/interact/Cargo.toml +++ b/contracts/examples/multisig/interact/Cargo.toml @@ -18,13 +18,17 @@ toml = "0.8.6" path = ".." [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../../contracts/modules" [dependencies.multiversx-sc-snippets] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/snippets" [dependencies.multiversx-sc-scenario] -version = "=0.47.5" +version = "=0.50.3" path = "../../../../framework/scenario" + +[dependencies.multiversx-sc] +version = "=0.50.3" +path = "../../../../framework/base" diff --git a/contracts/examples/multisig/interact/config.toml b/contracts/examples/multisig/interact/config.toml index 1a1e45429a..029fab5ac7 100644 --- a/contracts/examples/multisig/interact/config.toml +++ b/contracts/examples/multisig/interact/config.toml @@ -1,2 +1,3 @@ -gateway = 'https://testnet-gateway.multiversx.com' +gateway = 'https://devnet-gateway.multiversx.com' quorum = 2 +wegld_address = "erd1qqqqqqqqqqqqqpgqqkwzsxkjc83vlfex9dmznwm7tjvxlqqkpauqx0n782" diff --git a/contracts/examples/multisig/interact/src/multisig_interact.rs b/contracts/examples/multisig/interact/src/multisig_interact.rs index cf679c5a13..497b6636dd 100644 --- a/contracts/examples/multisig/interact/src/multisig_interact.rs +++ b/contracts/examples/multisig/interact/src/multisig_interact.rs @@ -3,33 +3,15 @@ mod multisig_interact_config; mod multisig_interact_nfts; mod multisig_interact_state; mod multisig_interact_wegld; +mod wegld_proxy; use clap::Parser; -use multisig::{ - multisig_perform::ProxyTrait as _, multisig_propose::ProxyTrait as _, - multisig_state::ProxyTrait as _, ProxyTrait as _, -}; +use multisig::multisig_proxy; use multisig_interact_config::Config; use multisig_interact_state::State; -use multiversx_sc_modules::dns::ProxyTrait as _; -use multiversx_sc_scenario::{ - mandos_system::ScenarioRunner, multiversx_sc::codec::multi_types::IgnoreValue, - scenario_format::interpret_trait::InterpretableFrom, - standalone::retrieve_account_as_scenario_set_state, test_wallets, -}; -use multiversx_sc_snippets::{ - dns_address_for_name, env_logger, - multiversx_sc::{ - codec::multi_types::MultiValueVec, storage::mappers::SingleValue, types::Address, - }, - multiversx_sc_scenario::{ - api::StaticApi, bech32, scenario_format::interpret_trait::InterpreterContext, - scenario_model::*, ContractInfo, - }, - tokio, Interactor, StepBuffer, -}; - -const SYSTEM_SC_BECH32: &str = "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"; + +use multiversx_sc_snippets::imports::*; + const INTERACTOR_SCENARIO_TRACE_PATH: &str = "interactor_trace.scen.json"; #[tokio::main] @@ -94,17 +76,17 @@ async fn main() { struct MultisigInteract { interactor: Interactor, - wallet_address: Address, - system_sc_address: Address, + wallet_address: Bech32Address, collection_token_identifier: String, multisig_code: BytesValue, + config: Config, state: State, } impl MultisigInteract { async fn init() -> Self { let config = Config::load_config(); - let mut interactor = Interactor::new(config.gateway()) + let mut interactor = Interactor::new(&config.gateway) .await .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; @@ -116,10 +98,10 @@ impl MultisigInteract { Self { interactor, - wallet_address, - system_sc_address: bech32::decode(SYSTEM_SC_BECH32), + wallet_address: wallet_address.into(), collection_token_identifier: String::new(), multisig_code, + config, state: State::load_state(), } } @@ -140,17 +122,9 @@ impl MultisigInteract { "board member address: {}", bech32::encode(board_member_address) ); - let scenario_raw = retrieve_account_as_scenario_set_state( - Config::load_config().gateway().to_string(), - bech32::encode(board_member_address), - true, - ) - .await; - - let scenario = Scenario::interpret_from(scenario_raw, &InterpreterContext::default()); - - self.interactor.pre_runners.run_scenario(&scenario); - self.interactor.post_runners.run_scenario(&scenario); + self.interactor + .retrieve_account(&board_member_address.into()) + .await; } self.wegld_swap_set_state().await; @@ -160,27 +134,24 @@ impl MultisigInteract { self.set_state().await; let board = self.board(); - let (new_address, _) = self + + let quorum = self.config.quorum; + let new_address = self .interactor - .sc_deploy_get_result::<_, IgnoreValue>( - ScDeployStep::new() - .call( - self.state - .default_multisig() - .init(Config::load_config().quorum(), board), - ) - .from(&self.wallet_address) - .code(&self.multisig_code) - .gas_limit("100,000,000") - .expect(TxExpect::ok().additional_error_message("deploy failed: ")), - ) + .tx() + .from(&self.wallet_address) + .typed(multisig_proxy::MultisigProxy) + .init(quorum, board) + .code(&self.multisig_code) + .gas(NumExpr("100,000,000")) + .returns(ReturnsNewBech32Address) + .prepare_async() + .run() .await; - let new_address_bech32 = bech32::encode(&new_address); - println!("new address: {new_address_bech32}"); + println!("new address: {new_address}"); - let new_address_expr = format!("bech32:{new_address_bech32}"); - self.state.set_multisig_address(&new_address_expr); + self.state.set_multisig_address(new_address); } async fn multi_deploy(&mut self, count: &u8) { @@ -192,40 +163,23 @@ impl MultisigInteract { println!("deploying {count} contracts..."); let board = self.board(); - let mut steps = Vec::new(); + let quorum = Config::load_config().quorum; + let mut buffer = self.interactor.homogenous_call_buffer(); for _ in 0..*count { - let typed_sc_deploy = ScDeployStep::new() - .call( - self.state - .default_multisig() - .init(Config::load_config().quorum(), board.clone()), - ) - .from(&self.wallet_address) - .code(&self.multisig_code) - .gas_limit("70,000,000"); - - steps.push(typed_sc_deploy); + buffer.push_tx(|tx| { + tx.from(&self.wallet_address) + .typed(multisig_proxy::MultisigProxy) + .init(quorum, board.clone()) + .code(&self.multisig_code) + .gas(NumExpr("70,000,000")) + .returns(ReturnsNewBech32Address) + }); } - self.interactor - .multi_sc_exec(StepBuffer::from_sc_deploy_vec(&mut steps)) - .await; - - for step in steps.iter() { - // warning: multi deploy not yet fully supported - // only works with last deployed address - // will be addressed in future versions - let new_deployed_address = step.response().new_deployed_address.clone(); - if let Some(new_address) = new_deployed_address { - let new_address_bech32 = bech32::encode(&new_address); - println!("new address: {new_address_bech32}"); - - let new_address_expr = format!("bech32:{new_address_bech32}"); - self.state.set_multisig_address(&new_address_expr); - } else { - println!("deploy failed"); - return; - } + let results = buffer.run().await; + for new_address in results { + println!("new address: {new_address}"); + self.state.set_multisig_address(new_address); } } @@ -235,7 +189,7 @@ impl MultisigInteract { let eve = test_wallets::eve(); MultiValueVec::from([ - self.wallet_address.clone(), + self.wallet_address.to_address(), carol.address().to_bytes().into(), dan.address().to_bytes().into(), eve.address().to_bytes().into(), @@ -243,151 +197,183 @@ impl MultisigInteract { } async fn feed_contract_egld(&mut self) { - let _ = self - .interactor - .transfer( - TransferStep::new() - .from(&self.wallet_address) - .to(self.state.multisig()) - .egld_value("0,050000000000000000"), - ) + self.interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .egld(BigUint::from(50_000_000_000_000_000u64)) // 0,05 or 5 * 10^16 + .prepare_async() + .run() .await; } - async fn perform_action(&mut self, action_id: usize, gas_expr: &str) { - if !self.quorum_reached(action_id).await && !self.sign(action_id).await { - return; + async fn perform_action(&mut self, action_id: usize, gas_expr: u64) { + if !self.quorum_reached(action_id).await { + self.sign(&[action_id]).await } println!("quorum reached for action `{action_id}`"); self.interactor - .sc_call( - ScCallStep::new() - .call(self.state.multisig().perform_action_endpoint(action_id)) - .from(&self.wallet_address) - .gas_limit(gas_expr) - .expect(TxExpect::ok().additional_error_message(format!( - "perform action `{action_id}` failed with: " - ))), - ) + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .gas(gas_expr) + .typed(multisig_proxy::MultisigProxy) + .perform_action_endpoint(action_id) + .prepare_async() + .run() .await; println!("successfully performed action `{action_id}`"); } - async fn perform_actions(&mut self, actions: Vec, gas_expr: &str) { - let mut steps = Vec::new(); - for action_id in actions.iter() { - if !self.quorum_reached(*action_id).await && !self.sign(*action_id).await { - continue; + async fn perform_actions(&mut self, action_ids: Vec, gas_expr: u64) { + let mut actions_no_quorum_reached = Vec::new(); + for &action_id in &action_ids { + if self.quorum_reached(action_id).await { + println!("quorum reached for action `{action_id}`"); + } else { + actions_no_quorum_reached.push(action_id) } - println!("quorum reached for action `{action_id}`"); - - let typed_sc_call = ScCallStep::new() - .call(self.state.multisig().perform_action_endpoint(action_id)) - .from(&self.wallet_address) - .gas_limit(gas_expr); + } - steps.push(typed_sc_call); + self.sign(&actions_no_quorum_reached).await; + + let from = &self.wallet_address; + let mut buffer = self.interactor.homogenous_call_buffer(); + let multisig_address = self.state.current_multisig_address(); + for action_id in action_ids { + buffer.push_tx(|tx| { + tx.from(from) + .to(multisig_address) + .gas(gas_expr) + .typed(multisig_proxy::MultisigProxy) + .perform_action_endpoint(action_id) + .returns(ReturnsResult) + }); } - self.interactor - .multi_sc_exec(StepBuffer::from_sc_call_vec(&mut steps)) - .await; + let deployed_addresses = buffer.run().await; - for (i, action_id) in actions.iter().enumerate() { - if !steps[i].response().is_success() { + for (action_id, address) in deployed_addresses.iter().enumerate() { + println!("successfully performed action `{action_id}`"); + if address.is_some() { println!( - "perform action `{action_id}` failed with: {}", - steps[i].response().tx_error - ); - continue; + "new deployed address for action `{action_id}: {:#?}`", + address.clone().into_option().unwrap() + ) } - - println!("successfully performed action `{action_id}`"); } } async fn quorum_reached(&mut self, action_id: usize) -> bool { self.interactor - .quick_query(self.state.multisig().quorum_reached(action_id)) + .query() + .to(self.state.current_multisig_address()) + .typed(multisig_proxy::MultisigProxy) + .quorum_reached(action_id) + .returns(ReturnsResult) + .prepare_async() + .run() .await } async fn signed(&mut self, signer: &Address, action_id: usize) -> bool { self.interactor - .quick_query(self.state.multisig().signed(signer, action_id)) + .query() + .to(self.state.current_multisig_address()) + .typed(multisig_proxy::MultisigProxy) + .signed(signer, action_id) + .returns(ReturnsResult) + .prepare_async() + .run() .await } - async fn sign(&mut self, action_id: usize) -> bool { - println!("signing action `{action_id}`..."); - let mut steps = Vec::new(); - for signer in self.board().iter() { - if self.signed(signer, action_id).await { - println!( - "{} - already signed action `{action_id}`", - bech32::encode(signer) - ); - continue; + async fn sign(&mut self, action_ids: &[usize]) { + println!("signing actions `{action_ids:?}`..."); + + let mut pending_signers = Vec::<(Address, usize)>::new(); + for &action_id in action_ids { + for signer in self.board().iter() { + if self.signed(signer, action_id).await { + println!( + "{} - already signed action `{action_id}`", + bech32::encode(signer) + ); + } else { + pending_signers.push((signer.clone(), action_id)); + } } + } - let typed_sc_call = ScCallStep::new() - .call(self.state.multisig().sign(action_id)) - .from(signer) - .gas_limit("15,000,000"); - - steps.push(typed_sc_call); + let mut buffer = self.interactor.homogenous_call_buffer(); + let multisig_address = self.state.current_multisig_address(); + for (signer, action_id) in pending_signers { + buffer.push_tx(|tx| { + tx.from(signer) + .to(multisig_address) + .gas(15_000_000u64) + .typed(multisig_proxy::MultisigProxy) + .sign(action_id) + }); } - self.interactor - .multi_sc_exec(StepBuffer::from_sc_call_vec(&mut steps)) - .await; + buffer.run().await; - for step in steps.iter() { - if !step.response().is_success() { - println!( - "perform sign `{action_id}` failed with: {}", - step.response().tx_error - ); - return false; - } - } + println!("successfully performed sign action `{action_ids:?}`"); + } - println!("successfully performed sign action `{action_id}`"); - true + async fn sign_if_quorum_not_reached(&mut self, action_id: usize) { + if !self.quorum_reached(action_id).await { + self.sign(&[action_id]).await; + } + println!("quorum reached for action `{action_id}`"); } async fn dns_register(&mut self, name: &str) { let dns_address = dns_address_for_name(name); self.interactor - .sc_call( - ScCallStep::new() - .call(self.state.multisig().dns_register(dns_address, name)) - .from(&self.wallet_address) - .gas_limit("30,000,000") - .expect(TxExpect::ok().additional_error_message("dns register failed with: ")), - ) + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .gas(NumExpr("30,000,000")) + .typed(multisig_proxy::MultisigProxy) + .dns_register(dns_address, name) + .prepare_async() + .run() .await; println!("successfully registered dns"); } async fn print_quorum(&mut self) { - let quorum: SingleValue = self + let quorum = self .interactor - .quick_query(self.state.multisig().quorum()) + .query() + .to(self.state.current_multisig_address()) + .typed(multisig_proxy::MultisigProxy) + .quorum() + .returns(ReturnsResult) + .prepare_async() + .run() .await; - println!("quorum: {}", quorum.into()); + println!("quorum: {}", quorum); } async fn print_board(&mut self) { - let board: SingleValue = self + let board = self .interactor - .quick_query(self.state.multisig().num_board_members()) + .query() + .to(self.state.current_multisig_address()) + .typed(multisig_proxy::MultisigProxy) + .num_board_members() + .returns(ReturnsResult) + .prepare_async() + .run() .await; - println!("board: {}", board.into()); + println!("board: {}", board); } } diff --git a/contracts/examples/multisig/interact/src/multisig_interact_config.rs b/contracts/examples/multisig/interact/src/multisig_interact_config.rs index 2a7ea60f3a..4aa9903cc0 100644 --- a/contracts/examples/multisig/interact/src/multisig_interact_config.rs +++ b/contracts/examples/multisig/interact/src/multisig_interact_config.rs @@ -1,3 +1,4 @@ +use multiversx_sc_scenario::imports::Bech32Address; use serde::Deserialize; use std::io::Read; @@ -7,8 +8,9 @@ const CONFIG_FILE: &str = "config.toml"; /// Multisig Interact configuration #[derive(Debug, Deserialize)] pub struct Config { - gateway: String, - quorum: usize, + pub gateway: String, + pub quorum: usize, + pub wegld_address: Bech32Address, } impl Config { @@ -19,14 +21,4 @@ impl Config { file.read_to_string(&mut content).unwrap(); toml::from_str(&content).unwrap() } - - // Returns the gateway - pub fn gateway(&self) -> &str { - &self.gateway - } - - // Returns the quorum - pub fn quorum(&self) -> usize { - self.quorum - } } diff --git a/contracts/examples/multisig/interact/src/multisig_interact_nfts.rs b/contracts/examples/multisig/interact/src/multisig_interact_nfts.rs index ab8fa001f7..2efda8e4d6 100644 --- a/contracts/examples/multisig/interact/src/multisig_interact_nfts.rs +++ b/contracts/examples/multisig/interact/src/multisig_interact_nfts.rs @@ -1,9 +1,6 @@ use std::time::Duration; -use multiversx_sc_scenario::multiversx_sc::{ - codec::{multi_types::IgnoreValue, Empty}, - types::FunctionCall, -}; +use multiversx_sc_snippets::imports::*; use super::*; @@ -36,29 +33,26 @@ impl MultisigInteract { } pub async fn propose_issue_collection_with_all_roles(&mut self) -> usize { - let system_sc_address = bech32::decode(SYSTEM_SC_BECH32); let action_id = self .interactor - .sc_call_get_result( - ScCallStep::new() - .call( - self.state.multisig().propose_async_call( - system_sc_address, - ISSUE_COST, - FunctionCall::new("registerAndSetAllRoles") - .argument(&COLLECTION_NAME) - .argument(&COLLECTION_TICKER) - .argument(&TOKEN_TYPE) - .argument(&0u32), - ), - ) - .from(&self.wallet_address) - .gas_limit("10,000,000") - .expect(TxExpect::ok().additional_error_message("failed to issue collection")), + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .gas(NumExpr("10,000,000")) + .typed(multisig_proxy::MultisigProxy) + .propose_async_call( + ESDTSystemSCAddress, + ISSUE_COST, + FunctionCall::new("registerAndSetAllRoles") + .argument(&COLLECTION_NAME) + .argument(&COLLECTION_TICKER) + .argument(&TOKEN_TYPE) + .argument(&0u32), ) - .await - .result - .unwrap(); + .returns(ReturnsResult) + .prepare_async() + .run() + .await; println!("successfully proposed issue colllection with roles all action `{action_id}`"); action_id @@ -70,26 +64,22 @@ impl MultisigInteract { println!("perfoming issue collection with all roles action `{action_id}`..."); - if !self.quorum_reached(action_id).await && !self.sign(action_id).await { - return; - } - println!("quorum reached for action `{action_id}`"); + self.sign_if_quorum_not_reached(action_id).await; - let response: TypedResponse = self + let new_token_id = self .interactor - .sc_call_get_result( - ScCallStep::new() - .call(self.state.multisig().perform_action_endpoint(action_id)) - .from(&self.wallet_address) - .gas_limit("80,000,000") - .expect(TxExpect::ok().additional_error_message( - "perform issue collection with all roles failed: ", - )), - ) + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .gas(NumExpr("80,000,000")) + .typed(multisig_proxy::MultisigProxy) + .perform_action_endpoint(action_id) + .returns(ReturnsNewTokenIdentifier) + .prepare_async() + .run() .await; - self.collection_token_identifier = response - .new_issued_token_identifier - .expect("new token identifier could not be retrieved"); + self.collection_token_identifier = new_token_id.to_string(); + println!( "collection token identifier: {}", self.collection_token_identifier @@ -97,26 +87,24 @@ impl MultisigInteract { } pub async fn propose_issue_collection(&mut self) -> usize { - let system_sc_address = bech32::decode(SYSTEM_SC_BECH32); let action_id = self .interactor - .sc_call_get_result( - ScCallStep::new() - .call( - self.state.multisig().propose_async_call( - system_sc_address, - ISSUE_COST, - FunctionCall::new("issueNonFungible") - .argument(&COLLECTION_NAME) - .argument(&COLLECTION_TICKER), - ), - ) - .from(&self.wallet_address) - .gas_limit("10,000,000"), + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .gas(NumExpr("10,000,000")) + .typed(multisig_proxy::MultisigProxy) + .propose_async_call( + ESDTSystemSCAddress, + ISSUE_COST, + FunctionCall::new("issueNonFungible") + .argument(&COLLECTION_NAME) + .argument(&COLLECTION_TICKER), ) - .await - .result - .unwrap(); + .returns(ReturnsResult) + .prepare_async() + .run() + .await; println!("successfully proposed issue colllection action `{action_id}`"); action_id @@ -128,26 +116,22 @@ impl MultisigInteract { println!("perfoming issue collection action `{action_id}`..."); - if !self.quorum_reached(action_id).await && !self.sign(action_id).await { - return; - } - println!("quorum reached for action `{action_id}`"); - - let response: TypedResponse = - self.interactor - .sc_call_get_result( - ScCallStep::new() - .call(self.state.multisig().perform_action_endpoint(action_id)) - .from(&self.wallet_address) - .gas_limit("80,000,000") - .expect(TxExpect::ok().additional_error_message( - "perform issue collection with all failed: ", - )), - ) - .await; - self.collection_token_identifier = response - .new_issued_token_identifier - .expect("new token identifier could not be retrieved"); + self.sign_if_quorum_not_reached(action_id).await; + + let new_token_id = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .gas(NumExpr("80,000,000")) + .typed(multisig_proxy::MultisigProxy) + .perform_action_endpoint(action_id) + .returns(ReturnsNewTokenIdentifier) + .prepare_async() + .run() + .await; + self.collection_token_identifier = new_token_id; + println!( "collection token identifier: {}", self.collection_token_identifier @@ -155,27 +139,26 @@ impl MultisigInteract { } pub async fn propose_set_special_role(&mut self) -> usize { - let multisig_address = self.state.multisig().to_address(); + let multisig_address = self.state.current_multisig_address(); let action_id = self .interactor - .sc_call_get_result( - ScCallStep::new() - .call( - self.state.multisig().propose_async_call( - &self.system_sc_address, - 0u64, - FunctionCall::new("setSpecialRole") - .argument(&self.collection_token_identifier) - .argument(&multisig_address) - .argument(&"ESDTRoleNFTCreate"), - ), - ) - .from(&self.wallet_address) - .gas_limit("10,000,000"), + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .gas(NumExpr("10,000,000")) + .typed(multisig_proxy::MultisigProxy) + .propose_async_call( + ESDTSystemSCAddress, + 0u64, + FunctionCall::new("setSpecialRole") + .argument(&self.collection_token_identifier) + .argument(multisig_address) + .argument(&"ESDTRoleNFTCreate"), ) - .await - .result - .unwrap(); + .returns(ReturnsResult) + .prepare_async() + .run() + .await; println!("successfully proposed set special role with action `{action_id}`"); action_id @@ -186,25 +169,27 @@ impl MultisigInteract { let action_id = self.propose_set_special_role().await; println!("performing set special role action `{action_id}`..."); - self.perform_action(action_id, "80,000,000").await; + self.perform_action(action_id, 80_000_000u64).await; } pub async fn create_items(&mut self) { println!("creating items..."); - let multisig_address = self.state.multisig().to_address(); - let mut steps = Vec::new(); - + let mut buffer = self.interactor.homogenous_call_buffer(); + let multisig_address = self.state.current_multisig_address(); for item_index in 0..NUM_ITEMS { let item_name = format!("Test collection item #{item_index}"); let image_cid = format!( "https://ipfs.io/ipfs/QmYyAaEf1phJS5mN6wfou5de5GbpUddBxTY1VekKcjd5PC/nft{item_index:02}.png" ); - let typed_sc_call = ScCallStep::new() - .call( - self.state.multisig().propose_async_call( - &multisig_address, + buffer.push_tx(|tx| { + tx.from(&self.wallet_address) + .to(multisig_address) + .gas(10_000_000u64) + .typed(multisig_proxy::MultisigProxy) + .propose_async_call( + multisig_address, 0u64, FunctionCall::new("ESDTNFTCreate") .argument(&self.collection_token_identifier) @@ -214,34 +199,16 @@ impl MultisigInteract { .argument(&Empty) .argument(&METADATA) .argument(&image_cid), - ), - ) - .from(&self.wallet_address) - .gas_limit("10,000,000"); - - steps.push(typed_sc_call); + ) + .returns(ReturnsResult) + }); } - self.interactor - .multi_sc_exec(StepBuffer::from_sc_call_vec(&mut steps)) - .await; - - let mut actions = Vec::new(); - for step in steps.iter() { - let result = step.result(); - if result.is_err() { - println!( - "propose ESDTNFTCreate failed with: {}", - result.err().unwrap() - ); - return; - } - - let action_id = result.unwrap(); + let action_ids = buffer.run().await; + for action_id in action_ids.iter() { println!("successfully proposed ESDTNFTCreate action `{action_id}`"); - actions.push(action_id); } - self.perform_actions(actions, "30,000,000").await; + self.perform_actions(action_ids, 30_000_000u64).await; } } diff --git a/contracts/examples/multisig/interact/src/multisig_interact_state.rs b/contracts/examples/multisig/interact/src/multisig_interact_state.rs index fef8b8baff..d5ff8bb7c1 100644 --- a/contracts/examples/multisig/interact/src/multisig_interact_state.rs +++ b/contracts/examples/multisig/interact/src/multisig_interact_state.rs @@ -1,23 +1,17 @@ -use crate::{ContractInfo, StaticApi}; +use multiversx_sc_scenario::imports::Bech32Address; use serde::{Deserialize, Serialize}; use std::{ io::{Read, Write}, path::Path, }; -/// Default multisig address -const DEFAULT_MULTISIG_ADDRESS: &str = - "0x0000000000000000000000000000000000000000000000000000000000000000"; - /// State file const STATE_FILE: &str = "state.toml"; -pub type MultisigContract = ContractInfo>; - /// Multisig Interact state #[derive(Debug, Default, Serialize, Deserialize)] pub struct State { - multisig_address: Option, + multisig_address: Option, } impl State { @@ -34,18 +28,14 @@ impl State { } /// Sets the multisig address - pub fn set_multisig_address(&mut self, address: &str) { - self.multisig_address = Some(String::from(address)); - } - - /// Returns the multisig contract - pub fn multisig(&self) -> MultisigContract { - MultisigContract::new(self.multisig_address.clone().unwrap()) + pub fn set_multisig_address(&mut self, address: Bech32Address) { + self.multisig_address = Some(address); } - /// Returns the multisig contract with default address - pub fn default_multisig(&self) -> MultisigContract { - MultisigContract::new(DEFAULT_MULTISIG_ADDRESS) + pub fn current_multisig_address(&self) -> &Bech32Address { + self.multisig_address + .as_ref() + .expect("no known multisig contract, deploy first") } } diff --git a/contracts/examples/multisig/interact/src/multisig_interact_wegld.rs b/contracts/examples/multisig/interact/src/multisig_interact_wegld.rs index a0d105abd9..7774bc02d4 100644 --- a/contracts/examples/multisig/interact/src/multisig_interact_wegld.rs +++ b/contracts/examples/multisig/interact/src/multisig_interact_wegld.rs @@ -1,22 +1,9 @@ use std::time::Duration; -use multiversx_sc_scenario::multiversx_sc::types::FunctionCall; -#[allow(unused_imports)] -use multiversx_sc_snippets::multiversx_sc::types::{ - EsdtTokenPayment, MultiValueEncoded, TokenIdentifier, -}; -use multiversx_sc_snippets::{ - multiversx_sc::types::{ContractCall, ContractCallNoPayment}, - multiversx_sc_scenario::{ - mandos_system::ScenarioRunner, scenario_format::interpret_trait::InterpretableFrom, - standalone::retrieve_account_as_scenario_set_state, - }, -}; +use multiversx_sc_snippets::imports::*; use super::*; -const WEGLD_SWAP_SC_BECH32: &str = "erd1qqqqqqqqqqqqqpgqcy2wua5cq59y6sxqj2ka3scayh5e5ms7cthqht8xtp"; -const WEGLD_TOKEN_IDENTIFIER: &str = "WEGLD-6cf38e"; const WRAP_AMOUNT: u64 = 50000000000000000; // 0.05 EGLD const UNWRAP_AMOUNT: u64 = 25000000000000000; // 0.025 WEGLD @@ -34,7 +21,7 @@ impl MultisigInteract { let action_id = self.propose_wrap_egld().await; println!("perfoming wrap egld action `{action_id}`..."); - self.perform_action(action_id, "15,000,000").await; + self.perform_action(action_id, 15_000_000u64).await; } pub async fn unwrap_egld(&mut self) { @@ -42,71 +29,84 @@ impl MultisigInteract { let action_id = self.propose_unwrap_egld().await; println!("perfoming unwrap egld action `{action_id}`..."); - self.perform_action(action_id, "15,000,000").await; + self.perform_action(action_id, 15_000_000u64).await; } pub async fn wegld_swap_set_state(&mut self) { - let scenario_raw = retrieve_account_as_scenario_set_state( - Config::load_config().gateway().to_string(), - WEGLD_SWAP_SC_BECH32.to_string(), - true, - ) - .await; - - let scenario = Scenario::interpret_from(scenario_raw, &InterpreterContext::default()); - - self.interactor.pre_runners.run_scenario(&scenario); - self.interactor.post_runners.run_scenario(&scenario); + self.interactor + .retrieve_account(&self.config.wegld_address) + .await; } async fn propose_wrap_egld(&mut self) -> usize { + let function_call = self + .interactor + .tx() + .to(&self.config.wegld_address) + .typed(wegld_proxy::EgldEsdtSwapProxy) + .wrap_egld() + .into_function_call(); + let action_id = self .interactor - .sc_call_get_result( - ScCallStep::new() - .call(self.state.multisig().propose_async_call( - bech32::decode(WEGLD_SWAP_SC_BECH32), - WRAP_AMOUNT, - FunctionCall::new("wrapEgld"), - )) - .from(&self.wallet_address) - .gas_limit("10,000,000"), - ) - .await - .result - .unwrap(); + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .gas(NumExpr("10,000,000")) + .typed(multisig_proxy::MultisigProxy) + .propose_async_call(&self.config.wegld_address, WRAP_AMOUNT, function_call) + .returns(ReturnsResult) + .prepare_async() + .run() + .await; println!("successfully proposed wrap egld action `{action_id}`"); action_id } + pub async fn query_wegld_token_identifier(&mut self) -> TokenIdentifier { + let wegld_token_id = self + .interactor + .query() + .to(&self.config.wegld_address) + .typed(wegld_proxy::EgldEsdtSwapProxy) + .wrapped_egld_token_id() + .returns(ReturnsResult) + .prepare_async() + .run() + .await; + + println!("WEGLD token identifier: {wegld_token_id}"); + + wegld_token_id + } + async fn propose_unwrap_egld(&mut self) -> usize { - let contract_call = ContractCallNoPayment::::new( - bech32::decode(WEGLD_SWAP_SC_BECH32).into(), - "unwrapEgld", - ) - .with_esdt_transfer(EsdtTokenPayment::new( - TokenIdentifier::from(WEGLD_TOKEN_IDENTIFIER), - 0u64, - UNWRAP_AMOUNT.into(), - )) - .into_normalized(); + let wegld_token_id = self.query_wegld_token_identifier().await; + + let normalized_tx = self + .interactor + .tx() + .to(&self.config.wegld_address) + .typed(wegld_proxy::EgldEsdtSwapProxy) + .unwrap_egld() + .single_esdt(&wegld_token_id, 0u64, &UNWRAP_AMOUNT.into()) + .normalize(); + let normalized_to = normalized_tx.to; + let normalized_data = normalized_tx.data; let action_id = self .interactor - .sc_call_get_result( - ScCallStep::new() - .call(self.state.multisig().propose_async_call( - contract_call.basic.to, - 0u64, - contract_call.basic.function_call, - )) - .from(&self.wallet_address) - .gas_limit("10,000,000"), - ) - .await - .result - .unwrap(); + .tx() + .from(&self.wallet_address) + .to(self.state.current_multisig_address()) + .gas(NumExpr("10,000,000")) + .typed(multisig_proxy::MultisigProxy) + .propose_async_call(normalized_to, 0u64, normalized_data) + .returns(ReturnsResult) + .prepare_async() + .run() + .await; println!("successfully proposed unwrap egld action `{action_id}`"); action_id diff --git a/contracts/examples/multisig/interact/src/wegld_proxy.rs b/contracts/examples/multisig/interact/src/wegld_proxy.rs new file mode 100644 index 0000000000..404831a1bd --- /dev/null +++ b/contracts/examples/multisig/interact/src/wegld_proxy.rs @@ -0,0 +1,129 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct EgldEsdtSwapProxy; + +impl TxProxyTrait for EgldEsdtSwapProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = EgldEsdtSwapProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + EgldEsdtSwapProxyMethods { wrapped_tx: tx } + } +} + +pub struct EgldEsdtSwapProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl EgldEsdtSwapProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + >( + self, + wrapped_egld_token_id: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&wrapped_egld_token_id) + .original_result() + } +} + +#[rustfmt::skip] +impl EgldEsdtSwapProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn wrap_egld( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .raw_call("wrapEgld") + .original_result() + } + + pub fn unwrap_egld( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("unwrapEgld") + .original_result() + } + + pub fn get_locked_egld_balance( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getLockedEgldBalance") + .original_result() + } + + pub fn wrapped_egld_token_id( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getWrappedEgldTokenId") + .original_result() + } + + pub fn pause_endpoint( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("pause") + .original_result() + } + + pub fn unpause_endpoint( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unpause") + .original_result() + } + + pub fn paused_status( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isPaused") + .original_result() + } +} diff --git a/contracts/examples/multisig/meta/Cargo.toml b/contracts/examples/multisig/meta/Cargo.toml index 1b46da4489..491eb95b25 100644 --- a/contracts/examples/multisig/meta/Cargo.toml +++ b/contracts/examples/multisig/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.multisig] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/multisig/meta/src/main.rs b/contracts/examples/multisig/meta/src/main.rs index 69a0a648b1..8719674b92 100644 --- a/contracts/examples/multisig/meta/src/main.rs +++ b/contracts/examples/multisig/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/multisig/sc-config.toml b/contracts/examples/multisig/sc-config.toml index ca6a294c4f..79c3aeaa20 100644 --- a/contracts/examples/multisig/sc-config.toml +++ b/contracts/examples/multisig/sc-config.toml @@ -14,3 +14,6 @@ name = "multisig-view" external-view = true add-unlabelled = false add-labels = ["multisig-external-view"] + +[[proxy]] +path = "src/multisig_proxy.rs" diff --git a/contracts/examples/multisig/src/action.rs b/contracts/examples/multisig/src/action.rs index d36af70f90..c26c83259a 100644 --- a/contracts/examples/multisig/src/action.rs +++ b/contracts/examples/multisig/src/action.rs @@ -5,7 +5,8 @@ use multiversx_sc::{ use multiversx_sc::derive_imports::*; -#[derive(NestedEncode, NestedDecode, TypeAbi, Clone)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, Clone)] pub struct CallActionData { pub to: ManagedAddress, pub egld_amount: BigUint, @@ -13,7 +14,8 @@ pub struct CallActionData { pub arguments: ManagedVec>, } -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi, Clone)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, Clone)] pub enum Action { Nothing, AddBoardMember(ManagedAddress), @@ -47,7 +49,8 @@ impl Action { } /// Not used internally, just to retrieve results via endpoint. -#[derive(TopEncode, TypeAbi)] +#[type_abi] +#[derive(TopEncode)] pub struct ActionFullInfo { pub action_id: usize, pub action_data: Action, diff --git a/contracts/examples/multisig/src/multisig.rs b/contracts/examples/multisig/src/multisig.rs index a3baed53ce..96d3d5cdfa 100644 --- a/contracts/examples/multisig/src/multisig.rs +++ b/contracts/examples/multisig/src/multisig.rs @@ -4,6 +4,7 @@ pub mod action; pub mod multisig_events; pub mod multisig_perform; pub mod multisig_propose; +pub mod multisig_proxy; pub mod multisig_state; pub mod user_role; diff --git a/contracts/examples/multisig/src/multisig_perform.rs b/contracts/examples/multisig/src/multisig_perform.rs index 1912b85321..3024df2696 100644 --- a/contracts/examples/multisig/src/multisig_perform.rs +++ b/contracts/examples/multisig/src/multisig_perform.rs @@ -167,16 +167,13 @@ pub trait MultisigPerformModule: &call_data.endpoint_name, call_data.arguments.as_multi(), ); - let result = self.send_raw().direct_egld_execute( - &call_data.to, - &call_data.egld_amount, - gas, - &call_data.endpoint_name, - &call_data.arguments.into(), - ); - if let Result::Err(e) = result { - sc_panic!(e); - } + self.tx() + .to(call_data.to) + .egld(call_data.egld_amount) + .gas(gas) + .raw_call(call_data.endpoint_name) + .arguments_raw(call_data.arguments.into()) + .transfer_execute(); OptionalValue::None }, Action::SendAsyncCall(call_data) => { @@ -189,13 +186,14 @@ pub trait MultisigPerformModule: &call_data.endpoint_name, call_data.arguments.as_multi(), ); - self.send() - .contract_call::<()>(call_data.to, call_data.endpoint_name) - .with_egld_transfer(call_data.egld_amount) - .with_raw_arguments(call_data.arguments.into()) - .async_call() - .with_callback(self.callbacks().perform_async_call_callback()) - .call_and_exit() + + self.tx() + .to(&call_data.to) + .raw_call(call_data.endpoint_name) + .arguments_raw(call_data.arguments.into()) + .egld(call_data.egld_amount) + .callback(self.callbacks().perform_async_call_callback()) + .async_call_and_exit(); }, Action::SCDeployFromSource { amount, @@ -212,13 +210,16 @@ pub trait MultisigPerformModule: gas_left, arguments.as_multi(), ); - let (new_address, _) = self.send_raw().deploy_from_source_contract( - gas_left, - &amount, - &source, - code_metadata, - &arguments.into(), - ); + let new_address = self + .tx() + .egld(amount) + .gas(gas_left) + .raw_deploy() + .from_source(source) + .code_metadata(code_metadata) + .arguments_raw(arguments.into()) + .returns(ReturnsNewManagedAddress) + .sync_call(); OptionalValue::Some(new_address) }, Action::SCUpgradeFromSource { @@ -238,14 +239,15 @@ pub trait MultisigPerformModule: gas_left, arguments.as_multi(), ); - self.send_raw().upgrade_from_source_contract( - &sc_address, - gas_left, - &amount, - &source, - code_metadata, - &arguments.into(), - ); + self.tx() + .to(sc_address) + .egld(amount) + .gas(gas_left) + .raw_upgrade() + .from_source(source) + .code_metadata(code_metadata) + .arguments_raw(arguments.into()) + .upgrade_async_call_and_exit(); OptionalValue::None }, } diff --git a/contracts/examples/multisig/src/multisig_proxy.rs b/contracts/examples/multisig/src/multisig_proxy.rs new file mode 100644 index 0000000000..d3a3e32e0e --- /dev/null +++ b/contracts/examples/multisig/src/multisig_proxy.rs @@ -0,0 +1,580 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct MultisigProxy; + +impl TxProxyTrait for MultisigProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = MultisigProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + MultisigProxyMethods { wrapped_tx: tx } + } +} + +pub struct MultisigProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl MultisigProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg, + Arg1: ProxyArg>>, + >( + self, + quorum: Arg0, + board: Arg1, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&quorum) + .argument(&board) + .original_result() + } +} + +#[rustfmt::skip] +impl MultisigProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade< + Arg0: ProxyArg, + Arg1: ProxyArg>>, + >( + self, + quorum: Arg0, + board: Arg1, + ) -> TxTypedUpgrade { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .argument(&quorum) + .argument(&board) + .original_result() + } +} + +#[rustfmt::skip] +impl MultisigProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + /// Allows the contract to receive funds even if it is marked as unpayable in the protocol. + pub fn deposit( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("deposit") + .original_result() + } + + /// Iterates through all actions and retrieves those that are still pending. + /// Serialized full action data: + /// - the action id + /// - the serialized action data + /// - (number of signers followed by) list of signer addresses. + pub fn get_pending_action_full_info( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getPendingActionFullInfo") + .original_result() + } + + /// Returns `true` (`1`) if the user has signed the action. + /// Does not check whether or not the user is still a board member and the signature valid. + pub fn signed< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + user: Arg0, + action_id: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("signed") + .argument(&user) + .argument(&action_id) + .original_result() + } + + /// Indicates user rights. + /// `0` = no rights, + /// `1` = can propose, but not sign, + /// `2` = can propose and sign. + pub fn user_role< + Arg0: ProxyArg>, + >( + self, + user: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("userRole") + .argument(&user) + .original_result() + } + + /// Lists all users that can sign actions. + pub fn get_all_board_members( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getAllBoardMembers") + .original_result() + } + + /// Lists all proposers that are not board members. + pub fn get_all_proposers( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getAllProposers") + .original_result() + } + + /// Used by board members to sign actions. + pub fn sign< + Arg0: ProxyArg, + >( + self, + action_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("sign") + .argument(&action_id) + .original_result() + } + + /// Board members can withdraw their signatures if they no longer desire for the action to be executed. + /// Actions that are left with no valid signatures can be then deleted to free up storage. + pub fn unsign< + Arg0: ProxyArg, + >( + self, + action_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unsign") + .argument(&action_id) + .original_result() + } + + /// Clears storage pertaining to an action that is no longer supposed to be executed. + /// Any signatures that the action received must first be removed, via `unsign`. + /// Otherwise this endpoint would be prone to abuse. + pub fn discard_action< + Arg0: ProxyArg, + >( + self, + action_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("discardAction") + .argument(&action_id) + .original_result() + } + + /// Minimum number of signatures needed to perform any action. + pub fn quorum( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getQuorum") + .original_result() + } + + /// Denormalized board member count. + /// It is kept in sync with the user list by the contract. + pub fn num_board_members( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getNumBoardMembers") + .original_result() + } + + /// Denormalized proposer count. + /// It is kept in sync with the user list by the contract. + pub fn num_proposers( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getNumProposers") + .original_result() + } + + /// The index of the last proposed action. + /// 0 means that no action was ever proposed yet. + pub fn get_action_last_index( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getActionLastIndex") + .original_result() + } + + /// Serialized action data of an action with index. + pub fn get_action_data< + Arg0: ProxyArg, + >( + self, + action_id: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getActionData") + .argument(&action_id) + .original_result() + } + + /// Gets addresses of all users who signed an action. + /// Does not check if those users are still board members or not, + /// so the result may contain invalid signers. + pub fn get_action_signers< + Arg0: ProxyArg, + >( + self, + action_id: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getActionSigners") + .argument(&action_id) + .original_result() + } + + /// Gets addresses of all users who signed an action and are still board members. + /// All these signatures are currently valid. + pub fn get_action_signer_count< + Arg0: ProxyArg, + >( + self, + action_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getActionSignerCount") + .argument(&action_id) + .original_result() + } + + /// It is possible for board members to lose their role. + /// They are not automatically removed from all actions when doing so, + /// therefore the contract needs to re-check every time when actions are performed. + /// This function is used to validate the signers before performing an action. + /// It also makes it easy to check before performing an action. + pub fn get_action_valid_signer_count< + Arg0: ProxyArg, + >( + self, + action_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getActionValidSignerCount") + .argument(&action_id) + .original_result() + } + + /// Initiates board member addition process. + /// Can also be used to promote a proposer to board member. + pub fn propose_add_board_member< + Arg0: ProxyArg>, + >( + self, + board_member_address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("proposeAddBoardMember") + .argument(&board_member_address) + .original_result() + } + + /// Initiates proposer addition process.. + /// Can also be used to demote a board member to proposer. + pub fn propose_add_proposer< + Arg0: ProxyArg>, + >( + self, + proposer_address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("proposeAddProposer") + .argument(&proposer_address) + .original_result() + } + + /// Removes user regardless of whether it is a board member or proposer. + pub fn propose_remove_user< + Arg0: ProxyArg>, + >( + self, + user_address: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("proposeRemoveUser") + .argument(&user_address) + .original_result() + } + + pub fn propose_change_quorum< + Arg0: ProxyArg, + >( + self, + new_quorum: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("proposeChangeQuorum") + .argument(&new_quorum) + .original_result() + } + + /// Propose a transaction in which the contract will perform a transfer-execute call. + /// Can send EGLD without calling anything. + /// Can call smart contract endpoints directly. + /// Doesn't really work with builtin functions. + pub fn propose_transfer_execute< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + to: Arg0, + egld_amount: Arg1, + function_call: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("proposeTransferExecute") + .argument(&to) + .argument(&egld_amount) + .argument(&function_call) + .original_result() + } + + /// Propose a transaction in which the contract will perform a transfer-execute call. + /// Can call smart contract endpoints directly. + /// Can use ESDTTransfer/ESDTNFTTransfer/MultiESDTTransfer to send tokens, while also optionally calling endpoints. + /// Works well with builtin functions. + /// Cannot simply send EGLD directly without calling anything. + pub fn propose_async_call< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + to: Arg0, + egld_amount: Arg1, + function_call: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("proposeAsyncCall") + .argument(&to) + .argument(&egld_amount) + .argument(&function_call) + .original_result() + } + + pub fn propose_sc_deploy_from_source< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>>, + >( + self, + amount: Arg0, + source: Arg1, + code_metadata: Arg2, + arguments: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("proposeSCDeployFromSource") + .argument(&amount) + .argument(&source) + .argument(&code_metadata) + .argument(&arguments) + .original_result() + } + + pub fn propose_sc_upgrade_from_source< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg, + Arg4: ProxyArg>>, + >( + self, + sc_address: Arg0, + amount: Arg1, + source: Arg2, + code_metadata: Arg3, + arguments: Arg4, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("proposeSCUpgradeFromSource") + .argument(&sc_address) + .argument(&amount) + .argument(&source) + .argument(&code_metadata) + .argument(&arguments) + .original_result() + } + + /// Returns `true` (`1`) if `getActionValidSignerCount >= getQuorum`. + pub fn quorum_reached< + Arg0: ProxyArg, + >( + self, + action_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("quorumReached") + .argument(&action_id) + .original_result() + } + + /// Proposers and board members use this to launch signed actions. + pub fn perform_action_endpoint< + Arg0: ProxyArg, + >( + self, + action_id: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("performAction") + .argument(&action_id) + .original_result() + } + + pub fn dns_register< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + dns_address: Arg0, + name: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("dnsRegister") + .argument(&dns_address) + .argument(&name) + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode)] +pub struct ActionFullInfo +where + Api: ManagedTypeApi, +{ + pub action_id: usize, + pub action_data: Action, + pub signers: ManagedVec>, +} + +#[rustfmt::skip] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, Clone)] +pub enum Action +where + Api: ManagedTypeApi, +{ + Nothing, + AddBoardMember(ManagedAddress), + AddProposer(ManagedAddress), + RemoveUser(ManagedAddress), + ChangeQuorum(usize), + SendTransferExecute(CallActionData), + SendAsyncCall(CallActionData), + SCDeployFromSource { + amount: BigUint, + source: ManagedAddress, + code_metadata: CodeMetadata, + arguments: ManagedVec>, + }, + SCUpgradeFromSource { + sc_address: ManagedAddress, + amount: BigUint, + source: ManagedAddress, + code_metadata: CodeMetadata, + arguments: ManagedVec>, + }, +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, Clone)] +pub struct CallActionData +where + Api: ManagedTypeApi, +{ + pub to: ManagedAddress, + pub egld_amount: BigUint, + pub endpoint_name: ManagedBuffer, + pub arguments: ManagedVec>, +} + +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub enum UserRole { + None, + Proposer, + BoardMember, +} diff --git a/contracts/examples/multisig/tests/multisig_blackbox_test.rs b/contracts/examples/multisig/tests/multisig_blackbox_test.rs index bb8eeff8f4..083a6c6be6 100644 --- a/contracts/examples/multisig/tests/multisig_blackbox_test.rs +++ b/contracts/examples/multisig/tests/multisig_blackbox_test.rs @@ -1,263 +1,246 @@ -use adder::ProxyTrait as _; -use multisig::{ - multisig_perform::ProxyTrait as _, multisig_propose::ProxyTrait as _, user_role::UserRole, - ProxyTrait as _, -}; -use multiversx_sc::{ - codec::{ - multi_types::{MultiValueVec, OptionalValue}, - test_util::top_encode_to_vec_u8_or_panic, - }, - storage::mappers::SingleValue, - types::{Address, CodeMetadata, ContractCallNoPayment, FunctionCall}, -}; -use multiversx_sc_scenario::{ - api::StaticApi, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, ScDeployStep, ScQueryStep, - SetStateStep, TxExpect, - }, - ContractInfo, ScenarioWorld, -}; +use multiversx_sc::codec::top_encode_to_vec_u8_or_panic; +use multiversx_sc_scenario::imports::*; + +use adder::adder_proxy; +use multisig::multisig_proxy; use num_bigint::BigUint; -const ADDER_ADDRESS_EXPR: &str = "sc:adder"; -const ADDER_OWNER_ADDRESS_EXPR: &str = "address:adder-owner"; -const ADDER_PATH_EXPR: &str = "mxsc:test-contracts/adder.mxsc.json"; -const BOARD_MEMBER_ADDRESS_EXPR: &str = "address:board-member"; -const MULTISIG_ADDRESS_EXPR: &str = "sc:multisig"; -const MULTISIG_PATH_EXPR: &str = "mxsc:output/multisig.mxsc.json"; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const PROPOSER_ADDRESS_EXPR: &str = "address:proposer"; -const PROPOSER_BALANCE_EXPR: &str = "100,000,000"; +const ADDER_ADDRESS: TestSCAddress = TestSCAddress::new("adder"); +const ADDER_OWNER_ADDRESS: TestAddress = TestAddress::new("adder-owner"); +const ADDER_CODE_PATH: MxscPath = MxscPath::new("test-contracts/adder.mxsc.json"); +const BOARD_MEMBER_ADDRESS: TestAddress = TestAddress::new("board-member"); +const MULTISIG_ADDRESS: TestSCAddress = TestSCAddress::new("multisig"); +const MULTISIG_CODE_PATH: MxscPath = MxscPath::new("output/multisig.mxsc.json"); +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const PROPOSER_ADDRESS: TestAddress = TestAddress::new("proposer"); +const PROPOSER_BALANCE: u64 = 100_000_000; const QUORUM_SIZE: usize = 1; -type MultisigContract = ContractInfo>; -type AdderContract = ContractInfo>; - fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/multisig"); - blockchain.register_contract(MULTISIG_PATH_EXPR, multisig::ContractBuilder); - blockchain.register_contract(ADDER_PATH_EXPR, adder::ContractBuilder); + blockchain.register_contract(MULTISIG_CODE_PATH, multisig::ContractBuilder); + blockchain.register_contract(ADDER_CODE_PATH, adder::ContractBuilder); blockchain } struct MultisigTestState { world: ScenarioWorld, - proposer_address: Address, - board_member_address: Address, - multisig_contract: MultisigContract, - adder_contract: AdderContract, - adder_address: Address, } impl MultisigTestState { fn new() -> Self { let mut world = world(); - world.set_state_step( - SetStateStep::new() - .put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .new_address(OWNER_ADDRESS_EXPR, 1, MULTISIG_ADDRESS_EXPR) - .put_account( - PROPOSER_ADDRESS_EXPR, - Account::new().nonce(1).balance(PROPOSER_BALANCE_EXPR), - ) - .put_account(BOARD_MEMBER_ADDRESS_EXPR, Account::new().nonce(1)) - .put_account(ADDER_OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .new_address(ADDER_OWNER_ADDRESS_EXPR, 1, ADDER_ADDRESS_EXPR), - ); - - let proposer_address = AddressValue::from(PROPOSER_ADDRESS_EXPR).to_address(); - let board_member_address = AddressValue::from(BOARD_MEMBER_ADDRESS_EXPR).to_address(); - let multisig_contract = MultisigContract::new(MULTISIG_ADDRESS_EXPR); - let adder_contract = AdderContract::new(ADDER_ADDRESS_EXPR); - let adder_address = AddressValue::from(ADDER_ADDRESS_EXPR).to_address(); - - Self { - world, - proposer_address, - board_member_address, - multisig_contract, - adder_contract, - adder_address, - } + + world + .account(OWNER_ADDRESS) + .nonce(1) + .account(PROPOSER_ADDRESS) + .nonce(1) + .balance(PROPOSER_BALANCE) + .account(BOARD_MEMBER_ADDRESS) + .nonce(1) + .account(ADDER_OWNER_ADDRESS) + .nonce(1); + + Self { world } } fn deploy_multisig_contract(&mut self) -> &mut Self { - let multisig_code = self.world.code_expression(MULTISIG_PATH_EXPR); - let board_members = MultiValueVec::from(vec![self.board_member_address.clone()]); - - self.world.sc_deploy( - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(multisig_code) - .call(self.multisig_contract.init(QUORUM_SIZE, board_members)), - ); - - let action_id: usize = self.world.sc_call_get_result( - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR).call( - self.multisig_contract - .propose_add_proposer(self.proposer_address.clone()), - ), - ); + let board_members = MultiValueVec::from(vec![BOARD_MEMBER_ADDRESS]); + + self.world + .tx() + .from(OWNER_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .init(QUORUM_SIZE, board_members) + .code(MULTISIG_CODE_PATH) + .new_address(MULTISIG_ADDRESS) + .run(); + + let action_id: usize = self + .world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_add_proposer(PROPOSER_ADDRESS) + .returns(ReturnsResult) + .run(); + self.sign(action_id); self.perform(action_id); - self.expect_user_role(&self.proposer_address.clone(), UserRole::Proposer); + self.expect_user_role(PROPOSER_ADDRESS, multisig_proxy::UserRole::Proposer); self } - fn deploy_adder_contract(&mut self) -> &mut Self { - let adder_code = self.world.code_expression(ADDER_PATH_EXPR); - - self.world.sc_deploy( - ScDeployStep::new() - .from(ADDER_OWNER_ADDRESS_EXPR) - .code(adder_code) - .call(self.adder_contract.init(5u64)), - ); - - self + fn deploy_adder_contract(&mut self) { + self.world + .tx() + .from(ADDER_OWNER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .init(5u64) + .code(ADDER_CODE_PATH) + .new_address(ADDER_ADDRESS) + .run(); } - fn propose_add_board_member(&mut self, board_member_address: Address) -> usize { - self.world.sc_call_get_result( - ScCallStep::new().from(PROPOSER_ADDRESS_EXPR).call( - self.multisig_contract - .propose_add_board_member(board_member_address), - ), - ) + fn propose_add_board_member(&mut self, board_member_address: TestAddress) -> usize { + self.world + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_add_board_member(board_member_address) + .returns(ReturnsResult) + .run() } - fn propose_add_proposer(&mut self, proposer_address: Address) -> usize { - self.world.sc_call_get_result( - ScCallStep::new().from(PROPOSER_ADDRESS_EXPR).call( - self.multisig_contract - .propose_add_proposer(proposer_address), - ), - ) + fn propose_add_proposer(&mut self, proposer_address: TestAddress) -> usize { + self.world + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_add_proposer(proposer_address) + .returns(ReturnsResult) + .run() } fn propose_change_quorum(&mut self, new_quorum: usize) -> usize { - self.world.sc_call_get_result( - ScCallStep::new() - .from(PROPOSER_ADDRESS_EXPR) - .call(self.multisig_contract.propose_change_quorum(new_quorum)), - ) + self.world + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_change_quorum(new_quorum) + .returns(ReturnsResult) + .run() } fn propose_transfer_execute( &mut self, - to: Address, + to: TestSCAddress, egld_amount: u64, - contract_call: ContractCallNoPayment, + contract_call: FunctionCall, ) -> usize { self.world - .sc_call_get_result(ScCallStep::new().from(PROPOSER_ADDRESS_EXPR).call( - self.multisig_contract.propose_transfer_execute( - to, - egld_amount, - contract_call.into_function_call(), - ), - )) + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_transfer_execute(to, egld_amount, contract_call) + .returns(ReturnsResult) + .run() } fn propose_async_call( &mut self, - to: Address, + to: TestSCAddress, egld_amount: u64, - contract_call: ContractCallNoPayment, + contract_call: FunctionCall, ) -> usize { self.world - .sc_call_get_result(ScCallStep::new().from(PROPOSER_ADDRESS_EXPR).call( - self.multisig_contract.propose_async_call( - to, - egld_amount, - contract_call.into_function_call(), - ), - )) + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_async_call(to, egld_amount, contract_call) + .returns(ReturnsResult) + .run() } - fn propose_remove_user(&mut self, user_address: Address) -> usize { - self.world.sc_call_get_result( - ScCallStep::new() - .from(PROPOSER_ADDRESS_EXPR) - .call(self.multisig_contract.propose_remove_user(user_address)), - ) + fn propose_remove_user(&mut self, user_address: TestAddress) -> usize { + self.world + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_remove_user(user_address) + .returns(ReturnsResult) + .run() } fn propose_sc_deploy_from_source( &mut self, amount: u64, - source: Address, + source: TestSCAddress, code_metadata: CodeMetadata, arguments: MultiValueVec>, ) -> usize { self.world - .sc_call_get_result(ScCallStep::new().from(PROPOSER_ADDRESS_EXPR).call( - self.multisig_contract.propose_sc_deploy_from_source( - amount, - source, - code_metadata, - arguments, - ), - )) + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_sc_deploy_from_source(amount, source, code_metadata, arguments) + .returns(ReturnsResult) + .run() } fn propose_sc_upgrade_from_source( &mut self, - sc_address: Address, + sc_address: TestSCAddress, amount: u64, - source: Address, + source: TestSCAddress, code_metadata: CodeMetadata, arguments: MultiValueVec>, ) -> usize { self.world - .sc_call_get_result(ScCallStep::new().from(PROPOSER_ADDRESS_EXPR).call( - self.multisig_contract.propose_sc_upgrade_from_source( - sc_address, - amount, - source, - code_metadata, - arguments, - ), - )) + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_sc_upgrade_from_source(sc_address, amount, source, code_metadata, arguments) + .returns(ReturnsResult) + .run() } fn perform(&mut self, action_id: usize) { - self.world.sc_call( - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .call(self.multisig_contract.perform_action_endpoint(action_id)), - ); + self.world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .perform_action_endpoint(action_id) + .run(); } fn perform_and_expect_err(&mut self, action_id: usize, err_message: &str) { - self.world.sc_call( - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .call(self.multisig_contract.perform_action_endpoint(action_id)) - .expect(TxExpect::user_error("str:".to_string() + err_message)), - ); + self.world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .perform_action_endpoint(action_id) + .with_result(ExpectError(4, err_message)) + .run(); } fn sign(&mut self, action_id: usize) { - self.world.sc_call( - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .call(self.multisig_contract.sign(action_id)), - ); + self.world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .sign(action_id) + .run(); } - fn expect_user_role(&mut self, user: &Address, expected_user_role: UserRole) { - self.world.sc_query( - ScQueryStep::new() - .call(self.multisig_contract.user_role(user.clone())) - .expect_value(expected_user_role), - ); + fn expect_user_role( + &mut self, + user: TestAddress, + expected_user_role: multisig_proxy::UserRole, + ) { + self.world + .query() + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .user_role(user) + .returns(ExpectValue(expected_user_role)) + .run(); } } @@ -266,28 +249,27 @@ fn test_add_board_member() { let mut state = MultisigTestState::new(); state.deploy_multisig_contract(); - const NEW_BOARD_MEMBER_ADDRESS_EXPR: &str = "address:new-board-member"; - let new_board_member_address = AddressValue::from(NEW_BOARD_MEMBER_ADDRESS_EXPR).to_address(); + let new_board_member_expr: TestAddress = TestAddress::new("new-board-member"); - state.world.set_state_step( - SetStateStep::new().put_account(NEW_BOARD_MEMBER_ADDRESS_EXPR, Account::new().nonce(1)), - ); + state.world.account(new_board_member_expr).nonce(1); - state.expect_user_role(&new_board_member_address, UserRole::None); + state.expect_user_role(new_board_member_expr, multisig_proxy::UserRole::None); - let action_id = state.propose_add_board_member(new_board_member_address.clone()); + let action_id = state.propose_add_board_member(new_board_member_expr); state.sign(action_id); state.perform(action_id); - state.expect_user_role(&new_board_member_address, UserRole::BoardMember); - state.world.sc_query( - ScQueryStep::new() - .call(state.multisig_contract.get_all_board_members()) - .expect_value(MultiValueVec::
::from(vec![ - state.board_member_address.clone(), - new_board_member_address.clone(), - ])), - ); + let expected_value = MultiValueVec::from(vec![BOARD_MEMBER_ADDRESS, new_board_member_expr]); + + state.expect_user_role(new_board_member_expr, multisig_proxy::UserRole::BoardMember); + state + .world + .query() + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .get_all_board_members() + .returns(ExpectValue(expected_value)) + .run() } #[test] @@ -295,28 +277,30 @@ fn test_add_proposer() { let mut state = MultisigTestState::new(); state.deploy_multisig_contract(); - const NEW_PROPOSER_ADDRESS_EXPR: &str = "address:new-proposer"; - let new_proposer_address = AddressValue::from(NEW_PROPOSER_ADDRESS_EXPR).to_address(); + let new_proposer_address_expr = TestAddress::new("new-proposer"); - state.world.set_state_step( - SetStateStep::new().put_account(NEW_PROPOSER_ADDRESS_EXPR, Account::new().nonce(1)), - ); + state.world.account(new_proposer_address_expr).nonce(1); - state.expect_user_role(&new_proposer_address, UserRole::None); + state.expect_user_role(new_proposer_address_expr, multisig_proxy::UserRole::None); - let action_id = state.propose_add_proposer(new_proposer_address.clone()); + let action_id = state.propose_add_proposer(new_proposer_address_expr); state.sign(action_id); state.perform(action_id); - state.expect_user_role(&new_proposer_address, UserRole::Proposer); - state.world.sc_query( - ScQueryStep::new() - .call(state.multisig_contract.get_all_proposers()) - .expect_value(MultiValueVec::
::from(vec![ - state.proposer_address.clone(), - new_proposer_address.clone(), - ])), + state.expect_user_role( + new_proposer_address_expr, + multisig_proxy::UserRole::Proposer, ); + + let expected_value = MultiValueVec::from(vec![PROPOSER_ADDRESS, new_proposer_address_expr]); + state + .world + .query() + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .get_all_proposers() + .returns(ExpectValue(expected_value)) + .run(); } #[test] @@ -324,18 +308,21 @@ fn test_remove_proposer() { let mut state = MultisigTestState::new(); state.deploy_multisig_contract(); - state.expect_user_role(&state.proposer_address.clone(), UserRole::Proposer); + state.expect_user_role(PROPOSER_ADDRESS, multisig_proxy::UserRole::Proposer); - let action_id = state.propose_remove_user(state.proposer_address.clone()); + let action_id = state.propose_remove_user(PROPOSER_ADDRESS); state.sign(action_id); state.perform(action_id); - state.expect_user_role(&state.proposer_address.clone(), UserRole::None); - state.world.sc_query( - ScQueryStep::new() - .call(state.multisig_contract.get_all_proposers()) - .expect_value(MultiValueVec::
::new()), - ); + state.expect_user_role(PROPOSER_ADDRESS, multisig_proxy::UserRole::None); + state + .world + .query() + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .get_all_proposers() + .returns(ExpectValue(MultiValueVec::
::new())) + .run(); } #[test] @@ -343,7 +330,7 @@ fn test_try_remove_all_board_members() { let mut state = MultisigTestState::new(); state.deploy_multisig_contract(); - let action_id = state.propose_remove_user(state.board_member_address.clone()); + let action_id = state.propose_remove_user(BOARD_MEMBER_ADDRESS); state.sign(action_id); state.perform_and_expect_err(action_id, "quorum cannot exceed board size") } @@ -360,45 +347,55 @@ fn test_change_quorum() { state.perform_and_expect_err(action_id, "quorum cannot exceed board size"); // try discard before unsigning - state.world.sc_call( - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .call(state.multisig_contract.discard_action(action_id)) - .expect(TxExpect::user_error( - "str:cannot discard action with valid signatures", - )), - ); + state + .world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .discard_action(action_id) + .with_result(ExpectError( + 4, + "cannot discard action with valid signatures", + )) + .run(); // unsign and discard action - state.world.sc_call( - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .call(state.multisig_contract.unsign(action_id)), - ); + state + .world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .unsign(action_id) + .run(); - state.world.sc_call( - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .call(state.multisig_contract.discard_action(action_id)), - ); + state + .world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .discard_action(action_id) + .run(); // try sign discarded action - state.world.sc_call( - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .call(state.multisig_contract.sign(action_id)) - .expect(TxExpect::user_error("str:action does not exist")), - ); + state + .world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .sign(action_id) + .with_result(ExpectError(4, "action does not exist")) + .run(); // add another board member - const NEW_BOARD_MEMBER_ADDRESS_EXPR: &str = "address:new-board-member"; - let new_board_member_address = AddressValue::from(NEW_BOARD_MEMBER_ADDRESS_EXPR).to_address(); + let new_board_member_address_expr = TestAddress::new("new-board-member"); - state.world.set_state_step( - SetStateStep::new().put_account(NEW_BOARD_MEMBER_ADDRESS_EXPR, Account::new().nonce(1)), - ); + state.world.account(new_board_member_address_expr).nonce(1); - let action_id = state.propose_add_board_member(new_board_member_address); + let action_id = state.propose_add_board_member(new_board_member_address_expr); state.sign(action_id); state.perform(action_id); @@ -413,57 +410,51 @@ fn test_transfer_execute_to_user() { let mut state = MultisigTestState::new(); state.deploy_multisig_contract(); - const NEW_USER_ADDRESS_EXPR: &str = "address:new-user"; - state.world.set_state_step( - SetStateStep::new().put_account(NEW_USER_ADDRESS_EXPR, Account::new().nonce(1)), - ); + let new_user_address_expr = TestAddress::new("new-user"); + state.world.account(new_user_address_expr).nonce(1); - const AMOUNT: &str = "100"; + let amount: u64 = 100; - state.world.sc_call( - ScCallStep::new() - .from(PROPOSER_ADDRESS_EXPR) - .egld_value(AMOUNT) - .call(state.multisig_contract.deposit()), - ); + state + .world + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .deposit() + .egld(amount) + .run(); - state.world.check_state_step( - CheckStateStep::new() - .put_account(MULTISIG_ADDRESS_EXPR, CheckAccount::new().balance(AMOUNT)), - ); + state.world.check_account(MULTISIG_ADDRESS).balance(amount); // failed attempt - let new_user_address = AddressValue::from(NEW_USER_ADDRESS_EXPR).to_address(); - - state.world.sc_call( - ScCallStep::new() - .from(PROPOSER_ADDRESS_EXPR) - .call(state.multisig_contract.propose_transfer_execute( - new_user_address.clone(), - 0u64, - FunctionCall::empty(), - )) - .expect(TxExpect::user_error("str:proposed action has no effect")), - ); + state + .world + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_transfer_execute(new_user_address_expr, 0u64, FunctionCall::empty()) + .with_result(ExpectError(4, "proposed action has no effect")) + .run(); // propose - let action_id = - state - .world - .sc_call_get_result(ScCallStep::new().from(PROPOSER_ADDRESS_EXPR).call( - state.multisig_contract.propose_transfer_execute( - new_user_address, - AMOUNT.parse::().unwrap(), - FunctionCall::empty(), - ), - )); + let action_id = state + .world + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .propose_transfer_execute(new_user_address_expr, amount, FunctionCall::empty()) + .returns(ReturnsResult) + .run(); state.sign(action_id); state.perform(action_id); - state.world.check_state_step( - CheckStateStep::new() - .put_account(NEW_USER_ADDRESS_EXPR, CheckAccount::new().balance(AMOUNT)), - ); + state + .world + .check_account(new_user_address_expr) + .balance(amount); } #[test] @@ -471,17 +462,25 @@ fn test_transfer_execute_sc_all() { let mut state = MultisigTestState::new(); state.deploy_multisig_contract().deploy_adder_contract(); - let adder_call = state.adder_contract.add(5u64); + let adder_call = state + .world + .tx() + .typed(adder_proxy::AdderProxy) + .add(5u64) + .into_function_call(); - let action_id = state.propose_transfer_execute(state.adder_address.clone(), 0u64, adder_call); + let action_id = state.propose_transfer_execute(ADDER_ADDRESS, 0u64, adder_call); state.sign(action_id); state.perform(action_id); - state.world.sc_query( - ScQueryStep::new() - .call(state.adder_contract.sum()) - .expect_value(SingleValue::from(BigUint::from(10u64))), - ); + state + .world + .query() + .to(ADDER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .sum() + .with_result(ExpectValue(BigUint::from(10u64))) + .run(); } #[test] @@ -489,17 +488,25 @@ fn test_async_call_to_sc() { let mut state = MultisigTestState::new(); state.deploy_multisig_contract().deploy_adder_contract(); - let adder_call = state.adder_contract.add(5u64); + let adder_call = state + .world + .tx() + .typed(adder_proxy::AdderProxy) + .add(5u64) + .into_function_call(); - let action_id = state.propose_async_call(state.adder_address.clone(), 0u64, adder_call); + let action_id = state.propose_async_call(ADDER_ADDRESS, 0u64, adder_call); state.sign(action_id); state.perform(action_id); - state.world.sc_query( - ScQueryStep::new() - .call(state.adder_contract.sum()) - .expect_value(SingleValue::from(BigUint::from(10u64))), - ); + state + .world + .query() + .to(ADDER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .sum() + .returns(ExpectValue(10u64)) + .run(); } #[test] @@ -507,59 +514,63 @@ fn test_deploy_and_upgrade_from_source() { let mut state = MultisigTestState::new(); state.deploy_multisig_contract().deploy_adder_contract(); - const NEW_ADDER_ADDRESS_EXPR: &str = "sc:new-adder"; - state.world.set_state_step(SetStateStep::new().new_address( - MULTISIG_ADDRESS_EXPR, - 0, - NEW_ADDER_ADDRESS_EXPR, - )); + let new_adder_address_expr = TestSCAddress::new("new-adder"); - let new_adder_address = AddressValue::from(NEW_ADDER_ADDRESS_EXPR).to_address(); + state + .world + .new_address(MULTISIG_ADDRESS, 0, new_adder_address_expr); let action_id = state.propose_sc_deploy_from_source( 0u64, - state.adder_address.clone(), + ADDER_ADDRESS, CodeMetadata::all(), MultiValueVec::from([top_encode_to_vec_u8_or_panic(&5u64)]), ); state.sign(action_id); - state.world.sc_call( - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .call(state.multisig_contract.perform_action_endpoint(action_id)) - .expect_value(OptionalValue::Some(new_adder_address.clone())), - ); - - let adder_call = state.adder_contract.add(5u64); + state + .world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .typed(multisig_proxy::MultisigProxy) + .perform_action_endpoint(action_id) + .returns(ExpectValue(OptionalValue::Some( + new_adder_address_expr.to_address(), + ))) + .run(); + + let adder_call = state + .world + .tx() + .to(ADDER_ADDRESS) + .typed(adder_proxy::AdderProxy) + .add(5u64) + .into_function_call(); - let action_id = state.propose_transfer_execute(new_adder_address, 0u64, adder_call); + let action_id = state.propose_transfer_execute(new_adder_address_expr, 0u64, adder_call); state.sign(action_id); state.perform(action_id); - let mut new_adder_contract = AdderContract::new(NEW_ADDER_ADDRESS_EXPR); - - state.world.sc_query( - ScQueryStep::new() - .call(new_adder_contract.sum()) - .expect_value(SingleValue::from(BigUint::from(10u64))), - ); - - const FACTORIAL_ADDRESS_EXPR: &str = "sc:factorial"; - const FACTORIAL_PATH_EXPR: &str = "mxsc:test-contracts/factorial.mxsc.json"; + state + .world + .query() + .to(new_adder_address_expr) + .typed(adder_proxy::AdderProxy) + .sum() + .returns(ExpectValue(BigUint::from(10u64))) + .run(); - let factorial_code = state.world.code_expression(FACTORIAL_PATH_EXPR); - let factorial_address = AddressValue::from(FACTORIAL_ADDRESS_EXPR).to_address(); + let factorial_address: TestSCAddress = TestSCAddress::new("factorial"); + let factorial_path: MxscPath = MxscPath::new("test-contracts/factorial.mxsc.json"); state .world - .register_contract(FACTORIAL_PATH_EXPR, factorial::ContractBuilder); - state.world.set_state_step(SetStateStep::new().put_account( - FACTORIAL_ADDRESS_EXPR, - Account::new().nonce(1).code(factorial_code.clone()), - )); + .register_contract(factorial_path, factorial::ContractBuilder); + + state.world.account(factorial_address).code(factorial_path); let action_id = state.propose_sc_upgrade_from_source( - state.adder_address.clone(), + ADDER_ADDRESS, 0u64, factorial_address, CodeMetadata::all(), @@ -568,8 +579,8 @@ fn test_deploy_and_upgrade_from_source() { state.sign(action_id); state.perform(action_id); - state.world.check_state_step( - CheckStateStep::new() - .put_account(ADDER_ADDRESS_EXPR, CheckAccount::new().code(factorial_code)), - ); + state + .world + .check_account(ADDER_ADDRESS) + .code(factorial_path); } diff --git a/contracts/examples/multisig/tests/multisig_scenario_rs_test.rs b/contracts/examples/multisig/tests/multisig_scenario_rs_test.rs index 8a606bffd8..67baad4ca2 100644 --- a/contracts/examples/multisig/tests/multisig_scenario_rs_test.rs +++ b/contracts/examples/multisig/tests/multisig_scenario_rs_test.rs @@ -4,7 +4,6 @@ const WEGLD_SWAP_EXPR: &str = "0x0061736d0100000001661160000060017f0060027f7f017 fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/multisig"); blockchain.register_partial_contract::( "mxsc:output/multisig.mxsc.json", diff --git a/contracts/examples/multisig/tests/multisig_whitebox_test.rs b/contracts/examples/multisig/tests/multisig_whitebox_test.rs index 227c012bc7..904a03c7e0 100644 --- a/contracts/examples/multisig/tests/multisig_whitebox_test.rs +++ b/contracts/examples/multisig/tests/multisig_whitebox_test.rs @@ -1,5 +1,6 @@ #![allow(unused)] +use multiversx_sc_scenario::imports::*; use std::borrow::Borrow; use adder::Adder; @@ -8,26 +9,6 @@ use multisig::{ multisig_perform::MultisigPerformModule, multisig_propose::MultisigProposeModule, user_role::UserRole, Multisig, }; -use multiversx_sc::{ - api::ManagedTypeApi, - codec::multi_types::OptionalValue, - storage::mappers::SingleValue, - types::{ - Address, BigUint, BoxedBytes, CodeMetadata, FunctionCall, ManagedAddress, ManagedBuffer, - ManagedVec, - }, -}; -use multiversx_sc_scenario::{ - managed_address, managed_biguint, - multiversx_chain_vm::types::VMAddress, - rust_biguint, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, ScDeployStep, ScQueryStep, - SetStateStep, TxExpect, TypedScQuery, - }, - testing_framework::TxResult, - DebugApi, ScenarioWorld, WhiteboxContract, -}; const OWNER_ADDRESS_EXPR: &str = "address:owner"; const PROPOSER_ADDRESS_EXPR: &str = "address:proposer"; @@ -70,7 +51,6 @@ pub struct CallActionDataRaw { fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/multisig"); blockchain.register_contract(MULTISIG_PATH_EXPR, multisig::ContractBuilder); blockchain diff --git a/contracts/examples/multisig/wasm-multisig-full/Cargo.lock b/contracts/examples/multisig/wasm-multisig-full/Cargo.lock index 329757cdb6..ddb406c3f0 100644 --- a/contracts/examples/multisig/wasm-multisig-full/Cargo.lock +++ b/contracts/examples/multisig/wasm-multisig-full/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -56,26 +56,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +87,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,14 +98,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/multisig/wasm-multisig-full/Cargo.toml b/contracts/examples/multisig/wasm-multisig-full/Cargo.toml index 64faae5032..eaa6458c9a 100644 --- a/contracts/examples/multisig/wasm-multisig-full/Cargo.toml +++ b/contracts/examples/multisig/wasm-multisig-full/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.multisig] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/multisig/wasm-multisig-full/src/lib.rs b/contracts/examples/multisig/wasm-multisig-full/src/lib.rs index b3f9a29bee..c62c8ef62b 100644 --- a/contracts/examples/multisig/wasm-multisig-full/src/lib.rs +++ b/contracts/examples/multisig/wasm-multisig-full/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 29 +// Upgrade: 1 +// Endpoints: 28 // Async Callback: 1 // Total number of exported functions: 31 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/multisig/wasm-multisig-view/Cargo.lock b/contracts/examples/multisig/wasm-multisig-view/Cargo.lock index 9ec7d5be1e..719bace565 100644 --- a/contracts/examples/multisig/wasm-multisig-view/Cargo.lock +++ b/contracts/examples/multisig/wasm-multisig-view/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -56,26 +56,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +87,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,14 +98,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/multisig/wasm-multisig-view/Cargo.toml b/contracts/examples/multisig/wasm-multisig-view/Cargo.toml index ec1c6aba87..5adc37f1d0 100644 --- a/contracts/examples/multisig/wasm-multisig-view/Cargo.toml +++ b/contracts/examples/multisig/wasm-multisig-view/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.multisig] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/multisig/wasm-multisig-view/src/lib.rs b/contracts/examples/multisig/wasm-multisig-view/src/lib.rs index c01d319c88..de4e6479d6 100644 --- a/contracts/examples/multisig/wasm-multisig-view/src/lib.rs +++ b/contracts/examples/multisig/wasm-multisig-view/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/multisig/wasm/Cargo.lock b/contracts/examples/multisig/wasm/Cargo.lock index a1f0090ffe..c06110a7ae 100755 --- a/contracts/examples/multisig/wasm/Cargo.lock +++ b/contracts/examples/multisig/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -56,26 +56,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +87,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,14 +98,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/multisig/wasm/Cargo.toml b/contracts/examples/multisig/wasm/Cargo.toml index de21ada11d..0b48d9b3a0 100644 --- a/contracts/examples/multisig/wasm/Cargo.toml +++ b/contracts/examples/multisig/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.multisig] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/multisig/wasm/src/lib.rs b/contracts/examples/multisig/wasm/src/lib.rs index 0bb7178ce4..2d7e536d14 100644 --- a/contracts/examples/multisig/wasm/src/lib.rs +++ b/contracts/examples/multisig/wasm/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 21 +// Upgrade: 1 +// Endpoints: 20 // Async Callback: 1 // Total number of exported functions: 23 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/multisig/wegld_proxy.rs b/contracts/examples/multisig/wegld_proxy.rs new file mode 100644 index 0000000000..404831a1bd --- /dev/null +++ b/contracts/examples/multisig/wegld_proxy.rs @@ -0,0 +1,129 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct EgldEsdtSwapProxy; + +impl TxProxyTrait for EgldEsdtSwapProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = EgldEsdtSwapProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + EgldEsdtSwapProxyMethods { wrapped_tx: tx } + } +} + +pub struct EgldEsdtSwapProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl EgldEsdtSwapProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + >( + self, + wrapped_egld_token_id: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&wrapped_egld_token_id) + .original_result() + } +} + +#[rustfmt::skip] +impl EgldEsdtSwapProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn wrap_egld( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .raw_call("wrapEgld") + .original_result() + } + + pub fn unwrap_egld( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("unwrapEgld") + .original_result() + } + + pub fn get_locked_egld_balance( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getLockedEgldBalance") + .original_result() + } + + pub fn wrapped_egld_token_id( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getWrappedEgldTokenId") + .original_result() + } + + pub fn pause_endpoint( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("pause") + .original_result() + } + + pub fn unpause_endpoint( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unpause") + .original_result() + } + + pub fn paused_status( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isPaused") + .original_result() + } +} diff --git a/contracts/examples/nft-minter/Cargo.toml b/contracts/examples/nft-minter/Cargo.toml index 9bcab9f7cc..e7d4b14ceb 100644 --- a/contracts/examples/nft-minter/Cargo.toml +++ b/contracts/examples/nft-minter/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/nft-minter/meta/Cargo.toml b/contracts/examples/nft-minter/meta/Cargo.toml index 9193979931..2c48a69050 100644 --- a/contracts/examples/nft-minter/meta/Cargo.toml +++ b/contracts/examples/nft-minter/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.nft-minter] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/nft-minter/meta/src/main.rs b/contracts/examples/nft-minter/meta/src/main.rs index 188f37dfb7..db7c559131 100644 --- a/contracts/examples/nft-minter/meta/src/main.rs +++ b/contracts/examples/nft-minter/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/nft-minter/src/lib.rs b/contracts/examples/nft-minter/src/lib.rs index 5f0a8b3f01..4148f368c2 100644 --- a/contracts/examples/nft-minter/src/lib.rs +++ b/contracts/examples/nft-minter/src/lib.rs @@ -2,6 +2,7 @@ use multiversx_sc::{derive_imports::*, imports::*}; +pub mod nft_marketplace_proxy; mod nft_module; #[derive(TypeAbi, TopEncode, TopDecode)] @@ -72,28 +73,10 @@ pub trait NftMinter: nft_module::NftModule { token_nonce: u64, ) { let caller = self.blockchain().get_caller(); - self.marketplace_proxy(marketplace_address) + self.tx() + .to(&marketplace_address) + .typed(nft_marketplace_proxy::NftMarketplaceProxy) .claim_tokens(token_id, token_nonce, caller) - .async_call() - .call_and_exit() - } - - #[proxy] - fn marketplace_proxy( - &self, - sc_address: ManagedAddress, - ) -> nft_marketplace_proxy::Proxy; -} - -mod nft_marketplace_proxy { - #[multiversx_sc::proxy] - pub trait NftMarketplace { - #[endpoint(claimTokens)] - fn claim_tokens( - &self, - token_id: TokenIdentifier, - token_nonce: u64, - claim_destination: ManagedAddress, - ); + .async_call_and_exit(); } } diff --git a/contracts/examples/nft-minter/src/nft_marketplace_proxy.rs b/contracts/examples/nft-minter/src/nft_marketplace_proxy.rs new file mode 100644 index 0000000000..84a291bbe4 --- /dev/null +++ b/contracts/examples/nft-minter/src/nft_marketplace_proxy.rs @@ -0,0 +1,55 @@ +use multiversx_sc::proxy_imports::*; + +pub struct NftMarketplaceProxy; + +impl TxProxyTrait for NftMarketplaceProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = NftMarketplaceProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + NftMarketplaceProxyMethods { wrapped_tx: tx } + } +} + +pub struct NftMarketplaceProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl NftMarketplaceProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn claim_tokens< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + token_id: Arg0, + token_nonce: Arg1, + claim_destination: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("claimTokens") + .argument(&token_id) + .argument(&token_nonce) + .argument(&claim_destination) + .original_result() + } +} diff --git a/contracts/examples/nft-minter/src/nft_module.rs b/contracts/examples/nft-minter/src/nft_module.rs index 2b9b73523c..da97c0d171 100644 --- a/contracts/examples/nft-minter/src/nft_module.rs +++ b/contracts/examples/nft-minter/src/nft_module.rs @@ -37,9 +37,8 @@ pub trait NftModule { can_add_special_roles: true, }, ) - .async_call() .with_callback(self.callbacks().issue_callback()) - .call_and_exit() + .async_call_and_exit() } #[only_owner] @@ -54,8 +53,7 @@ pub trait NftModule { &self.nft_token_id().get(), [EsdtLocalRole::NftCreate][..].iter().cloned(), ) - .async_call() - .call_and_exit() + .async_call_and_exit() } // endpoints @@ -88,21 +86,14 @@ pub trait NftModule { self.price_tag(nft_nonce).clear(); let nft_token_id = self.nft_token_id().get(); - let caller = self.blockchain().get_caller(); - self.send().direct_esdt( - &caller, - &nft_token_id, - nft_nonce, - &BigUint::from(NFT_AMOUNT), - ); + + self.tx() + .to(ToCaller) + .single_esdt(&nft_token_id, nft_nonce, &BigUint::from(NFT_AMOUNT)) + .transfer(); let owner = self.blockchain().get_owner_address(); - self.send().direct( - &owner, - &payment.token_identifier, - payment.token_nonce, - &payment.amount, - ); + self.tx().to(owner).payment(payment).transfer(); } // views @@ -135,11 +126,9 @@ pub trait NftModule { self.nft_token_id().set(&token_id.unwrap_esdt()); }, ManagedAsyncCallResult::Err(_) => { - let caller = self.blockchain().get_owner_address(); let returned = self.call_value().egld_or_single_esdt(); if returned.token_identifier.is_egld() && returned.amount > 0 { - self.send() - .direct(&caller, &returned.token_identifier, 0, &returned.amount); + self.tx().to(ToCaller).egld(returned.amount).transfer(); } }, } diff --git a/contracts/examples/nft-minter/tests/nft_minter_scenario_rs_test.rs b/contracts/examples/nft-minter/tests/nft_minter_scenario_rs_test.rs index db79559f43..1e8c9a3f43 100644 --- a/contracts/examples/nft-minter/tests/nft_minter_scenario_rs_test.rs +++ b/contracts/examples/nft-minter/tests/nft_minter_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/nft-minter"); blockchain.register_contract( "mxsc:output/nft-minter.mxsc.json", diff --git a/contracts/examples/nft-minter/wasm/Cargo.lock b/contracts/examples/nft-minter/wasm/Cargo.lock index 8137f69e11..7c29b164a0 100644 --- a/contracts/examples/nft-minter/wasm/Cargo.lock +++ b/contracts/examples/nft-minter/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/nft-minter/wasm/Cargo.toml b/contracts/examples/nft-minter/wasm/Cargo.toml index d44e299f52..d6e60df991 100644 --- a/contracts/examples/nft-minter/wasm/Cargo.toml +++ b/contracts/examples/nft-minter/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.nft-minter] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/nft-minter/wasm/src/lib.rs b/contracts/examples/nft-minter/wasm/src/lib.rs index aab639db54..daef60b06e 100644 --- a/contracts/examples/nft-minter/wasm/src/lib.rs +++ b/contracts/examples/nft-minter/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 8 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/nft-storage-prepay/Cargo.toml b/contracts/examples/nft-storage-prepay/Cargo.toml index c40c8096e5..4777f46e2a 100644 --- a/contracts/examples/nft-storage-prepay/Cargo.toml +++ b/contracts/examples/nft-storage-prepay/Cargo.toml @@ -10,9 +10,9 @@ path = "src/nft_storage_prepay.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/nft-storage-prepay/meta/Cargo.toml b/contracts/examples/nft-storage-prepay/meta/Cargo.toml index 2ecb100f40..e158c72588 100644 --- a/contracts/examples/nft-storage-prepay/meta/Cargo.toml +++ b/contracts/examples/nft-storage-prepay/meta/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nft-storage-prepay-meta" version = "0.0.0" -authors = [ "Dorin Iancu ",] +authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -10,7 +10,7 @@ publish = false [dependencies.nft-storage-prepay] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/nft-storage-prepay/meta/src/main.rs b/contracts/examples/nft-storage-prepay/meta/src/main.rs index 4624ae5199..76e9d39bcf 100644 --- a/contracts/examples/nft-storage-prepay/meta/src/main.rs +++ b/contracts/examples/nft-storage-prepay/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs b/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs index f21dfcb61b..7e1c6115d3 100644 --- a/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs +++ b/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs @@ -42,7 +42,7 @@ pub trait NftStoragePrepay { self.total_reserved().clear(); let owner = self.blockchain().get_caller(); - self.send().direct_egld(&owner, &total_reserved); + self.tx().to(&owner).egld(&total_reserved).transfer(); } // endpoints @@ -71,7 +71,7 @@ pub trait NftStoragePrepay { user_deposit -= &amount; self.deposit(&caller).set(&user_deposit); - self.send().direct_egld(&caller, &amount); + self.tx().to(&caller).egld(&amount).transfer(); } // views diff --git a/contracts/examples/nft-storage-prepay/wasm/Cargo.lock b/contracts/examples/nft-storage-prepay/wasm/Cargo.lock index 9618be73c9..e70d37fe32 100755 --- a/contracts/examples/nft-storage-prepay/wasm/Cargo.lock +++ b/contracts/examples/nft-storage-prepay/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/nft-storage-prepay/wasm/Cargo.toml b/contracts/examples/nft-storage-prepay/wasm/Cargo.toml index 2d0fa1f340..11c08b1fa7 100644 --- a/contracts/examples/nft-storage-prepay/wasm/Cargo.toml +++ b/contracts/examples/nft-storage-prepay/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.nft-storage-prepay] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/nft-storage-prepay/wasm/src/lib.rs b/contracts/examples/nft-storage-prepay/wasm/src/lib.rs index 4f9e57e282..cbcfccb60f 100644 --- a/contracts/examples/nft-storage-prepay/wasm/src/lib.rs +++ b/contracts/examples/nft-storage-prepay/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/nft-subscription/Cargo.toml b/contracts/examples/nft-subscription/Cargo.toml index c3a15ca04e..797f618a9f 100644 --- a/contracts/examples/nft-subscription/Cargo.toml +++ b/contracts/examples/nft-subscription/Cargo.toml @@ -9,13 +9,13 @@ publish = false path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/nft-subscription/meta/Cargo.toml b/contracts/examples/nft-subscription/meta/Cargo.toml index ebb5c97716..c8df6df7d8 100644 --- a/contracts/examples/nft-subscription/meta/Cargo.toml +++ b/contracts/examples/nft-subscription/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.nft-subscription] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/nft-subscription/meta/src/main.rs b/contracts/examples/nft-subscription/meta/src/main.rs index 27c3b0f0ad..0efbdfc0de 100644 --- a/contracts/examples/nft-subscription/meta/src/main.rs +++ b/contracts/examples/nft-subscription/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/nft-subscription/src/lib.rs b/contracts/examples/nft-subscription/src/lib.rs index d291eaf212..7b0b63096e 100644 --- a/contracts/examples/nft-subscription/src/lib.rs +++ b/contracts/examples/nft-subscription/src/lib.rs @@ -35,12 +35,15 @@ pub trait NftSubscription: ManagedBuffer::from(b"common"), &ManagedVec::new(), ); - self.send().direct_esdt( - &self.blockchain().get_caller(), - self.token_id().get_token_id_ref(), - nonce, - &BigUint::from(1u8), - ); + + self.tx() + .to(ToCaller) + .single_esdt( + self.token_id().get_token_id_ref(), + nonce, + &BigUint::from(1u8), + ) + .transfer(); } #[payable("*")] @@ -48,12 +51,10 @@ pub trait NftSubscription: fn update_attributes(&self, attributes: ManagedBuffer) { let (id, nonce, _) = self.call_value().single_esdt().into_tuple(); self.update_subscription_attributes::(&id, nonce, attributes); - self.send().direct_esdt( - &self.blockchain().get_caller(), - &id, - nonce, - &BigUint::from(1u8), - ); + self.tx() + .to(ToCaller) + .single_esdt(&id, nonce, &BigUint::from(1u8)) + .transfer(); } #[payable("*")] @@ -61,12 +62,10 @@ pub trait NftSubscription: fn renew(&self, duration: u64) { let (id, nonce, _) = self.call_value().single_esdt().into_tuple(); self.renew_subscription::(&id, nonce, duration); - self.send().direct_esdt( - &self.blockchain().get_caller(), - &id, - nonce, - &BigUint::from(1u8), - ); + self.tx() + .to(ToCaller) + .single_esdt(&id, nonce, &BigUint::from(1u8)) + .transfer(); } #[payable("*")] @@ -74,12 +73,11 @@ pub trait NftSubscription: fn cancel(&self) { let (id, nonce, _) = self.call_value().single_esdt().into_tuple(); self.cancel_subscription::(&id, nonce); - self.send().direct_esdt( - &self.blockchain().get_caller(), - &id, - nonce, - &BigUint::from(1u8), - ); + + self.tx() + .to(ToCaller) + .single_esdt(&id, nonce, &BigUint::from(1u8)) + .transfer(); } #[storage_mapper("tokenId")] diff --git a/contracts/examples/nft-subscription/tests/nft_subscription_scenario_rs_test.rs b/contracts/examples/nft-subscription/tests/nft_subscription_scenario_rs_test.rs index 4340f468a7..c36191ef22 100644 --- a/contracts/examples/nft-subscription/tests/nft_subscription_scenario_rs_test.rs +++ b/contracts/examples/nft-subscription/tests/nft_subscription_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/nft-subscription"); blockchain.register_contract( "mxsc:output/nft-subscription.mxsc.json", diff --git a/contracts/examples/nft-subscription/wasm/Cargo.lock b/contracts/examples/nft-subscription/wasm/Cargo.lock index 53bd528197..f2144f6237 100644 --- a/contracts/examples/nft-subscription/wasm/Cargo.lock +++ b/contracts/examples/nft-subscription/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,14 +82,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/nft-subscription/wasm/Cargo.toml b/contracts/examples/nft-subscription/wasm/Cargo.toml index 0469136d02..f5fe109489 100644 --- a/contracts/examples/nft-subscription/wasm/Cargo.toml +++ b/contracts/examples/nft-subscription/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.nft-subscription] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/nft-subscription/wasm/src/lib.rs b/contracts/examples/nft-subscription/wasm/src/lib.rs index 2c95afe219..07b9b6e288 100644 --- a/contracts/examples/nft-subscription/wasm/src/lib.rs +++ b/contracts/examples/nft-subscription/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 7 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/order-book/factory/Cargo.toml b/contracts/examples/order-book/factory/Cargo.toml index e78a41e300..e77701abd6 100644 --- a/contracts/examples/order-book/factory/Cargo.toml +++ b/contracts/examples/order-book/factory/Cargo.toml @@ -8,10 +8,10 @@ publish = false path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/examples/order-book/factory/meta/Cargo.toml b/contracts/examples/order-book/factory/meta/Cargo.toml index c81b977517..269cf88d2d 100644 --- a/contracts/examples/order-book/factory/meta/Cargo.toml +++ b/contracts/examples/order-book/factory/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.order-book-factory] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/order-book/factory/meta/src/main.rs b/contracts/examples/order-book/factory/meta/src/main.rs index c085aa4118..d0e77f9c9e 100644 --- a/contracts/examples/order-book/factory/meta/src/main.rs +++ b/contracts/examples/order-book/factory/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/order-book/factory/src/lib.rs b/contracts/examples/order-book/factory/src/lib.rs index cac1192361..fb83863ae3 100644 --- a/contracts/examples/order-book/factory/src/lib.rs +++ b/contracts/examples/order-book/factory/src/lib.rs @@ -23,13 +23,19 @@ pub trait Factory { arguments.push_arg(&token_id_pair.first_token_id); arguments.push_arg(&token_id_pair.second_token_id); - let (pair_address, _) = self.send_raw().deploy_from_source_contract( - self.blockchain().get_gas_left(), - &BigUint::zero(), - &self.pair_template_address().get(), - CodeMetadata::DEFAULT, - &arguments, - ); + let gas_left = self.blockchain().get_gas_left(); + let source = self.pair_template_address().get(); + + let pair_address = self + .tx() + .gas(gas_left) + .raw_deploy() + .arguments_raw(arguments) + .from_source(source) + .code_metadata(CodeMetadata::DEFAULT) + .returns(ReturnsNewManagedAddress) + .sync_call(); + self.pairs().insert(token_id_pair, pair_address.clone()); pair_address diff --git a/contracts/examples/order-book/factory/wasm/Cargo.lock b/contracts/examples/order-book/factory/wasm/Cargo.lock index c5b0d6fa16..3e773acdf3 100644 --- a/contracts/examples/order-book/factory/wasm/Cargo.lock +++ b/contracts/examples/order-book/factory/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,9 +98,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -120,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/order-book/factory/wasm/Cargo.toml b/contracts/examples/order-book/factory/wasm/Cargo.toml index 491a30d13c..78f1e1d508 100644 --- a/contracts/examples/order-book/factory/wasm/Cargo.toml +++ b/contracts/examples/order-book/factory/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.order-book-factory] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/order-book/factory/wasm/src/lib.rs b/contracts/examples/order-book/factory/wasm/src/lib.rs index 97a9ff166d..be215e6f41 100644 --- a/contracts/examples/order-book/factory/wasm/src/lib.rs +++ b/contracts/examples/order-book/factory/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/order-book/pair/Cargo.toml b/contracts/examples/order-book/pair/Cargo.toml index db90006821..f416341dc0 100644 --- a/contracts/examples/order-book/pair/Cargo.toml +++ b/contracts/examples/order-book/pair/Cargo.toml @@ -8,9 +8,9 @@ publish = false path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/examples/order-book/pair/meta/Cargo.toml b/contracts/examples/order-book/pair/meta/Cargo.toml index b9af3fa938..e1d7d8abd6 100644 --- a/contracts/examples/order-book/pair/meta/Cargo.toml +++ b/contracts/examples/order-book/pair/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.order-book-pair] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/order-book/pair/meta/src/main.rs b/contracts/examples/order-book/pair/meta/src/main.rs index 7d149c79e1..79d63c3360 100644 --- a/contracts/examples/order-book/pair/meta/src/main.rs +++ b/contracts/examples/order-book/pair/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/order-book/pair/scenarios/free_orders.scen.json b/contracts/examples/order-book/pair/scenarios/free_orders.scen.json index 8556d1dee2..0e53547971 100644 --- a/contracts/examples/order-book/pair/scenarios/free_orders.scen.json +++ b/contracts/examples/order-book/pair/scenarios/free_orders.scen.json @@ -27,7 +27,8 @@ "to": "sc:pair", "function": "freeOrders", "arguments": [ - "u64:0|u64:1" + "0", + "1" ], "gasLimit": "100,000,000", "gasPrice": "0" diff --git a/contracts/examples/order-book/pair/src/orders.rs b/contracts/examples/order-book/pair/src/orders.rs index 6dd9bdc0bf..1ec11afee4 100644 --- a/contracts/examples/order-book/pair/src/orders.rs +++ b/contracts/examples/order-book/pair/src/orders.rs @@ -353,12 +353,10 @@ pub trait OrdersModule: fn execute_transfers(&self, transfers: ManagedVec>) { for transfer in &transfers { if transfer.payment.amount > 0 { - self.send().direct_esdt( - &transfer.to, - &transfer.payment.token_id, - 0, - &transfer.payment.amount, - ) + self.tx() + .to(&transfer.to) + .single_esdt(&transfer.payment.token_id, 0, &transfer.payment.amount) + .transfer(); } } } diff --git a/contracts/examples/order-book/pair/tests/pair_scenario_rs_test.rs b/contracts/examples/order-book/pair/tests/pair_scenario_rs_test.rs index c17ebaea2b..cc5df5d805 100644 --- a/contracts/examples/order-book/pair/tests/pair_scenario_rs_test.rs +++ b/contracts/examples/order-book/pair/tests/pair_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/order-book/pair"); blockchain.register_contract( "mxsc:output/order-book-pair.mxsc.json", diff --git a/contracts/examples/order-book/pair/wasm/Cargo.lock b/contracts/examples/order-book/pair/wasm/Cargo.lock index ee004b1197..c2f75cfc9b 100644 --- a/contracts/examples/order-book/pair/wasm/Cargo.lock +++ b/contracts/examples/order-book/pair/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,9 +98,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -120,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/order-book/pair/wasm/Cargo.toml b/contracts/examples/order-book/pair/wasm/Cargo.toml index f00e902291..3d4b6ded0e 100644 --- a/contracts/examples/order-book/pair/wasm/Cargo.toml +++ b/contracts/examples/order-book/pair/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.order-book-pair] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/order-book/pair/wasm/src/lib.rs b/contracts/examples/order-book/pair/wasm/src/lib.rs index ba30c0e8e9..2a4b058a13 100644 --- a/contracts/examples/order-book/pair/wasm/src/lib.rs +++ b/contracts/examples/order-book/pair/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 15 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/ping-pong-egld/Cargo.toml b/contracts/examples/ping-pong-egld/Cargo.toml index 2679417da3..31417a1261 100644 --- a/contracts/examples/ping-pong-egld/Cargo.toml +++ b/contracts/examples/ping-pong-egld/Cargo.toml @@ -9,10 +9,10 @@ publish = false path = "src/ping_pong.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/ping-pong-egld/meta/Cargo.toml b/contracts/examples/ping-pong-egld/meta/Cargo.toml index 0b40d9aa0b..f754237755 100644 --- a/contracts/examples/ping-pong-egld/meta/Cargo.toml +++ b/contracts/examples/ping-pong-egld/meta/Cargo.toml @@ -1,14 +1,14 @@ [package] name = "ping-pong-egld-meta" version = "0.0.0" -authors = [ "Bruda Claudiu-Marcel ",] +authors = ["Bruda Claudiu-Marcel "] edition = "2021" publish = false [dependencies.ping-pong-egld] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/ping-pong-egld/meta/src/main.rs b/contracts/examples/ping-pong-egld/meta/src/main.rs index e3f5dae33e..677f71931c 100644 --- a/contracts/examples/ping-pong-egld/meta/src/main.rs +++ b/contracts/examples/ping-pong-egld/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-interrupted-2.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-interrupted-2.scen.json index 2b597650b6..9253cff4f8 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-interrupted-2.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-interrupted-2.scen.json @@ -21,7 +21,7 @@ "to": "sc:ping-pong", "function": "pongAll", "arguments": [], - "gasLimit": "6,100,000", + "gasLimit": "3,500,000", "gasPrice": "0" }, "expect": { diff --git a/contracts/examples/ping-pong-egld/src/ping_pong.rs b/contracts/examples/ping-pong-egld/src/ping_pong.rs index d2d84546de..683c2a2ed5 100644 --- a/contracts/examples/ping-pong-egld/src/ping_pong.rs +++ b/contracts/examples/ping-pong-egld/src/ping_pong.rs @@ -107,8 +107,8 @@ pub trait PingPong { UserStatus::Registered => { self.user_status(user_id).set(UserStatus::Withdrawn); if let Some(user_address) = self.user_mapper().get_user_address(user_id) { - self.send() - .direct_egld(&user_address, &self.ping_amount().get()); + let amount = self.ping_amount().get(); + self.tx().to(user_address).egld(amount).transfer(); Result::Ok(()) } else { Result::Err("unknown user") diff --git a/contracts/examples/ping-pong-egld/tests/ping_pong_egld_scenario_rs_test.rs b/contracts/examples/ping-pong-egld/tests/ping_pong_egld_scenario_rs_test.rs index ccec7f5ca9..55a8e591eb 100644 --- a/contracts/examples/ping-pong-egld/tests/ping_pong_egld_scenario_rs_test.rs +++ b/contracts/examples/ping-pong-egld/tests/ping_pong_egld_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/ping-pong-egld"); blockchain.register_contract( "mxsc:output/ping-pong-egld.mxsc.json", diff --git a/contracts/examples/ping-pong-egld/wasm/Cargo.lock b/contracts/examples/ping-pong-egld/wasm/Cargo.lock index b1fa1d7bee..4f18b598d6 100755 --- a/contracts/examples/ping-pong-egld/wasm/Cargo.lock +++ b/contracts/examples/ping-pong-egld/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,9 +98,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -120,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/ping-pong-egld/wasm/Cargo.toml b/contracts/examples/ping-pong-egld/wasm/Cargo.toml index 73147c5c45..dcd7f18362 100644 --- a/contracts/examples/ping-pong-egld/wasm/Cargo.toml +++ b/contracts/examples/ping-pong-egld/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.ping-pong-egld] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/ping-pong-egld/wasm/src/lib.rs b/contracts/examples/ping-pong-egld/wasm/src/lib.rs index ec95d16c7e..35bade6af2 100644 --- a/contracts/examples/ping-pong-egld/wasm/src/lib.rs +++ b/contracts/examples/ping-pong-egld/wasm/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 11 +// Upgrade: 1 +// Endpoints: 10 // Async Callback (empty): 1 // Total number of exported functions: 13 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/proxy-pause/Cargo.toml b/contracts/examples/proxy-pause/Cargo.toml index 3e4c3a6aec..68c8785786 100644 --- a/contracts/examples/proxy-pause/Cargo.toml +++ b/contracts/examples/proxy-pause/Cargo.toml @@ -9,11 +9,11 @@ publish = false path = "src/proxy_pause.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dev-dependencies.check-pause] diff --git a/contracts/examples/proxy-pause/meta/Cargo.toml b/contracts/examples/proxy-pause/meta/Cargo.toml index fba5a0b1bc..f601641135 100644 --- a/contracts/examples/proxy-pause/meta/Cargo.toml +++ b/contracts/examples/proxy-pause/meta/Cargo.toml @@ -3,14 +3,14 @@ name = "proxy-pause-meta" version = "0.0.0" edition = "2021" publish = false -authors = [ "you",] +authors = ["you"] [dev-dependencies] [dependencies.proxy-pause] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/proxy-pause/meta/src/main.rs b/contracts/examples/proxy-pause/meta/src/main.rs index 979554a4d6..35592a5361 100644 --- a/contracts/examples/proxy-pause/meta/src/main.rs +++ b/contracts/examples/proxy-pause/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/proxy-pause/src/pause_sc_proxy.rs b/contracts/examples/proxy-pause/src/pause_sc_proxy.rs new file mode 100644 index 0000000000..a547030978 --- /dev/null +++ b/contracts/examples/proxy-pause/src/pause_sc_proxy.rs @@ -0,0 +1,53 @@ +use multiversx_sc::proxy_imports::*; + +pub struct PausableProxy; + +impl TxProxyTrait for PausableProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = PausableProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + PausableProxyMethods { wrapped_tx: tx } + } +} + +pub struct PausableProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl PausableProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn pause( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("pause") + .original_result() + } + + pub fn unpause( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("unpause") + .original_result() + } +} diff --git a/contracts/examples/proxy-pause/src/proxy_pause.rs b/contracts/examples/proxy-pause/src/proxy_pause.rs index 685a870c7e..aa5f07e7d6 100644 --- a/contracts/examples/proxy-pause/src/proxy_pause.rs +++ b/contracts/examples/proxy-pause/src/proxy_pause.rs @@ -1,17 +1,7 @@ #![no_std] use multiversx_sc::imports::*; - -mod pause_proxy { - #[multiversx_sc::proxy] - pub trait Pausable { - #[endpoint] - fn pause(&self); - - #[endpoint] - fn unpause(&self); - } -} +pub mod pause_sc_proxy; #[multiversx_sc::contract] pub trait PauseProxy { @@ -46,23 +36,26 @@ pub trait PauseProxy { fn for_each_contract(&self, f: F) where - F: Fn(pause_proxy::Proxy), + F: Fn(pause_sc_proxy::PausableProxyMethods, (), &ManagedAddress, ()>), { for contract_address in self.contracts().iter() { - f(self.pausable_contract().contract(contract_address)); + f(self + .tx() + .to(&contract_address) + .typed(pause_sc_proxy::PausableProxy)); } } #[endpoint] fn pause(&self) { self.require_owner(); - self.for_each_contract(|mut contract| contract.pause().execute_on_dest_context()); + self.for_each_contract(|contract| contract.pause().sync_call()); } #[endpoint] fn unpause(&self) { self.require_owner(); - self.for_each_contract(|mut contract| contract.unpause().execute_on_dest_context()); + self.for_each_contract(|contract| contract.unpause().sync_call()); } fn require_owner(&self) { @@ -79,7 +72,4 @@ pub trait PauseProxy { #[view] #[storage_mapper("contracts")] fn contracts(&self) -> SetMapper; - - #[proxy] - fn pausable_contract(&self) -> pause_proxy::Proxy; } diff --git a/contracts/examples/proxy-pause/tests/proxy_pause_scenario_rs_test.rs b/contracts/examples/proxy-pause/tests/proxy_pause_scenario_rs_test.rs index 41c563d7c7..08a9f92276 100644 --- a/contracts/examples/proxy-pause/tests/proxy_pause_scenario_rs_test.rs +++ b/contracts/examples/proxy-pause/tests/proxy_pause_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/proxy-pause"); blockchain.register_contract( "mxsc:output/proxy-pause.mxsc.json", diff --git a/contracts/examples/proxy-pause/wasm/Cargo.lock b/contracts/examples/proxy-pause/wasm/Cargo.lock index d9ee7fd1bf..aa6b65e308 100644 --- a/contracts/examples/proxy-pause/wasm/Cargo.lock +++ b/contracts/examples/proxy-pause/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,18 +98,18 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -129,9 +131,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/proxy-pause/wasm/Cargo.toml b/contracts/examples/proxy-pause/wasm/Cargo.toml index bdf21b6703..2642fa32a2 100644 --- a/contracts/examples/proxy-pause/wasm/Cargo.toml +++ b/contracts/examples/proxy-pause/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.proxy-pause] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/proxy-pause/wasm/src/lib.rs b/contracts/examples/proxy-pause/wasm/src/lib.rs index 62e1c633ca..e2a1a07417 100644 --- a/contracts/examples/proxy-pause/wasm/src/lib.rs +++ b/contracts/examples/proxy-pause/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/rewards-distribution/Cargo.toml b/contracts/examples/rewards-distribution/Cargo.toml index bafdb40929..3eb643c711 100644 --- a/contracts/examples/rewards-distribution/Cargo.toml +++ b/contracts/examples/rewards-distribution/Cargo.toml @@ -9,13 +9,13 @@ publish = false path = "src/rewards_distribution.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/rewards-distribution/meta/Cargo.toml b/contracts/examples/rewards-distribution/meta/Cargo.toml index cf59d2db46..09009356f9 100644 --- a/contracts/examples/rewards-distribution/meta/Cargo.toml +++ b/contracts/examples/rewards-distribution/meta/Cargo.toml @@ -10,7 +10,7 @@ authors = ["Claudiu-Marcel Bruda "] [dependencies.rewards-distribution] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/rewards-distribution/meta/src/main.rs b/contracts/examples/rewards-distribution/meta/src/main.rs index a0d8c4d099..91955a1efd 100644 --- a/contracts/examples/rewards-distribution/meta/src/main.rs +++ b/contracts/examples/rewards-distribution/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/rewards-distribution/sc-config.toml b/contracts/examples/rewards-distribution/sc-config.toml new file mode 100644 index 0000000000..9661ab3dc5 --- /dev/null +++ b/contracts/examples/rewards-distribution/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "src/rewards_distribution_proxy.rs" diff --git a/contracts/examples/rewards-distribution/src/rewards_distribution.rs b/contracts/examples/rewards-distribution/src/rewards_distribution.rs index cef14e0fef..7300fcaf88 100644 --- a/contracts/examples/rewards-distribution/src/rewards_distribution.rs +++ b/contracts/examples/rewards-distribution/src/rewards_distribution.rs @@ -5,19 +5,23 @@ use multiversx_sc_modules::ongoing_operation::{ CONTINUE_OP, DEFAULT_MIN_GAS_TO_SAVE_PROGRESS, STOP_OP, }; +pub mod rewards_distribution_proxy; +pub mod seed_nft_minter_proxy; type Epoch = u64; pub const EPOCHS_IN_WEEK: Epoch = 7; pub const MAX_PERCENTAGE: u64 = 100_000; // 100% pub const DIVISION_SAFETY_CONSTANT: u64 = 1_000_000_000_000; -#[derive(ManagedVecItem, NestedEncode, NestedDecode, TypeAbi)] +#[type_abi] +#[derive(ManagedVecItem, NestedEncode, NestedDecode)] pub struct Bracket { pub index_percent: u64, pub bracket_reward_percent: u64, } -#[derive(ManagedVecItem, NestedEncode, NestedDecode, TypeAbi)] +#[type_abi] +#[derive(ManagedVecItem, NestedEncode, NestedDecode)] pub struct ComputedBracket { pub end_index: u64, pub nft_reward_percent: BigUint, @@ -39,10 +43,14 @@ pub trait RewardsDistribution: fn init(&self, seed_nft_minter_address: ManagedAddress, brackets: ManagedVec) { self.seed_nft_minter_address().set(&seed_nft_minter_address); - let nft_token_id: TokenIdentifier = self - .seed_nft_minter_proxy(seed_nft_minter_address) - .get_nft_token_id() - .execute_on_dest_context(); + let nft_token_id = self + .tx() + .to(&seed_nft_minter_address) + .typed(seed_nft_minter_proxy::SeedNftMinterProxy) + .nft_token_id() + .returns(ReturnsResult) + .sync_call(); + self.nft_token_id().set(nft_token_id); self.validate_brackets(&brackets); @@ -175,10 +183,15 @@ pub trait RewardsDistribution: }); let seed_nft_minter_address = self.seed_nft_minter_address().get(); - let ticket_count: u64 = self - .seed_nft_minter_proxy(seed_nft_minter_address) - .get_nft_count() - .execute_on_dest_context(); + + let ticket_count = self + .tx() + .to(&seed_nft_minter_address) + .typed(seed_nft_minter_proxy::SeedNftMinterProxy) + .nft_count() + .returns(ReturnsResult) + .sync_call(); + let brackets = self.brackets().get(); let computed_brackets = self.compute_brackets(brackets, ticket_count); @@ -266,10 +279,9 @@ pub trait RewardsDistribution: } } - self.send() - .direct_non_zero_egld(&caller, &total_egld_reward); - self.send().direct_multi(&caller, &rewards); - self.send().direct_multi(&caller, &nfts); + self.tx().to(&caller).egld(total_egld_reward).transfer(); + self.tx().to(&caller).payment(rewards).transfer(); + self.tx().to(&caller).payment(nfts).transfer(); } fn claim_reward_token( @@ -417,9 +429,6 @@ pub trait RewardsDistribution: #[storage_mapper("raffleProgress")] fn raffle_progress(&self) -> SingleValueMapper>>; - - #[proxy] - fn seed_nft_minter_proxy(&self, address: ManagedAddress) -> seed_nft_minter::Proxy; } fn ticket_to_storage(position: u64, ticket_id: u64) -> u64 { @@ -437,14 +446,3 @@ fn ticket_from_storage(position: u64, ticket_id: u64) -> u64 { ticket_id } } - -mod seed_nft_minter { - #[multiversx_sc::proxy] - pub trait SeedNftMinter { - #[endpoint(getNftCount)] - fn get_nft_count(&self) -> u64; - - #[endpoint(getNftTokenId)] - fn get_nft_token_id(&self) -> TokenIdentifier; - } -} diff --git a/contracts/examples/rewards-distribution/src/rewards_distribution_proxy.rs b/contracts/examples/rewards-distribution/src/rewards_distribution_proxy.rs new file mode 100644 index 0000000000..68ddd7800f --- /dev/null +++ b/contracts/examples/rewards-distribution/src/rewards_distribution_proxy.rs @@ -0,0 +1,246 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct RewardsDistributionProxy; + +impl TxProxyTrait for RewardsDistributionProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = RewardsDistributionProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + RewardsDistributionProxyMethods { wrapped_tx: tx } + } +} + +pub struct RewardsDistributionProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl RewardsDistributionProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + seed_nft_minter_address: Arg0, + brackets: Arg1, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&seed_nft_minter_address) + .argument(&brackets) + .original_result() + } +} + +#[rustfmt::skip] +impl RewardsDistributionProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn deposit_royalties( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("depositRoyalties") + .original_result() + } + + pub fn raffle( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("raffle") + .original_result() + } + + pub fn claim_rewards< + Arg0: ProxyArg, + Arg1: ProxyArg, + Arg2: ProxyArg, u64>>>, + >( + self, + raffle_id_start: Arg0, + raffle_id_end: Arg1, + reward_tokens: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("claimRewards") + .argument(&raffle_id_start) + .argument(&raffle_id_end) + .argument(&reward_tokens) + .original_result() + } + + pub fn compute_claimable_amount< + Arg0: ProxyArg, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg, + >( + self, + raffle_id: Arg0, + reward_token_id: Arg1, + reward_token_nonce: Arg2, + nft_nonce: Arg3, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("computeClaimableAmount") + .argument(&raffle_id) + .argument(&reward_token_id) + .argument(&reward_token_nonce) + .argument(&nft_nonce) + .original_result() + } + + pub fn raffle_id( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getRaffleId") + .original_result() + } + + pub fn completed_raffle_id_count( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getCompletedRaffleIdCount") + .original_result() + } + + pub fn royalties< + Arg0: ProxyArg, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + raffle_id: Arg0, + reward_token_id: Arg1, + reward_token_nonce: Arg2, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getRoyalties") + .argument(&raffle_id) + .argument(&reward_token_id) + .argument(&reward_token_nonce) + .original_result() + } + + pub fn nft_reward_percent< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + raffle_id: Arg0, + nft_nonce: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getNftRewardPercent") + .argument(&raffle_id) + .argument(&nft_nonce) + .original_result() + } + + pub fn was_claimed< + Arg0: ProxyArg, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg, + >( + self, + raffle_id: Arg0, + reward_token_id: Arg1, + reward_token_nonce: Arg2, + nft_nonce: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getWasClaimed") + .argument(&raffle_id) + .argument(&reward_token_id) + .argument(&reward_token_nonce) + .argument(&nft_nonce) + .original_result() + } + + pub fn seed_nft_minter_address( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getSeedNftMinterAddress") + .original_result() + } + + pub fn brackets( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getBrackets") + .original_result() + } + + pub fn last_raffle_epoch( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getLastRaffleEpoch") + .original_result() + } + + pub fn nft_token_id( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getNftTokenId") + .original_result() + } +} + +#[type_abi] +#[derive(ManagedVecItem, NestedEncode, NestedDecode)] +pub struct Bracket { + pub index_percent: u64, + pub bracket_reward_percent: u64, +} diff --git a/contracts/examples/rewards-distribution/src/seed_nft_minter_proxy.rs b/contracts/examples/rewards-distribution/src/seed_nft_minter_proxy.rs new file mode 100644 index 0000000000..e25ef3fa44 --- /dev/null +++ b/contracts/examples/rewards-distribution/src/seed_nft_minter_proxy.rs @@ -0,0 +1,203 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct SeedNftMinterProxy; + +impl TxProxyTrait for SeedNftMinterProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = SeedNftMinterProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + SeedNftMinterProxyMethods { wrapped_tx: tx } + } +} + +pub struct SeedNftMinterProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl SeedNftMinterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>>, + Arg1: ProxyArg>>, + >( + self, + marketplaces: Arg0, + distribution: Arg1, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&marketplaces) + .argument(&distribution) + .original_result() + } +} + +#[rustfmt::skip] +impl SeedNftMinterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn create_nft< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>>, + Arg5: ProxyArg>, + >( + self, + name: Arg0, + royalties: Arg1, + uri: Arg2, + selling_price: Arg3, + opt_token_used_as_payment: Arg4, + opt_token_used_as_payment_nonce: Arg5, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("createNft") + .argument(&name) + .argument(&royalties) + .argument(&uri) + .argument(&selling_price) + .argument(&opt_token_used_as_payment) + .argument(&opt_token_used_as_payment_nonce) + .original_result() + } + + pub fn claim_and_distribute< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_id: Arg0, + token_nonce: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("claimAndDistribute") + .argument(&token_id) + .argument(&token_nonce) + .original_result() + } + + pub fn marketplaces( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getMarketplaces") + .original_result() + } + + pub fn nft_count( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getNftCount") + .original_result() + } + + pub fn distribution_rules( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getDistributionRules") + .original_result() + } + + pub fn issue_token< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("issueToken") + .argument(&token_display_name) + .argument(&token_ticker) + .original_result() + } + + pub fn buy_nft< + Arg0: ProxyArg, + >( + self, + nft_nonce: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("buyNft") + .argument(&nft_nonce) + .original_result() + } + + pub fn get_nft_price< + Arg0: ProxyArg, + >( + self, + nft_nonce: Arg0, + ) -> TxTypedCall, u64, BigUint>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getNftPrice") + .argument(&nft_nonce) + .original_result() + } + + pub fn nft_token_id( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getNftTokenId") + .original_result() + } +} + +#[type_abi] +#[derive(ManagedVecItem, NestedEncode, NestedDecode)] +pub struct Distribution +where + Api: ManagedTypeApi, +{ + pub address: ManagedAddress, + pub percentage: u64, + pub endpoint: ManagedBuffer, + pub gas_limit: u64, +} diff --git a/contracts/examples/rewards-distribution/tests/mock_seed_nft_minter_proxy.rs b/contracts/examples/rewards-distribution/tests/mock_seed_nft_minter_proxy.rs new file mode 100644 index 0000000000..00cc59adb5 --- /dev/null +++ b/contracts/examples/rewards-distribution/tests/mock_seed_nft_minter_proxy.rs @@ -0,0 +1,70 @@ +use multiversx_sc::proxy_imports::*; + +pub struct MockSeedNftMinterProxy; + +impl TxProxyTrait for MockSeedNftMinterProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = MockSeedNftMinterProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + MockSeedNftMinterProxyMethods { wrapped_tx: tx } + } +} + +pub struct MockSeedNftMinterProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl MockSeedNftMinterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + >( + self, + nft_token_id: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .raw_deploy() + .argument(&nft_token_id) + .original_result() + } +} + +#[rustfmt::skip] +impl MockSeedNftMinterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn set_nft_count< + Arg0: ProxyArg, + >( + self, + nft_count: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("setNftCount") + .argument(&nft_count) + .original_result() + } +} diff --git a/contracts/examples/rewards-distribution/tests/rewards_distribution_blackbox_test.rs b/contracts/examples/rewards-distribution/tests/rewards_distribution_blackbox_test.rs deleted file mode 100644 index 2902c7832c..0000000000 --- a/contracts/examples/rewards-distribution/tests/rewards_distribution_blackbox_test.rs +++ /dev/null @@ -1,373 +0,0 @@ -mod mock_seed_nft_minter; -mod utils; - -use std::iter::zip; - -use multiversx_sc::{ - codec::multi_types::MultiValue2, - storage::mappers::SingleValue, - types::{ - Address, BigUint, EgldOrEsdtTokenIdentifier, ManagedVec, MultiValueEncoded, - OperationCompletionStatus, TokenIdentifier, - }, -}; -use multiversx_sc_scenario::{ - api::StaticApi, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, ScDeployStep, ScQueryStep, - SetStateStep, TxESDT, TypedResponse, - }, - ContractInfo, DebugApi, ScenarioWorld, WhiteboxContract, -}; - -use crate::mock_seed_nft_minter::ProxyTrait as _; -use rewards_distribution::{ - Bracket, ContractObj, ProxyTrait as _, RewardsDistribution, DIVISION_SAFETY_CONSTANT, -}; - -const NFT_TOKEN_ID: &[u8] = b"NFT-123456"; -const NFT_TOKEN_ID_EXPR: &str = "str:NFT-123456"; - -const ALICE_ADDRESS_EXPR: &str = "address:alice"; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const REWARDS_DISTRIBUTION_ADDRESS_EXPR: &str = "sc:rewards-distribution"; -const REWARDS_DISTRIBUTION_PATH_EXPR: &str = "mxsc:output/rewards-distribution.mxsc.json"; -const SEED_NFT_MINTER_ADDRESS_EXPR: &str = "sc:seed-nft-minter"; -const SEED_NFT_MINTER_PATH_EXPR: &str = "mxsc:../seed-nft-minter/output/seed-nft-minter.mxsc.json"; - -type RewardsDistributionContract = ContractInfo>; -type SeedNFTMinterContract = ContractInfo>; - -fn world() -> ScenarioWorld { - let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/rewards-distribution"); - - blockchain.register_contract( - REWARDS_DISTRIBUTION_PATH_EXPR, - rewards_distribution::ContractBuilder, - ); - blockchain.register_contract( - SEED_NFT_MINTER_PATH_EXPR, - mock_seed_nft_minter::ContractBuilder, - ); - blockchain -} - -struct RewardsDistributionTestState { - world: ScenarioWorld, - seed_nft_minter_address: Address, - seed_nft_minter_contract: SeedNFTMinterContract, - rewards_distribution_contract: RewardsDistributionContract, - rewards_distribution_whitebox: WhiteboxContract>, -} - -impl RewardsDistributionTestState { - fn new() -> Self { - let mut world = world(); - - world.set_state_step( - SetStateStep::new().put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1)), - ); - - let seed_nft_minter_address = AddressValue::from(SEED_NFT_MINTER_ADDRESS_EXPR).to_address(); - - let seed_nft_minter_contract = SeedNFTMinterContract::new(SEED_NFT_MINTER_ADDRESS_EXPR); - let rewards_distribution_contract = - RewardsDistributionContract::new(REWARDS_DISTRIBUTION_ADDRESS_EXPR); - let rewards_distribution_whitebox = WhiteboxContract::new( - REWARDS_DISTRIBUTION_ADDRESS_EXPR, - rewards_distribution::contract_obj, - ); - - Self { - world, - seed_nft_minter_address, - seed_nft_minter_contract, - rewards_distribution_contract, - rewards_distribution_whitebox, - } - } - - fn deploy_seed_nft_minter_contract(&mut self) -> &mut Self { - let seed_nft_miinter_code = self.world.code_expression(SEED_NFT_MINTER_PATH_EXPR); - - self.world.sc_deploy( - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(seed_nft_miinter_code) - .call( - self.seed_nft_minter_contract - .init(TokenIdentifier::from_esdt_bytes(NFT_TOKEN_ID)), - ), - ); - - self.world.sc_call( - ScCallStep::new() - .from(OWNER_ADDRESS_EXPR) - .call(self.seed_nft_minter_contract.set_nft_count(10_000u64)), - ); - - self - } - - fn deploy_rewards_distribution_contract(&mut self) -> &mut Self { - let rewards_distribution_code = self.world.code_expression(REWARDS_DISTRIBUTION_PATH_EXPR); - - let brackets_vec = &[ - (10, 2_000), - (90, 6_000), - (400, 7_000), - (2_500, 10_000), - (25_000, 35_000), - (72_000, 40_000), - ]; - let mut brackets = ManagedVec::::new(); - for (index_percent, bracket_reward_percent) in brackets_vec.iter().cloned() { - brackets.push(Bracket { - index_percent, - bracket_reward_percent, - }); - } - self.world.sc_deploy( - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(rewards_distribution_code) - .call( - self.rewards_distribution_contract - .init(self.seed_nft_minter_address.clone(), brackets), - ), - ); - - self - } -} - -#[test] -fn test_compute_brackets() { - let mut state = RewardsDistributionTestState::new(); - - let rewards_distribution_code = state.world.code_expression(REWARDS_DISTRIBUTION_PATH_EXPR); - - state.world.set_state_step( - SetStateStep::new().put_account( - REWARDS_DISTRIBUTION_ADDRESS_EXPR, - Account::new() - .nonce(1) - .owner(OWNER_ADDRESS_EXPR) - .code(rewards_distribution_code) - .balance("0"), - ), - ); - - state.world.whitebox_call( - &state.rewards_distribution_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| { - let brackets = utils::to_brackets(&[ - (10, 2_000), - (90, 6_000), - (400, 7_000), - (2_500, 10_000), - (25_000, 35_000), - (72_000, 40_000), - ]); - - let computed_brackets = sc.compute_brackets(brackets, 10_000); - - let expected_values = vec![ - (1, 2_000 * DIVISION_SAFETY_CONSTANT), - (10, 6_000 * DIVISION_SAFETY_CONSTANT / (10 - 1)), - (50, 7_000 * DIVISION_SAFETY_CONSTANT / (50 - 10)), - (300, 10_000 * DIVISION_SAFETY_CONSTANT / (300 - 50)), - (2_800, 35_000 * DIVISION_SAFETY_CONSTANT / (2_800 - 300)), - (10_000, 40_000 * DIVISION_SAFETY_CONSTANT / (10_000 - 2_800)), - ]; - - assert_eq!(computed_brackets.len(), expected_values.len()); - for (computed, expected) in zip(computed_brackets.iter(), expected_values) { - let (expected_end_index, expected_reward_percent) = expected; - assert_eq!(computed.end_index, expected_end_index); - assert_eq!(computed.nft_reward_percent, expected_reward_percent); - } - }, - ); -} - -#[test] -fn test_raffle_and_claim() { - let mut state = RewardsDistributionTestState::new(); - - let nft_nonces: [u64; 6] = [1, 2, 3, 4, 5, 6]; - let nft_payments: Vec = nft_nonces - .iter() - .map(|nonce| TxESDT { - esdt_token_identifier: NFT_TOKEN_ID.into(), - nonce: (*nonce).into(), - esdt_value: 1u64.into(), - }) - .collect(); - - let mut alice_account = Account::new().nonce(1).balance("2_070_000_000"); - for nonce in nft_nonces.iter() { - alice_account = - alice_account.esdt_nft_balance(NFT_TOKEN_ID_EXPR, *nonce, "1", Option::<&[u8]>::None); - } - - state.world.set_state_step( - SetStateStep::new() - .put_account(ALICE_ADDRESS_EXPR, alice_account) - .new_address(OWNER_ADDRESS_EXPR, 1, SEED_NFT_MINTER_ADDRESS_EXPR) - .new_address(OWNER_ADDRESS_EXPR, 3, REWARDS_DISTRIBUTION_ADDRESS_EXPR), - ); - - state - .deploy_seed_nft_minter_contract() - .deploy_rewards_distribution_contract(); - - // deposit royalties - state.world.sc_call( - ScCallStep::new() - .from(ALICE_ADDRESS_EXPR) - .egld_value("2_070_000_000") - .call(state.rewards_distribution_contract.deposit_royalties()), - ); - - // run the raffle - state.world.sc_call( - ScCallStep::new() - .from(ALICE_ADDRESS_EXPR) - .tx_hash(&[0u8; 32]) // blockchain rng is deterministic, so we can use a fixed hash - .call(state.rewards_distribution_contract.raffle()) - .expect_value(OperationCompletionStatus::Completed), - ); - - let mut rewards: Vec> = Vec::new(); - // post-raffle reward amount frequency checksstate - for nonce in 1u64..=10_000u64 { - state.world.sc_call_use_result( - ScCallStep::new().from(ALICE_ADDRESS_EXPR).call( - state - .rewards_distribution_contract - .compute_claimable_amount( - 0u64, - &EgldOrEsdtTokenIdentifier::egld(), - 0u64, - nonce, - ), - ), - |r: TypedResponse>| rewards.push(r.result.unwrap()), - ); - } - - assert_eq!(rewards.len() as u64, 10_000u64); - - // check that the reward amounts match in frequency - let expected_reward_amounts = [ - (41_400_000, 1), - (13_799_999, 9), - (3_622_500, 40), - (828_000, 250), - (289_800, 2500), - (114_999, 7200), - ]; - - let total_expected_count: u64 = expected_reward_amounts.iter().map(|(_, count)| count).sum(); - assert_eq!(total_expected_count, 10_000u64); - - for (amount, expected_count) in expected_reward_amounts { - let expected_amount = amount as u64; - assert_eq!( - rewards - .iter() - .filter(|value| *value == &expected_amount) - .count(), - expected_count as usize - ); - } - - let expected_rewards = [114_999, 114_999, 114_999, 828_000, 114_999, 114_999]; - - for (nonce, expected_reward) in std::iter::zip(nft_nonces, expected_rewards) { - state.world.sc_call_use_result( - ScCallStep::new().from(ALICE_ADDRESS_EXPR).call( - state - .rewards_distribution_contract - .compute_claimable_amount( - 0u64, - &EgldOrEsdtTokenIdentifier::egld(), - 0u64, - nonce, - ), - ), - |r: TypedResponse>| { - assert_eq!(r.result.unwrap().to_u64().unwrap(), expected_reward); - }, - ); - } - - // claim rewards - let mut reward_tokens: MultiValueEncoded< - StaticApi, - MultiValue2, u64>, - > = MultiValueEncoded::new(); - reward_tokens.push((EgldOrEsdtTokenIdentifier::egld(), 0).into()); - state.world.sc_call( - ScCallStep::new() - .from(ALICE_ADDRESS_EXPR) - .multi_esdt_transfer(nft_payments.clone()) - .call( - state - .rewards_distribution_contract - .claim_rewards(0u64, 0u64, reward_tokens), - ), - ); - - // check that the rewards were claimed - for nonce in nft_nonces.iter() { - state.world.sc_query( - ScQueryStep::new() - .call(state.rewards_distribution_contract.was_claimed( - 0u64, - &EgldOrEsdtTokenIdentifier::egld(), - 0u64, - nonce, - )) - .expect_value(SingleValue::from(true)), - ); - } - - // confirm the received amount matches the sum of the queried rewards - let alice_balance_after_claim: u64 = expected_rewards.iter().sum(); - let balance_expr = alice_balance_after_claim.to_string(); - - state - .world - .check_state_step(CheckStateStep::new().put_account( - ALICE_ADDRESS_EXPR, - CheckAccount::new().balance(balance_expr.as_str()), - )); - - // a second claim with the same nfts should succeed, but return no more rewards - let mut reward_tokens: MultiValueEncoded< - StaticApi, - MultiValue2, u64>, - > = MultiValueEncoded::new(); - reward_tokens.push((EgldOrEsdtTokenIdentifier::egld(), 0).into()); - state.world.sc_call( - ScCallStep::new() - .from(ALICE_ADDRESS_EXPR) - .multi_esdt_transfer(nft_payments) - .call( - state - .rewards_distribution_contract - .claim_rewards(0u64, 0u64, reward_tokens), - ), - ); - - state - .world - .check_state_step(CheckStateStep::new().put_account( - ALICE_ADDRESS_EXPR, - CheckAccount::new().balance(balance_expr.as_str()), - )); -} diff --git a/contracts/examples/rewards-distribution/tests/rewards_distribution_integration_test.rs b/contracts/examples/rewards-distribution/tests/rewards_distribution_integration_test.rs new file mode 100644 index 0000000000..be3a4cb788 --- /dev/null +++ b/contracts/examples/rewards-distribution/tests/rewards_distribution_integration_test.rs @@ -0,0 +1,312 @@ +mod mock_seed_nft_minter; +mod mock_seed_nft_minter_proxy; +mod utils; + +use multiversx_sc_scenario::imports::*; +use std::iter::zip; + +use rewards_distribution::{ + rewards_distribution_proxy, ContractObj, RewardsDistribution, DIVISION_SAFETY_CONSTANT, +}; + +const ALICE_ADDRESS: TestAddress = TestAddress::new("alice"); +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const REWARDS_DISTRIBUTION_ADDRESS: TestSCAddress = TestSCAddress::new("rewards-distribution"); +const REWARDS_DISTRIBUTION_PATH: MxscPath = MxscPath::new("output/rewards-distribution.mxsc.json"); +const SEED_NFT_MINTER_ADDRESS: TestSCAddress = TestSCAddress::new("seed-nft-minter"); +const SEED_NFT_MINTER_PATH: MxscPath = + MxscPath::new("../seed-nft-minter/output/seed-nft-minter.mxsc.json"); +const NFT_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("NFT-123456"); + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + REWARDS_DISTRIBUTION_PATH, + rewards_distribution::ContractBuilder, + ); + blockchain.register_contract(SEED_NFT_MINTER_PATH, mock_seed_nft_minter::ContractBuilder); + blockchain +} + +struct RewardsDistributionTestState { + world: ScenarioWorld, + rewards_distribution_whitebox: WhiteboxContract>, +} + +impl RewardsDistributionTestState { + fn new() -> Self { + let mut world = world(); + + world.account(OWNER_ADDRESS).nonce(1); + + let rewards_distribution_whitebox = WhiteboxContract::new( + REWARDS_DISTRIBUTION_ADDRESS, + rewards_distribution::contract_obj, + ); + + Self { + world, + rewards_distribution_whitebox, + } + } + + fn deploy_seed_nft_minter_contract(&mut self) -> &mut Self { + self.world + .tx() + .from(OWNER_ADDRESS) + .typed(mock_seed_nft_minter_proxy::MockSeedNftMinterProxy) + .init(NFT_TOKEN_ID) + .code(SEED_NFT_MINTER_PATH) + .run(); + + self.world + .tx() + .from(OWNER_ADDRESS) + .to(SEED_NFT_MINTER_ADDRESS) + .typed(mock_seed_nft_minter_proxy::MockSeedNftMinterProxy) + .set_nft_count(10_000u64) + .run(); + + self + } + + fn deploy_rewards_distribution_contract(&mut self) -> &mut Self { + let brackets_vec = &[ + (10, 2_000), + (90, 6_000), + (400, 7_000), + (2_500, 10_000), + (25_000, 35_000), + (72_000, 40_000), + ]; + let mut brackets = ManagedVec::new(); + for (index_percent, bracket_reward_percent) in brackets_vec.iter().cloned() { + brackets.push(rewards_distribution_proxy::Bracket { + index_percent, + bracket_reward_percent, + }); + } + self.world + .tx() + .from(OWNER_ADDRESS) + .typed(rewards_distribution_proxy::RewardsDistributionProxy) + .init(SEED_NFT_MINTER_ADDRESS.to_address(), brackets) + .code(REWARDS_DISTRIBUTION_PATH) + .run(); + + self + } +} + +#[test] +fn test_compute_brackets() { + let mut state = RewardsDistributionTestState::new(); + + state + .world + .account(REWARDS_DISTRIBUTION_ADDRESS) + .nonce(1) + .owner(OWNER_ADDRESS) + .code(REWARDS_DISTRIBUTION_PATH); + + state.world.whitebox_call( + &state.rewards_distribution_whitebox, + ScCallStep::new().from(OWNER_ADDRESS), + |sc| { + let brackets = utils::to_brackets(&[ + (10, 2_000), + (90, 6_000), + (400, 7_000), + (2_500, 10_000), + (25_000, 35_000), + (72_000, 40_000), + ]); + + let computed_brackets = sc.compute_brackets(brackets, 10_000); + + let expected_values = vec![ + (1, 2_000 * DIVISION_SAFETY_CONSTANT), + (10, 6_000 * DIVISION_SAFETY_CONSTANT / (10 - 1)), + (50, 7_000 * DIVISION_SAFETY_CONSTANT / (50 - 10)), + (300, 10_000 * DIVISION_SAFETY_CONSTANT / (300 - 50)), + (2_800, 35_000 * DIVISION_SAFETY_CONSTANT / (2_800 - 300)), + (10_000, 40_000 * DIVISION_SAFETY_CONSTANT / (10_000 - 2_800)), + ]; + + assert_eq!(computed_brackets.len(), expected_values.len()); + for (computed, expected) in zip(computed_brackets.iter(), expected_values) { + let (expected_end_index, expected_reward_percent) = expected; + assert_eq!(computed.end_index, expected_end_index); + assert_eq!(computed.nft_reward_percent, expected_reward_percent); + } + }, + ); +} + +#[test] +fn test_raffle_and_claim() { + let mut state = RewardsDistributionTestState::new(); + + let nft_nonces: [u64; 6] = [1, 2, 3, 4, 5, 6]; + let mut nft_payments = ManagedVec::new(); + for nonce in nft_nonces.into_iter() { + let payment = EsdtTokenPayment::new(NFT_TOKEN_ID.into(), nonce, 1u64.into()); + nft_payments.push(payment); + } + + { + let mut account_setter = state + .world + .account(ALICE_ADDRESS) + .nonce(1) + .balance(2_070_000_000); + for nft_nonce in nft_nonces { + account_setter = account_setter.esdt_nft_balance(NFT_TOKEN_ID, nft_nonce, 1, ()); + } + } + + state.world.set_state_step( + SetStateStep::new() + .new_address(OWNER_ADDRESS, 1, SEED_NFT_MINTER_ADDRESS) + .new_address(OWNER_ADDRESS, 3, REWARDS_DISTRIBUTION_ADDRESS), + ); + + state + .deploy_seed_nft_minter_contract() + .deploy_rewards_distribution_contract(); + + // deposit royalties + state + .world + .tx() + .from(ALICE_ADDRESS) + .to(REWARDS_DISTRIBUTION_ADDRESS) + .typed(rewards_distribution_proxy::RewardsDistributionProxy) + .deposit_royalties() + .egld(2_070_000_000) + .run(); + + // run the raffle + state + .world + .tx() + .from(ALICE_ADDRESS) + .to(REWARDS_DISTRIBUTION_ADDRESS) + .typed(rewards_distribution_proxy::RewardsDistributionProxy) + .raffle() + .tx_hash([0u8; 32]) // blockchain rng is deterministic, so we can use a fixed hash + .run(); + + let mut rewards: Vec> = Vec::new(); + // post-raffle reward amount frequency checksstate + for nonce in 1u64..=10_000u64 { + let reward = state + .world + .tx() + .from(ALICE_ADDRESS) + .to(REWARDS_DISTRIBUTION_ADDRESS) + .typed(rewards_distribution_proxy::RewardsDistributionProxy) + .compute_claimable_amount(0u64, &EgldOrEsdtTokenIdentifier::egld(), 0u64, nonce) + .returns(ReturnsResult) + .run(); + rewards.push(reward); + } + + assert_eq!(rewards.len() as u64, 10_000u64); + + // check that the reward amounts match in frequency + let expected_reward_amounts = [ + (41_400_000, 1), + (13_799_999, 9), + (3_622_500, 40), + (828_000, 250), + (289_800, 2500), + (114_999, 7200), + ]; + + let total_expected_count: u64 = expected_reward_amounts.iter().map(|(_, count)| count).sum(); + assert_eq!(total_expected_count, 10_000u64); + + for (amount, expected_count) in expected_reward_amounts { + let expected_amount = amount as u64; + assert_eq!( + rewards + .iter() + .filter(|value| *value == &expected_amount) + .count(), + expected_count as usize + ); + } + + let expected_rewards = [114_999, 114_999, 114_999, 828_000, 114_999, 114_999]; + + for (nonce, expected_reward) in std::iter::zip(nft_nonces, expected_rewards) { + state + .world + .tx() + .from(ALICE_ADDRESS) + .to(REWARDS_DISTRIBUTION_ADDRESS) + .typed(rewards_distribution_proxy::RewardsDistributionProxy) + .compute_claimable_amount(0u64, &EgldOrEsdtTokenIdentifier::egld(), 0u64, nonce) + .returns(ExpectValue(expected_reward)) + .run(); + } + + // claim rewards + let mut reward_tokens: MultiValueEncoded< + StaticApi, + MultiValue2, u64>, + > = MultiValueEncoded::new(); + reward_tokens.push((EgldOrEsdtTokenIdentifier::egld(), 0).into()); + state + .world + .tx() + .from(ALICE_ADDRESS) + .to(REWARDS_DISTRIBUTION_ADDRESS) + .typed(rewards_distribution_proxy::RewardsDistributionProxy) + .claim_rewards(0u64, 0u64, reward_tokens) + .with_multi_token_transfer(nft_payments.clone()) + .run(); + + // check that the rewards were claimed + for nonce in nft_nonces.iter() { + state + .world + .query() + .to(REWARDS_DISTRIBUTION_ADDRESS) + .typed(rewards_distribution_proxy::RewardsDistributionProxy) + .was_claimed(0u64, &EgldOrEsdtTokenIdentifier::egld(), 0u64, nonce) + .returns(ExpectValue(true)) + .run(); + } + + // confirm the received amount matches the sum of the queried rewards + let alice_balance_after_claim: u64 = expected_rewards.iter().sum(); + + state + .world + .check_account(ALICE_ADDRESS) + .balance(alice_balance_after_claim); + + // a second claim with the same nfts should succeed, but return no more rewards + let mut reward_tokens: MultiValueEncoded< + StaticApi, + MultiValue2, u64>, + > = MultiValueEncoded::new(); + reward_tokens.push((EgldOrEsdtTokenIdentifier::egld(), 0).into()); + state + .world + .tx() + .from(ALICE_ADDRESS) + .to(REWARDS_DISTRIBUTION_ADDRESS) + .typed(rewards_distribution_proxy::RewardsDistributionProxy) + .claim_rewards(0u64, 0u64, reward_tokens) + .with_multi_token_transfer(nft_payments) + .run(); + + state + .world + .check_account(ALICE_ADDRESS) + .balance(alice_balance_after_claim); +} diff --git a/contracts/examples/rewards-distribution/wasm/Cargo.lock b/contracts/examples/rewards-distribution/wasm/Cargo.lock index 2f7aa5b9c9..72eb898ad0 100644 --- a/contracts/examples/rewards-distribution/wasm/Cargo.lock +++ b/contracts/examples/rewards-distribution/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,14 +82,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,27 +105,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/rewards-distribution/wasm/Cargo.toml b/contracts/examples/rewards-distribution/wasm/Cargo.toml index a17709b9e7..33b39a2c69 100644 --- a/contracts/examples/rewards-distribution/wasm/Cargo.toml +++ b/contracts/examples/rewards-distribution/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.rewards-distribution] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/rewards-distribution/wasm/src/lib.rs b/contracts/examples/rewards-distribution/wasm/src/lib.rs index b41b365c4e..34397de228 100644 --- a/contracts/examples/rewards-distribution/wasm/src/lib.rs +++ b/contracts/examples/rewards-distribution/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 15 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/seed-nft-minter/Cargo.toml b/contracts/examples/seed-nft-minter/Cargo.toml index b1b22d1276..68a01761c4 100644 --- a/contracts/examples/seed-nft-minter/Cargo.toml +++ b/contracts/examples/seed-nft-minter/Cargo.toml @@ -9,13 +9,13 @@ publish = false path = "src/seed_nft_minter.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/seed-nft-minter/meta/Cargo.toml b/contracts/examples/seed-nft-minter/meta/Cargo.toml index 9828dc2788..69787cc915 100644 --- a/contracts/examples/seed-nft-minter/meta/Cargo.toml +++ b/contracts/examples/seed-nft-minter/meta/Cargo.toml @@ -10,7 +10,7 @@ authors = ["Claudiu-Marcel Bruda "] [dependencies.seed-nft-minter] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/examples/seed-nft-minter/meta/src/main.rs b/contracts/examples/seed-nft-minter/meta/src/main.rs index 8d7ab4b957..b8cc68fd11 100644 --- a/contracts/examples/seed-nft-minter/meta/src/main.rs +++ b/contracts/examples/seed-nft-minter/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/seed-nft-minter/sc-config.toml b/contracts/examples/seed-nft-minter/sc-config.toml new file mode 100644 index 0000000000..5597c10092 --- /dev/null +++ b/contracts/examples/seed-nft-minter/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "../rewards-distribution/src/seed_nft_minter_proxy.rs" diff --git a/contracts/examples/seed-nft-minter/src/distribution_module.rs b/contracts/examples/seed-nft-minter/src/distribution_module.rs index 9b3bb6d507..54f8bf2586 100644 --- a/contracts/examples/seed-nft-minter/src/distribution_module.rs +++ b/contracts/examples/seed-nft-minter/src/distribution_module.rs @@ -2,7 +2,8 @@ use multiversx_sc::{derive_imports::*, imports::*}; pub const MAX_DISTRIBUTION_PERCENTAGE: u64 = 100_000; // 100% -#[derive(ManagedVecItem, NestedEncode, NestedDecode, TypeAbi)] +#[type_abi] +#[derive(ManagedVecItem, NestedEncode, NestedDecode)] pub struct Distribution { pub address: ManagedAddress, pub percentage: u64, @@ -32,10 +33,11 @@ pub trait DistributionModule { if payment_amount == 0 { continue; } - self.send() - .contract_call::(distribution.address, distribution.endpoint) - .with_egld_or_single_esdt_transfer((token_id.clone(), token_nonce, payment_amount)) - .with_gas_limit(distribution.gas_limit) + self.tx() + .to(&distribution.address) + .raw_call(distribution.endpoint) + .egld_or_single_esdt(token_id, token_nonce, &payment_amount) + .gas(distribution.gas_limit) .transfer_execute(); } } diff --git a/contracts/examples/seed-nft-minter/src/nft_marketplace_proxy.rs b/contracts/examples/seed-nft-minter/src/nft_marketplace_proxy.rs new file mode 100644 index 0000000000..dc41de1948 --- /dev/null +++ b/contracts/examples/seed-nft-minter/src/nft_marketplace_proxy.rs @@ -0,0 +1,74 @@ +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct NftMarketplaceProxy; + +impl TxProxyTrait for NftMarketplaceProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = NftMarketplaceProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + NftMarketplaceProxyMethods { wrapped_tx: tx } + } +} + +pub struct NftMarketplaceProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl NftMarketplaceProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl NftMarketplaceProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn claim_tokens< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + claim_destination: Arg0, + token_id: Arg1, + token_nonce: Arg2, + ) -> TxTypedCall, ManagedVec>>> { + self.wrapped_tx + .raw_call("claimTokens") + .argument(&claim_destination) + .argument(&token_id) + .argument(&token_nonce) + .original_result() + } +} diff --git a/contracts/examples/seed-nft-minter/src/nft_module.rs b/contracts/examples/seed-nft-minter/src/nft_module.rs index 885ff36c90..a65a4175d7 100644 --- a/contracts/examples/seed-nft-minter/src/nft_module.rs +++ b/contracts/examples/seed-nft-minter/src/nft_module.rs @@ -65,13 +65,11 @@ pub trait NftModule: self.price_tag(nft_nonce).clear(); let nft_token_id = self.nft_token_id().get_token_id(); - let caller = self.blockchain().get_caller(); - self.send().direct_esdt( - &caller, - &nft_token_id, - nft_nonce, - &BigUint::from(NFT_AMOUNT), - ); + + self.tx() + .to(ToCaller) + .single_esdt(&nft_token_id, nft_nonce, &BigUint::from(NFT_AMOUNT)) + .transfer(); self.distribute_funds( &payment.token_identifier, diff --git a/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs b/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs index 42b064e5cd..1a6ac5ffe2 100644 --- a/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs +++ b/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs @@ -3,6 +3,7 @@ use multiversx_sc::{derive_imports::*, imports::*}; mod distribution_module; +pub mod nft_marketplace_proxy; mod nft_module; use distribution_module::Distribution; @@ -86,10 +87,13 @@ pub trait SeedNftMinter: let claim_destination = self.blockchain().get_sc_address(); let mut total_amount = BigUint::zero(); for address in self.marketplaces().iter() { - let results: MultiValue2> = self - .marketplace_proxy(address) + let results = self + .tx() + .to(&address) + .typed(nft_marketplace_proxy::NftMarketplaceProxy) .claim_tokens(&claim_destination, token_id, token_nonce) - .execute_on_dest_context(); + .returns(ReturnsResult) + .sync_call(); let (egld_amount, esdt_payments) = results.into_tuple(); let amount = if token_id.is_egld() { @@ -113,25 +117,4 @@ pub trait SeedNftMinter: #[view(getNftCount)] #[storage_mapper("nftCount")] fn nft_count(&self) -> SingleValueMapper; - - #[proxy] - fn marketplace_proxy( - &self, - sc_address: ManagedAddress, - ) -> nft_marketplace_proxy::Proxy; -} - -mod nft_marketplace_proxy { - use multiversx_sc::imports::*; - - #[multiversx_sc::proxy] - pub trait NftMarketplace { - #[endpoint(claimTokens)] - fn claim_tokens( - &self, - claim_destination: &ManagedAddress, - token_id: &EgldOrEsdtTokenIdentifier, - token_nonce: u64, - ) -> MultiValue2>; - } } diff --git a/contracts/examples/seed-nft-minter/wasm/Cargo.lock b/contracts/examples/seed-nft-minter/wasm/Cargo.lock index cf8559ba91..91ebc13608 100644 --- a/contracts/examples/seed-nft-minter/wasm/Cargo.lock +++ b/contracts/examples/seed-nft-minter/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,14 +82,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,27 +105,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/seed-nft-minter/wasm/Cargo.toml b/contracts/examples/seed-nft-minter/wasm/Cargo.toml index b6f616bf91..3b76bf97e4 100644 --- a/contracts/examples/seed-nft-minter/wasm/Cargo.toml +++ b/contracts/examples/seed-nft-minter/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.seed-nft-minter] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/seed-nft-minter/wasm/src/lib.rs b/contracts/examples/seed-nft-minter/wasm/src/lib.rs index e4aec1825d..5f0e0090d6 100644 --- a/contracts/examples/seed-nft-minter/wasm/src/lib.rs +++ b/contracts/examples/seed-nft-minter/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 11 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/examples/token-release/Cargo.toml b/contracts/examples/token-release/Cargo.toml index 2e20827705..1cf88eb1e3 100644 --- a/contracts/examples/token-release/Cargo.toml +++ b/contracts/examples/token-release/Cargo.toml @@ -9,10 +9,10 @@ publish = false path = "src/token_release.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/examples/token-release/meta/Cargo.toml b/contracts/examples/token-release/meta/Cargo.toml index d774d4a2bb..5b814916b4 100644 --- a/contracts/examples/token-release/meta/Cargo.toml +++ b/contracts/examples/token-release/meta/Cargo.toml @@ -9,8 +9,7 @@ publish = false [dependencies.token-release] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false - diff --git a/contracts/examples/token-release/meta/src/main.rs b/contracts/examples/token-release/meta/src/main.rs index 5d201501f4..1cbd2f7583 100644 --- a/contracts/examples/token-release/meta/src/main.rs +++ b/contracts/examples/token-release/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/examples/token-release/src/token_release.rs b/contracts/examples/token-release/src/token_release.rs index 29fb3890e0..b0acd8a0e7 100644 --- a/contracts/examples/token-release/src/token_release.rs +++ b/contracts/examples/token-release/src/token_release.rs @@ -312,8 +312,10 @@ pub trait TokenRelease { address: &ManagedAddress, amount: &BigUint, ) { - self.send() - .direct_esdt(address, token_identifier, 0, amount); + self.tx() + .to(address) + .single_esdt(token_identifier, 0, amount) + .transfer(); } fn mint_all_tokens(&self, token_identifier: &TokenIdentifier, amount: &BigUint) { diff --git a/contracts/examples/token-release/tests/token_release_scenario_rs_test.rs b/contracts/examples/token-release/tests/token_release_scenario_rs_test.rs index 57f8c4a142..eefa11be57 100644 --- a/contracts/examples/token-release/tests/token_release_scenario_rs_test.rs +++ b/contracts/examples/token-release/tests/token_release_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/token-release"); blockchain.register_contract( "mxsc:output/token-release.mxsc.json", diff --git a/contracts/examples/token-release/wasm/Cargo.lock b/contracts/examples/token-release/wasm/Cargo.lock index 04771bffe7..382cdc8414 100644 --- a/contracts/examples/token-release/wasm/Cargo.lock +++ b/contracts/examples/token-release/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -133,15 +135,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/token-release/wasm/Cargo.toml b/contracts/examples/token-release/wasm/Cargo.toml index 71ad98f976..2a6ee31f04 100644 --- a/contracts/examples/token-release/wasm/Cargo.toml +++ b/contracts/examples/token-release/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.token-release] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/token-release/wasm/src/lib.rs b/contracts/examples/token-release/wasm/src/lib.rs index be580b5ccd..4dd7699632 100644 --- a/contracts/examples/token-release/wasm/src/lib.rs +++ b/contracts/examples/token-release/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 15 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/abi-tester/Cargo.toml b/contracts/feature-tests/abi-tester/Cargo.toml index 66ff8bb666..6962ad0618 100644 --- a/contracts/feature-tests/abi-tester/Cargo.toml +++ b/contracts/feature-tests/abi-tester/Cargo.toml @@ -9,14 +9,14 @@ publish = false path = "src/abi_tester.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" -[dev-dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../framework/meta" +[dev-dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../framework/meta-lib" diff --git a/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json b/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json index 400f5134aa..440b5b68b7 100644 --- a/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json +++ b/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json @@ -14,7 +14,7 @@ }, "framework": { "name": "multiversx-sc", - "version": "0.47.5" + "version": "0.50.3" } }, "docs": [ @@ -44,6 +44,22 @@ ], "outputs": [] }, + "upgradeConstructor": { + "docs": [ + "Upgrade constructor." + ], + "inputs": [ + { + "name": "_constructor_arg_1", + "type": "i32" + }, + { + "name": "_constructor_arg_2", + "type": "OnlyShowsUpInConstructor" + } + ], + "outputs": [] + }, "endpoints": [ { "docs": [ @@ -363,6 +379,16 @@ } ] }, + { + "name": "operation_completion_status", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "OperationCompletionStatus" + } + ] + }, { "name": "payable_egld", "mutability": "mutable", @@ -927,6 +953,23 @@ "type": "OnlyShowsUpAsNested10" } ] + }, + "OperationCompletionStatus": { + "type": "explicit-enum", + "variants": [ + { + "docs": [ + "indicates that operation was completed" + ], + "name": "completed" + }, + { + "docs": [ + "indicates that operation was interrupted prematurely, due to low gas" + ], + "name": "interrupted" + } + ] } } } diff --git a/contracts/feature-tests/abi-tester/abi_tester_expected_view.abi.json b/contracts/feature-tests/abi-tester/abi_tester_expected_view.abi.json index d77a31f4df..0600ad44df 100644 --- a/contracts/feature-tests/abi-tester/abi_tester_expected_view.abi.json +++ b/contracts/feature-tests/abi-tester/abi_tester_expected_view.abi.json @@ -14,7 +14,7 @@ }, "framework": { "name": "multiversx-sc", - "version": "0.47.5" + "version": "0.50.3" } }, "docs": [ @@ -604,6 +604,23 @@ "type": "OnlyShowsUpAsNested10" } ] + }, + "OperationCompletionStatus": { + "type": "explicit-enum", + "variants": [ + { + "docs": [ + "indicates that operation was completed" + ], + "name": "completed" + }, + { + "docs": [ + "indicates that operation was interrupted prematurely, due to low gas" + ], + "name": "interrupted" + } + ] } } } diff --git a/contracts/feature-tests/abi-tester/meta/Cargo.toml b/contracts/feature-tests/abi-tester/meta/Cargo.toml index 00bd658c54..643984beaf 100644 --- a/contracts/feature-tests/abi-tester/meta/Cargo.toml +++ b/contracts/feature-tests/abi-tester/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.abi-tester] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/abi-tester/meta/src/main.rs b/contracts/feature-tests/abi-tester/meta/src/main.rs index 94f485814b..f1525e90f9 100644 --- a/contracts/feature-tests/abi-tester/meta/src/main.rs +++ b/contracts/feature-tests/abi-tester/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/abi-tester/sc-config.toml b/contracts/feature-tests/abi-tester/sc-config.toml index 5a61f68d47..df90daa529 100644 --- a/contracts/feature-tests/abi-tester/sc-config.toml +++ b/contracts/feature-tests/abi-tester/sc-config.toml @@ -11,4 +11,10 @@ name = "abi-tester-ev" external-view = true add-unlabelled = false add-labels = ["test-external-view"] -add-endpoints = ["payable_any_token", "label_a"] # labels can be bypassed, endpoints added directly +add-endpoints = [ + "payable_any_token", + "label_a", +] # labels can be bypassed, endpoints added directly + +[[proxy]] +path = "src/abi_proxy.rs" diff --git a/contracts/feature-tests/abi-tester/src/abi_proxy.rs b/contracts/feature-tests/abi-tester/src/abi_proxy.rs new file mode 100644 index 0000000000..2011970429 --- /dev/null +++ b/contracts/feature-tests/abi-tester/src/abi_proxy.rs @@ -0,0 +1,589 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct AbiTesterProxy; + +impl TxProxyTrait for AbiTesterProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = AbiTesterProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + AbiTesterProxyMethods { wrapped_tx: tx } + } +} + +pub struct AbiTesterProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl AbiTesterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + /// Contract constructor. + pub fn init< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + _constructor_arg_1: Arg0, + _constructor_arg_2: Arg1, + ) -> TxTypedDeploy { + self.wrapped_tx + .raw_deploy() + .argument(&_constructor_arg_1) + .argument(&_constructor_arg_2) + .original_result() + } +} + +#[rustfmt::skip] +impl AbiTesterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + /// Upgrade constructor. + pub fn upgrade< + Arg0: ProxyArg, + Arg1: ProxyArg, + >( + self, + _constructor_arg_1: Arg0, + _constructor_arg_2: Arg1, + ) -> TxTypedUpgrade { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .argument(&_constructor_arg_1) + .argument(&_constructor_arg_2) + .original_result() + } +} + +#[rustfmt::skip] +impl AbiTesterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + /// Example endpoint docs. + pub fn echo_abi_test_type< + Arg0: ProxyArg, + >( + self, + att: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_abi_test_type") + .argument(&att) + .original_result() + } + + pub fn echo_enum< + Arg0: ProxyArg, + >( + self, + e: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_enum") + .argument(&e) + .original_result() + } + + pub fn take_managed_type< + Arg0: ProxyArg>, + >( + self, + _arg: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("take_managed_type") + .argument(&_arg) + .original_result() + } + + pub fn multi_result_3( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("multi_result_3") + .original_result() + } + + pub fn multi_result_4( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("multi_result_4") + .original_result() + } + + pub fn var_args< + Arg0: ProxyArg, + Arg1: ProxyArg>>, + >( + self, + _simple_arg: Arg0, + _var_args: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("var_args") + .argument(&_simple_arg) + .argument(&_var_args) + .original_result() + } + + pub fn multi_result_vec( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("multi_result_vec") + .original_result() + } + + pub fn optional_arg< + Arg0: ProxyArg, + Arg1: ProxyArg>, + >( + self, + _simple_arg: Arg0, + _opt_args: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("optional_arg") + .argument(&_simple_arg) + .argument(&_opt_args) + .original_result() + } + + pub fn optional_result( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("optional_result") + .original_result() + } + + pub fn address_vs_h256< + Arg0: ProxyArg
, + Arg1: ProxyArg, + >( + self, + address: Arg0, + h256: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("address_vs_h256") + .argument(&address) + .argument(&h256) + .original_result() + } + + pub fn managed_address_vs_byte_array< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + address: Arg0, + byte_array: Arg1, + ) -> TxTypedCall, ManagedByteArray>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("managed_address_vs_byte_array") + .argument(&address) + .argument(&byte_array) + .original_result() + } + + pub fn esdt_local_role( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("esdt_local_role") + .original_result() + } + + pub fn esdt_token_payment( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("esdt_token_payment") + .original_result() + } + + pub fn esdt_token_data( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("esdt_token_data") + .original_result() + } + + pub fn sample_storage_mapper( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("sample_storage_mapper") + .original_result() + } + + pub fn item_for_vec( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("item_for_vec") + .original_result() + } + + pub fn item_for_array_vec( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("item_for_array_vec") + .original_result() + } + + pub fn item_for_managed_vec( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("item_for_managed_vec") + .original_result() + } + + pub fn item_for_array< + Arg0: ProxyArg<[OnlyShowsUpAsNestedInArray; 5]>, + >( + self, + _array: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("item_for_array") + .argument(&_array) + .original_result() + } + + pub fn item_for_box( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("item_for_box") + .original_result() + } + + pub fn item_for_boxed_slice( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("item_for_boxed_slice") + .original_result() + } + + pub fn item_for_ref< + Arg0: ProxyArg, + >( + self, + _ref: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("item_for_ref") + .argument(&_ref) + .original_result() + } + + pub fn item_for_slice< + Arg0: ProxyArg>, + >( + self, + _ref: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("item_for_slice") + .argument(&_ref) + .original_result() + } + + pub fn item_for_option( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("item_for_option") + .original_result() + } + + pub fn operation_completion_status( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("operation_completion_status") + .original_result() + } + + pub fn payable_egld( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("payable_egld") + .original_result() + } + + pub fn payable_some_token( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("payable_some_token") + .original_result() + } + + pub fn payable_any_token( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("payable_any_token") + .original_result() + } + + pub fn external_view( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("external_view") + .original_result() + } + + pub fn label_a( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("label_a") + .original_result() + } + + pub fn label_b( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("label_b") + .original_result() + } +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpInConstructor { + pub something: (), +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct AbiTestType { + pub nested: OnlyShowsUpAsNested01, + pub next: Option>, + pub tuple_madness: (OnlyShowsUpAsNested02, Option>), +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested01 {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested02 { + pub something: [u8; 0], +} + +#[rustfmt::skip] +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub enum AbiEnum { + Nothing, + Something(i32), + SomethingMore(u8, OnlyShowsUpAsNested08), + SomeStruct { + a: u16, + b: OnlyShowsUpAsNested09, + }, +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested08 {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested09 {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct AbiManagedType +where + Api: ManagedTypeApi, +{ + pub big_uint: BigUint, + pub integer: i32, + pub managed_buffer: ManagedBuffer, +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested03 {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested04 {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested05 {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested06 {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested07 {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNestedInSingleValueMapper {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNestedInVec {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNestedInArrayVec {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, ManagedVecItem)] +pub struct AbiManagedVecItem { + pub value1: u32, + pub value2: u32, +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNestedInArray {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNestedInBox {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNestedInBoxedSlice {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNestedInRef {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNestedInSlice {} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNestedInOption {} + +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub struct OnlyShowsUpInEsdtAttr { + pub field: OnlyShowsUpAsNested10, +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct OnlyShowsUpAsNested10 {} + +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub enum ExplicitDiscriminant { + Zero, + Thirty, + Twelve, + Fifty, + FiftyOne, +} + +#[rustfmt::skip] +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub enum ExplicitDiscriminantMixed { + Zero, + Unit, + Tuple(u16), + Five, + Struct { + a: u8, + b: u16, + }, +} + +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub struct ManagedDecimalWrapper +where + Api: ManagedTypeApi, +{ + pub field: ManagedDecimal>, +} diff --git a/contracts/feature-tests/abi-tester/src/abi_test_type.rs b/contracts/feature-tests/abi-tester/src/abi_test_type.rs index 6ff0fc3de9..2928e81c89 100644 --- a/contracts/feature-tests/abi-tester/src/abi_test_type.rs +++ b/contracts/feature-tests/abi-tester/src/abi_test_type.rs @@ -6,7 +6,8 @@ use multiversx_sc::{ multiversx_sc::derive_imports!(); /// Its only purpose is to test that the ABI generator works fine. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct AbiTestType { /// This type should only appear here. pub nested: OnlyShowsUpAsNested01, @@ -20,7 +21,8 @@ pub struct AbiTestType { } /// Its only purpose is to test that the ABI generator works fine. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct AbiManagedType { pub big_uint: BigUint, pub integer: i32, @@ -28,14 +30,16 @@ pub struct AbiManagedType { } /// Its only purpose is to test that the ABI generator works fine. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi, ManagedVecItem)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, ManagedVecItem)] pub struct AbiManagedVecItem { pub value1: u32, pub value2: u32, } -#[derive(TypeAbi)] +#[type_abi] pub struct OnlyShowsUpInEsdtAttr { + #[allow(dead_code)] pub field: OnlyShowsUpAsNested10, } diff --git a/contracts/feature-tests/abi-tester/src/abi_tester.rs b/contracts/feature-tests/abi-tester/src/abi_tester.rs index ce0b6f82b7..6848f0d237 100644 --- a/contracts/feature-tests/abi-tester/src/abi_tester.rs +++ b/contracts/feature-tests/abi-tester/src/abi_tester.rs @@ -3,6 +3,7 @@ multiversx_sc::imports!(); mod abi_enum; +pub mod abi_proxy; mod abi_test_type; mod only_nested; @@ -32,6 +33,12 @@ pub trait AbiTester { #[payable("EGLD")] fn init(&self, _constructor_arg_1: i32, _constructor_arg_2: OnlyShowsUpInConstructor) {} + /// Upgrade constructor. + #[upgrade] + fn upgrade(&self, _constructor_arg_1: i32, _constructor_arg_2: OnlyShowsUpInConstructor) { + self.init(_constructor_arg_1, _constructor_arg_2) + } + /// Example endpoint docs. #[endpoint] #[output_name("single output")] @@ -160,6 +167,11 @@ pub trait AbiTester { None } + #[view] + fn operation_completion_status(&self) -> OperationCompletionStatus { + OperationCompletionStatus::Completed + } + #[endpoint] #[payable("EGLD")] fn payable_egld(&self) {} diff --git a/contracts/feature-tests/abi-tester/src/only_nested.rs b/contracts/feature-tests/abi-tester/src/only_nested.rs index d1e19441d0..5c960cc95a 100644 --- a/contracts/feature-tests/abi-tester/src/only_nested.rs +++ b/contracts/feature-tests/abi-tester/src/only_nested.rs @@ -1,85 +1,105 @@ multiversx_sc::derive_imports!(); /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpInConstructor { pub something: (), } /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested01; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested02 { pub something: [u8; 0], } /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested03(); /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested04; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested05; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested06; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested07; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested08; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested09; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNested10; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNestedInSingleValueMapper; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNestedInVec; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNestedInArrayVec; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNestedInArray; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNestedInBox; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNestedInBoxedSlice; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNestedInRef; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNestedInSlice; /// Tests that the ABI generator also fetches types that only appear as fields. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct OnlyShowsUpAsNestedInOption; diff --git a/contracts/feature-tests/abi-tester/tests/abi_tester_abi_test.rs b/contracts/feature-tests/abi-tester/tests/abi_tester_abi_test.rs index f4274861de..d4114d316a 100644 --- a/contracts/feature-tests/abi-tester/tests/abi_tester_abi_test.rs +++ b/contracts/feature-tests/abi-tester/tests/abi_tester_abi_test.rs @@ -1,10 +1,10 @@ use std::{fs, fs::File, io::Write}; use multiversx_sc::{ - abi::{EnumVariantDescription, TypeContents}, + abi::{EnumVariantDescription, TypeContents, TypeNames}, contract_base::ContractAbiProvider, }; -use multiversx_sc_meta::{ +use multiversx_sc_meta_lib::{ abi_json::{self, EsdtAttributeAbiJson}, esdt_attr_file_json::serialize_esdt_attribute_json, }; @@ -12,13 +12,12 @@ use multiversx_sc_scenario::ScenarioWorld; #[test] fn abi_tester_abi_generated_ok() { - let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/abi-tester"); + let blockchain = ScenarioWorld::new(); // generate ABI - let multi_contract_config = multiversx_sc_meta::multi_contract_config::( - blockchain.current_dir().as_path(), - ); + let multi_contract_config = multiversx_sc_meta_lib::multi_contract_config::< + abi_tester::AbiProvider, + >(blockchain.current_dir().as_path()); let main_contract = multi_contract_config.find_contract("abi-tester"); assert!(!main_contract.settings.external_view); @@ -71,12 +70,11 @@ fn abi_tester_esdt_attr_abi_generated_ok() { #[test] fn check_multi_contract_config() { - let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/abi-tester"); + let blockchain = ScenarioWorld::new(); - let multi_contract_config = multiversx_sc_meta::multi_contract_config::( - blockchain.current_dir().as_path(), - ); + let multi_contract_config = multiversx_sc_meta_lib::multi_contract_config::< + abi_tester::AbiProvider, + >(blockchain.current_dir().as_path()); let ev_contract = multi_contract_config.find_contract("abi-tester-ev"); assert!(ev_contract.settings.external_view); @@ -89,12 +87,15 @@ fn check_multi_contract_config() { #[test] fn abi_deserialization_check() { let main_json = fs::read_to_string("./abi_tester_expected_main.abi.json").unwrap(); - let main_abi = multiversx_sc_meta::abi_json::deserialize_abi_from_json(&main_json).unwrap(); + let main_abi = multiversx_sc_meta_lib::abi_json::deserialize_abi_from_json(&main_json).unwrap(); let abi_enum_type = main_abi .types .get("AbiEnum") .unwrap() - .to_type_description("AbiEnum"); + .to_type_description(TypeNames { + abi: "AbiEnum".to_string(), + rust: "Enum".to_string(), + }); if let TypeContents::Enum(variants) = abi_enum_type.contents { assert_eq!(variants.len(), 4); assert_eq!( diff --git a/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/Cargo.lock b/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/Cargo.lock index 68b0945a4a..bac560f281 100644 --- a/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/Cargo.lock +++ b/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/Cargo.lock @@ -25,15 +25,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/Cargo.toml b/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/Cargo.toml index f6fa5ff5af..d7ac6245da 100644 --- a/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/Cargo.toml +++ b/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.abi-tester] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/src/lib.rs b/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/src/lib.rs index 5fe18202f2..8569b396ce 100644 --- a/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/src/lib.rs +++ b/contracts/feature-tests/abi-tester/wasm-abi-tester-ev/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 5 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/abi-tester/wasm/Cargo.lock b/contracts/feature-tests/abi-tester/wasm/Cargo.lock index 8f5706541d..d69bdd5bbd 100755 --- a/contracts/feature-tests/abi-tester/wasm/Cargo.lock +++ b/contracts/feature-tests/abi-tester/wasm/Cargo.lock @@ -25,15 +25,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/abi-tester/wasm/Cargo.toml b/contracts/feature-tests/abi-tester/wasm/Cargo.toml index b5171c7792..074956883f 100644 --- a/contracts/feature-tests/abi-tester/wasm/Cargo.toml +++ b/contracts/feature-tests/abi-tester/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.abi-tester] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/abi-tester/wasm/src/lib.rs b/contracts/feature-tests/abi-tester/wasm/src/lib.rs index 6a15c9899b..dcfd861dd0 100644 --- a/contracts/feature-tests/abi-tester/wasm/src/lib.rs +++ b/contracts/feature-tests/abi-tester/wasm/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 27 +// Upgrade: 1 +// Endpoints: 28 // Async Callback (empty): 1 -// Total number of exported functions: 29 +// Total number of exported functions: 31 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -20,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { abi_tester ( init => init + upgrade => upgrade echo_abi_test_type => echo_abi_test_type echo_enum => echo_enum take_managed_type => take_managed_type @@ -44,6 +44,7 @@ multiversx_sc_wasm_adapter::endpoints! { item_for_ref => item_for_ref item_for_slice => item_for_slice item_for_option => item_for_option + operation_completion_status => operation_completion_status payable_egld => payable_egld payable_some_token => payable_some_token payable_any_token => payable_any_token diff --git a/contracts/feature-tests/alloc-features/Cargo.toml b/contracts/feature-tests/alloc-features/Cargo.toml index 3af733d06d..0a892d5458 100644 --- a/contracts/feature-tests/alloc-features/Cargo.toml +++ b/contracts/feature-tests/alloc-features/Cargo.toml @@ -9,12 +9,12 @@ publish = false path = "src/alloc_features_main.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dev-dependencies.esdt-system-sc-mock] diff --git a/contracts/feature-tests/alloc-features/meta/Cargo.toml b/contracts/feature-tests/alloc-features/meta/Cargo.toml index e737db810b..5d9fbe2bb6 100644 --- a/contracts/feature-tests/alloc-features/meta/Cargo.toml +++ b/contracts/feature-tests/alloc-features/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.alloc-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/alloc-features/meta/src/main.rs b/contracts/feature-tests/alloc-features/meta/src/main.rs index 564416ad32..9f02362e27 100644 --- a/contracts/feature-tests/alloc-features/meta/src/main.rs +++ b/contracts/feature-tests/alloc-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/alloc-features/scenarios/sc_result.scen.json b/contracts/feature-tests/alloc-features/scenarios/sc_result.scen.json index a3f22fd47f..b4fac3e261 100644 --- a/contracts/feature-tests/alloc-features/scenarios/sc_result.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/sc_result.scen.json @@ -60,7 +60,7 @@ "tx": { "from": "address:an_account", "to": "sc:alloc-features", - "function": "result_err_from_bytes_1", + "function": "result_err_from_bytes", "arguments": [ "str:test error message" ], @@ -82,7 +82,7 @@ "tx": { "from": "address:an_account", "to": "sc:alloc-features", - "function": "result_err_from_bytes_2", + "function": "result_err_from_bytes", "arguments": [ "str:test error message" ], @@ -104,7 +104,7 @@ "tx": { "from": "address:an_account", "to": "sc:alloc-features", - "function": "result_err_from_bytes_3", + "function": "result_err_from_bytes", "arguments": [ "str:test error message" ], diff --git a/contracts/feature-tests/alloc-features/src/alloc_features_main.rs b/contracts/feature-tests/alloc-features/src/alloc_features_main.rs index d744d2195c..d5a83a1e70 100644 --- a/contracts/feature-tests/alloc-features/src/alloc_features_main.rs +++ b/contracts/feature-tests/alloc-features/src/alloc_features_main.rs @@ -1,5 +1,4 @@ #![no_std] -#![feature(never_type)] multiversx_sc::imports!(); diff --git a/contracts/feature-tests/alloc-features/src/macro_features_legacy.rs b/contracts/feature-tests/alloc-features/src/macro_features_legacy.rs index 1efc5ff38e..0a33d06c05 100644 --- a/contracts/feature-tests/alloc-features/src/macro_features_legacy.rs +++ b/contracts/feature-tests/alloc-features/src/macro_features_legacy.rs @@ -27,18 +27,7 @@ pub trait MacroFeaturesLegacy { } #[view] - fn result_err_from_bytes_1(&self, e: BoxedBytes) -> SCResult<(), ManagedSCError> { - SCResult::Err(e.into())?; - unreachable!() - } - - #[view] - fn result_err_from_bytes_2<'a>(&self, e: &'a [u8]) -> SCResult<(), ManagedSCError> { - SCResult::Err(e.into()) - } - - #[view] - fn result_err_from_bytes_3(&self, e: Vec) -> SCResult<(), ManagedSCError> { + fn result_err_from_bytes(&self, e: BoxedBytes) -> SCResult<(), ManagedSCError> { SCResult::Err(e.into()) } @@ -55,15 +44,13 @@ pub trait MacroFeaturesLegacy { #[endpoint] fn result_echo(&self, arg: Option, test: bool) -> SCResult { require!(test, "test argument is false"); - let unwrapped = - SCResult::::from_result(arg.ok_or("option argument is none"))?; - SCResult::Ok(unwrapped) + + SCResult::::from_result(arg.ok_or("option argument is none")) } #[endpoint] fn result_echo_2(&self, arg: Option) -> SCResult { - let unwrapped = arg.ok_or("option argument is none")?; - SCResult::Ok(unwrapped) + arg.ok_or("option argument is none").into() } #[endpoint] diff --git a/contracts/feature-tests/alloc-features/tests/alloc_features_scenario_rs_test.rs b/contracts/feature-tests/alloc-features/tests/alloc_features_scenario_rs_test.rs index 1d1cee1936..3d3c798e44 100644 --- a/contracts/feature-tests/alloc-features/tests/alloc_features_scenario_rs_test.rs +++ b/contracts/feature-tests/alloc-features/tests/alloc_features_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/alloc-features"); blockchain.register_partial_contract::( "mxsc:output/alloc-features.mxsc.json", diff --git a/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.lock b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.lock index 86a0dd8369..acc0c96da5 100644 --- a/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.lock +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.lock @@ -25,15 +25,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.toml b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.toml index c4a1f55e35..29e5037e2e 100644 --- a/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.toml +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.alloc-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/src/lib.rs b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/src/lib.rs index 675bddb53d..f6acd5959c 100644 --- a/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/src/lib.rs +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/src/lib.rs @@ -5,13 +5,11 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 65 +// Endpoints: 63 // Async Callback (empty): 1 -// Total number of exported functions: 67 +// Total number of exported functions: 65 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -54,9 +52,7 @@ multiversx_sc_wasm_adapter::endpoints! { only_owner_legacy => only_owner_legacy return_sc_error => return_sc_error result_ok => result_ok - result_err_from_bytes_1 => result_err_from_bytes_1 - result_err_from_bytes_2 => result_err_from_bytes_2 - result_err_from_bytes_3 => result_err_from_bytes_3 + result_err_from_bytes => result_err_from_bytes result_err_from_string => result_err_from_string result_err_from_str => result_err_from_str result_echo => result_echo diff --git a/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.lock b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.lock index e6478aa683..1d03996070 100644 --- a/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.lock +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.lock @@ -25,15 +25,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.toml b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.toml index 3380c24cf1..90d20b5f2b 100644 --- a/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.toml +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.alloc-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/src/lib.rs b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/src/lib.rs index 55d2f88725..9056a19d65 100644 --- a/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/src/lib.rs +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/src/lib.rs @@ -5,13 +5,11 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 65 +// Endpoints: 63 // Async Callback (empty): 1 -// Total number of exported functions: 67 +// Total number of exported functions: 65 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(leaking); multiversx_sc_wasm_adapter::panic_handler!(); @@ -54,9 +52,7 @@ multiversx_sc_wasm_adapter::endpoints! { only_owner_legacy => only_owner_legacy return_sc_error => return_sc_error result_ok => result_ok - result_err_from_bytes_1 => result_err_from_bytes_1 - result_err_from_bytes_2 => result_err_from_bytes_2 - result_err_from_bytes_3 => result_err_from_bytes_3 + result_err_from_bytes => result_err_from_bytes result_err_from_string => result_err_from_string result_err_from_str => result_err_from_str result_echo => result_echo diff --git a/contracts/feature-tests/alloc-features/wasm/Cargo.lock b/contracts/feature-tests/alloc-features/wasm/Cargo.lock index 78cd8de067..9b6a2ac16a 100644 --- a/contracts/feature-tests/alloc-features/wasm/Cargo.lock +++ b/contracts/feature-tests/alloc-features/wasm/Cargo.lock @@ -25,15 +25,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/alloc-features/wasm/Cargo.toml b/contracts/feature-tests/alloc-features/wasm/Cargo.toml index 398ff4d589..b1f92d6082 100644 --- a/contracts/feature-tests/alloc-features/wasm/Cargo.toml +++ b/contracts/feature-tests/alloc-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.alloc-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/alloc-features/wasm/src/lib.rs b/contracts/feature-tests/alloc-features/wasm/src/lib.rs index f01cc37f8b..3b8d0b84e3 100644 --- a/contracts/feature-tests/alloc-features/wasm/src/lib.rs +++ b/contracts/feature-tests/alloc-features/wasm/src/lib.rs @@ -5,13 +5,11 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 64 +// Endpoints: 62 // Async Callback (empty): 1 -// Total number of exported functions: 66 +// Total number of exported functions: 64 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); @@ -54,9 +52,7 @@ multiversx_sc_wasm_adapter::endpoints! { only_owner_legacy => only_owner_legacy return_sc_error => return_sc_error result_ok => result_ok - result_err_from_bytes_1 => result_err_from_bytes_1 - result_err_from_bytes_2 => result_err_from_bytes_2 - result_err_from_bytes_3 => result_err_from_bytes_3 + result_err_from_bytes => result_err_from_bytes result_err_from_string => result_err_from_string result_err_from_str => result_err_from_str result_echo => result_echo diff --git a/contracts/feature-tests/basic-features/Cargo.toml b/contracts/feature-tests/basic-features/Cargo.toml index 52a6628859..5ce96ac53b 100644 --- a/contracts/feature-tests/basic-features/Cargo.toml +++ b/contracts/feature-tests/basic-features/Cargo.toml @@ -9,15 +9,15 @@ publish = false path = "src/basic_features_main.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dev-dependencies.esdt-system-sc-mock] diff --git a/contracts/feature-tests/basic-features/interact/Cargo.toml b/contracts/feature-tests/basic-features/interact/Cargo.toml index e761436e47..ca15ae386e 100644 --- a/contracts/feature-tests/basic-features/interact/Cargo.toml +++ b/contracts/feature-tests/basic-features/interact/Cargo.toml @@ -18,5 +18,5 @@ toml = "0.8.6" path = ".." [dependencies.multiversx-sc-snippets] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/snippets" diff --git a/contracts/feature-tests/basic-features/interact/config.toml b/contracts/feature-tests/basic-features/interact/config.toml index b7fe10a560..61ac8dbf87 100644 --- a/contracts/feature-tests/basic-features/interact/config.toml +++ b/contracts/feature-tests/basic-features/interact/config.toml @@ -1 +1 @@ -gateway = 'https://testnet-gateway.multiversx.com' +gateway = 'https://devnet-gateway.multiversx.com' diff --git a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs index ceca3ace12..e8f269cb71 100644 --- a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs +++ b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs @@ -2,26 +2,12 @@ mod bf_interact_cli; mod bf_interact_config; mod bf_interact_state; -use basic_features::{ - storage_direct_load::ProxyTrait as _, storage_direct_store::ProxyTrait as _, ProxyTrait, -}; +use basic_features::basic_features_proxy; use bf_interact_config::Config; use bf_interact_state::State; use clap::Parser; -use multiversx_sc_snippets::{ - env_logger, - multiversx_sc::{codec::multi_types::IgnoreValue, types::Address}, - multiversx_sc_scenario::{ - api::StaticApi, - bech32, - mandos_system::ScenarioRunner, - scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext}, - scenario_model::{BytesValue, ScCallStep, ScDeployStep, Scenario, TxExpect}, - standalone::retrieve_account_as_scenario_set_state, - test_wallets, ContractInfo, - }, - tokio, Interactor, -}; + +use multiversx_sc_snippets::imports::*; const INTERACTOR_SCENARIO_TRACE_PATH: &str = "interactor_trace.scen.json"; @@ -46,7 +32,7 @@ async fn main() { #[allow(unused)] struct BasicFeaturesInteract { interactor: Interactor, - wallet_address: Address, + wallet_address: Bech32Address, code_expr: BytesValue, state: State, large_storage_payload: Vec, @@ -67,7 +53,7 @@ impl BasicFeaturesInteract { Self { interactor, - wallet_address, + wallet_address: wallet_address.into(), code_expr, state: State::load_state(), large_storage_payload: Vec::new(), @@ -84,64 +70,60 @@ impl BasicFeaturesInteract { } async fn set_state(&mut self) { - println!("wallet address: {}", bech32::encode(&self.wallet_address)); - let scenario_raw = retrieve_account_as_scenario_set_state( - Config::load_config().gateway().to_string(), - bech32::encode(&self.wallet_address), - true, - ) - .await; - - let scenario = Scenario::interpret_from(scenario_raw, &InterpreterContext::default()); - - self.interactor.pre_runners.run_scenario(&scenario); - self.interactor.post_runners.run_scenario(&scenario); + println!("wallet address: {}", self.wallet_address); + self.interactor.retrieve_account(&self.wallet_address).await; } async fn deploy(&mut self) { self.set_state().await; - let (new_address, _) = self + let new_address = self .interactor - .sc_deploy_get_result::<_, IgnoreValue>( - ScDeployStep::new() - .call(self.state.default_contract().init()) - .from(&self.wallet_address) - .code(&self.code_expr) - .gas_limit("4,000,000") - .expect(TxExpect::ok().additional_error_message("deploy failed: ")), - ) + .tx() + .from(&self.wallet_address) + .typed(basic_features_proxy::BasicFeaturesProxy) + .init() + .code(&self.code_expr) + .gas(NumExpr("4,000,000")) + .returns(ReturnsNewBech32Address) + .prepare_async() + .run() .await; - let new_address_bech32 = bech32::encode(&new_address); - println!("new address: {new_address_bech32}"); + println!("new address: {new_address}"); - let new_address_expr = format!("bech32:{new_address_bech32}"); - self.state.set_bf_address(&new_address_expr); + self.state.set_bf_address(new_address); } async fn set_large_storage(&mut self, value: &[u8]) { self.interactor - .sc_call( - ScCallStep::new() - .call(self.state.bf_contract().store_bytes(value)) - .from(&self.wallet_address) - .gas_limit("600,000,000") - .expect( - TxExpect::ok() - .additional_error_message("performing store_bytes failed with: "), - ), - ) + .tx() + .from(&self.wallet_address) + .to(self.state.bf_contract()) + .gas(NumExpr("600,000,000")) + .typed(basic_features_proxy::BasicFeaturesProxy) + .store_bytes(value) + .prepare_async() + .run() .await; println!("successfully performed store_bytes"); } async fn print_length(&mut self) { - let data: Vec = self + let data_raw = self .interactor - .quick_query(self.state.bf_contract().load_bytes()) + .query() + .to(self.state.bf_contract()) + .typed(basic_features_proxy::BasicFeaturesProxy) + .load_bytes() + .returns(ReturnsResult) + .prepare_async() + .run() .await; + + let data = data_raw.to_vec(); + println!("retrieved data length: {}", data.len()); if data != self.large_storage_payload { println!("WARNING! Payload mismatch!"); diff --git a/contracts/feature-tests/basic-features/interact/src/bf_interact_state.rs b/contracts/feature-tests/basic-features/interact/src/bf_interact_state.rs index 6e904dd53c..9df12fa02b 100644 --- a/contracts/feature-tests/basic-features/interact/src/bf_interact_state.rs +++ b/contracts/feature-tests/basic-features/interact/src/bf_interact_state.rs @@ -1,22 +1,17 @@ -use crate::{ContractInfo, StaticApi}; +use multiversx_sc_snippets::imports::Bech32Address; use serde::{Deserialize, Serialize}; use std::{ io::{Read, Write}, path::Path, }; -const DEFAULT_CONTRACT_ADDRESS: &str = - "0x0000000000000000000000000000000000000000000000000000000000000000"; - /// State file const STATE_FILE: &str = "state.toml"; -pub type BasicFeaturesContract = ContractInfo>; - /// Multisig Interact state #[derive(Debug, Default, Serialize, Deserialize)] pub struct State { - bf_address: Option, + bf_address: Option, } impl State { @@ -33,22 +28,15 @@ impl State { } /// Sets the contract address - pub fn set_bf_address(&mut self, address: &str) { - self.bf_address = Some(String::from(address)); + pub fn set_bf_address(&mut self, address: Bech32Address) { + self.bf_address = Some(address); } /// Returns the contract - pub fn bf_contract(&self) -> BasicFeaturesContract { - BasicFeaturesContract::new( - self.bf_address - .clone() - .expect("basic-features contract not yet deployed"), - ) - } - - /// Returns the adder contract with default address - pub fn default_contract(&self) -> BasicFeaturesContract { - BasicFeaturesContract::new(DEFAULT_CONTRACT_ADDRESS) + pub fn bf_contract(&self) -> &Bech32Address { + self.bf_address + .as_ref() + .expect("basic-features contract not yet deployed") } } diff --git a/contracts/feature-tests/basic-features/meta/Cargo.toml b/contracts/feature-tests/basic-features/meta/Cargo.toml index 0f728ed49f..6cf2669d8c 100644 --- a/contracts/feature-tests/basic-features/meta/Cargo.toml +++ b/contracts/feature-tests/basic-features/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.basic-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/basic-features/meta/src/main.rs b/contracts/feature-tests/basic-features/meta/src/main.rs index 883e824ce4..482a5fadcf 100644 --- a/contracts/feature-tests/basic-features/meta/src/main.rs +++ b/contracts/feature-tests/basic-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/basic-features/scenarios/managed_vec_array_push.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_vec_array_push.scen.json deleted file mode 100644 index 1412fd5e31..0000000000 --- a/contracts/feature-tests/basic-features/scenarios/managed_vec_array_push.scen.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "steps": [ - { - "step": "setState", - "accounts": { - "sc:basic-features": { - "nonce": "0", - "balance": "0", - "code": "mxsc:../output/basic-features.mxsc.json" - }, - "address:an_account": { - "nonce": "0", - "balance": "0" - } - } - }, - { - "step": "scQuery", - "id": "1", - "tx": { - "to": "sc:basic-features", - "function": "managed_vec_array_push", - "arguments": [ - "", - "str:12345" - ] - }, - "expect": { - "out": [ - "str:12345" - ] - } - }, - { - "step": "scQuery", - "id": "1", - "tx": { - "to": "sc:basic-features", - "function": "managed_vec_array_push", - "arguments": [ - "str:12345", - "str:67890" - ] - }, - "expect": { - "out": [ - "str:1234567890" - ] - } - } - ] -} diff --git a/contracts/feature-tests/basic-features/scenarios/storage_i64_bad.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_i64_bad.scen.json index 74ae9f7bff..d46e1a783a 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_i64_bad.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_i64_bad.scen.json @@ -33,7 +33,7 @@ "expect": { "out": [], "status": "*", - "message": "str:storage decode error: input too long", + "message": "str:storage decode error: argument out of range", "logs": "*", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address.scen.json index ffa1bbb620..3076c1e82b 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address.scen.json @@ -303,6 +303,71 @@ "gas": "*", "refund": "*" } + }, + { + "step": "scCall", + "id": "fill unordered set mapper", + "tx": { + "from": "address:an_account", + "to": "sc:to-be-called", + "function": "fill_unordered_set_mapper", + "arguments": [ + "10" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "contains unordered at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "contains_unordered_at_address", + "arguments": ["5"], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x01" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "get by index at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "get_by_index", + "arguments": [ + "5" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "5" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/basic-features/src/basic_features_main.rs b/contracts/feature-tests/basic-features/src/basic_features_main.rs index 3ce78bc679..0b36bcbf0b 100644 --- a/contracts/feature-tests/basic-features/src/basic_features_main.rs +++ b/contracts/feature-tests/basic-features/src/basic_features_main.rs @@ -1,8 +1,8 @@ #![no_std] -#![feature(never_type)] multiversx_sc::imports!(); +pub mod basic_features_proxy; pub mod big_num_methods; pub mod big_num_operators; pub mod block_info_features; diff --git a/contracts/feature-tests/basic-features/src/basic_features_proxy.rs b/contracts/feature-tests/basic-features/src/basic_features_proxy.rs new file mode 100644 index 0000000000..7131607d8c --- /dev/null +++ b/contracts/feature-tests/basic-features/src/basic_features_proxy.rs @@ -0,0 +1,139 @@ +use multiversx_sc::proxy_imports::*; + +pub struct BasicFeaturesProxy; + +impl TxProxyTrait for BasicFeaturesProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = BasicFeaturesProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + BasicFeaturesProxyMethods { wrapped_tx: tx } + } +} + +pub struct BasicFeaturesProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl BasicFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl BasicFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn load_bytes( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("load_bytes") + .original_result() + } + + pub fn store_bytes< + Arg0: ProxyArg>, + >( + self, + bi: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("store_bytes") + .argument(&bi) + .original_result() + } + + pub fn returns_egld_decimal( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .raw_call("returns_egld_decimal") + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub struct CodecErrorTestType {} + +#[rustfmt::skip] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub enum ExampleEnumWithFields { + Unit, + Newtype(u32), + Tuple(u32, u32), + Struct { + a: u32, + }, +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub enum ExampleEnumSimple { + Variant0, + Variant1, + Variant2, +} + +#[type_abi] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode)] +pub struct TokenAttributesStruct +where + Api: ManagedTypeApi, +{ + pub field_biguint: BigUint, + pub field_u64: u64, + pub field_vec_u32: ManagedVec, +} + +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub struct RgbColor { + pub r: u8, + pub g: u8, + pub b: u8, +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, PartialEq, Eq, Debug, Clone)] +pub struct ExampleStructManaged +where + Api: ManagedTypeApi, +{ + pub big_uint: BigUint, + pub int: u32, + pub bytes: ManagedBuffer, +} diff --git a/contracts/feature-tests/basic-features/src/codec_err_test.rs b/contracts/feature-tests/basic-features/src/codec_err_test.rs index 4fa4da2258..23e21310a6 100644 --- a/contracts/feature-tests/basic-features/src/codec_err_test.rs +++ b/contracts/feature-tests/basic-features/src/codec_err_test.rs @@ -1,20 +1,6 @@ multiversx_sc::imports!(); use crate::types::CodecErrorTestType; -mod encode_err_proxy { - multiversx_sc::imports!(); - use crate::types::CodecErrorTestType; - - #[multiversx_sc::proxy] - pub trait EncodeErrorProxy { - #[init] - fn init(&self, error_arg: CodecErrorTestType); - - #[endpoint] - fn encode_error_method(&self, error_arg: CodecErrorTestType); - } -} - /// Test various serialization errors. #[multiversx_sc::module] pub trait CodecErrorTest { @@ -62,24 +48,17 @@ pub trait CodecErrorTest { fn codec_err_event_data(&self) { self.event_err_data(CodecErrorTestType); } - - #[proxy] - fn encode_err_proxy(&self) -> encode_err_proxy::Proxy; - /// Never actually calls any deploy/upgrade, so it is appropriate in this contract. /// It just covers contract init serialization errors. #[endpoint] fn codec_err_contract_init(&self) { - let _ = self.encode_err_proxy().init(CodecErrorTestType); + let _ = self.tx().raw_deploy().argument(&CodecErrorTestType); } /// Never actually calls any async/sync call, so it is appropriate in this contract. /// It just covers contract call serialization errors. #[endpoint] fn codec_err_contract_call(&self) { - let _ = self - .encode_err_proxy() - .contract(ManagedAddress::zero()) - .encode_error_method(CodecErrorTestType); + let _ = self.tx().raw_call("dummy").argument(&CodecErrorTestType); } } diff --git a/contracts/feature-tests/basic-features/src/managed_vec_features.rs b/contracts/feature-tests/basic-features/src/managed_vec_features.rs index 63aaab5811..6f42d104be 100644 --- a/contracts/feature-tests/basic-features/src/managed_vec_features.rs +++ b/contracts/feature-tests/basic-features/src/managed_vec_features.rs @@ -67,16 +67,6 @@ pub trait ManagedVecFeatures { mv.contains(&item) } - #[endpoint] - fn managed_vec_array_push( - &self, - mut mv: ManagedVec<[u8; 5]>, - item: [u8; 5], - ) -> ManagedVec<[u8; 5]> { - mv.push(item); - mv - } - #[endpoint] fn managed_ref_explicit(&self, mv: ManagedVec, index: usize) -> BigUint { let value: ManagedRef = mv.get(index); diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_get_at_address.rs b/contracts/feature-tests/basic-features/src/storage_mapper_get_at_address.rs index 7970619957..35ef02b905 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_get_at_address.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_get_at_address.rs @@ -86,6 +86,22 @@ pub trait StorageMapperGetAtAddress { mapper.values().collect() } + #[endpoint] + fn contains_unordered_at_address(&self, item: u32) -> bool { + let address = self.contract_address().get(); + let mapper: UnorderedSetMapper = + UnorderedSetMapper::new_from_address(address, StorageKey::from("unordered_set_mapper")); + mapper.contains(&item) + } + + #[endpoint] + fn get_by_index(&self, index: usize) -> u32 { + let address = self.contract_address().get(); + let mapper: UnorderedSetMapper = + UnorderedSetMapper::new_from_address(address, StorageKey::from("unordered_set_mapper")); + mapper.get_by_index(index) + } + /// Storage to be called. For testing, this contract is deployed twice, /// and this module acts both as caller and receiver #[storage_mapper("set_mapper")] @@ -94,6 +110,9 @@ pub trait StorageMapperGetAtAddress { #[storage_mapper("map_mapper")] fn map_mapper(&self) -> MapMapper; + #[storage_mapper("unordered_set_mapper")] + fn unordered_set_mapper(&self) -> UnorderedSetMapper; + #[endpoint] fn fill_set_mapper(&self, value: u32) { for item in 1u32..=value { @@ -108,4 +127,11 @@ pub trait StorageMapperGetAtAddress { self.map_mapper().insert(key, item); } } + + #[endpoint] + fn fill_unordered_set_mapper(&self, value: u32) { + for item in 1u32..=value { + self.unordered_set_mapper().insert(item); + } + } } diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs b/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs index 92963e5c11..4e341f04bd 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_non_fungible_token.rs @@ -1,7 +1,8 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -#[derive(TypeAbi, TopEncode, TopDecode)] +#[type_abi] +#[derive(TopEncode, TopDecode)] pub struct RgbColor { r: u8, g: u8, diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_token_attributes.rs b/contracts/feature-tests/basic-features/src/storage_mapper_token_attributes.rs index 366c6727c9..3a9101055c 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_token_attributes.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_token_attributes.rs @@ -1,7 +1,8 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi)] +#[type_abi] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode)] pub struct TokenAttributesStruct { field_biguint: BigUint, field_u64: u64, diff --git a/contracts/feature-tests/basic-features/src/types/codec_err_test_type.rs b/contracts/feature-tests/basic-features/src/types/codec_err_test_type.rs index 16350f3a5a..41c1524c41 100644 --- a/contracts/feature-tests/basic-features/src/types/codec_err_test_type.rs +++ b/contracts/feature-tests/basic-features/src/types/codec_err_test_type.rs @@ -4,11 +4,11 @@ use multiversx_sc::{ NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, }, - derive::TypeAbi, + derive::type_abi, }; /// Helper type to explore encode/decode errors. -#[derive(TypeAbi)] +#[type_abi] pub struct CodecErrorTestType; impl TopEncode for CodecErrorTestType { diff --git a/contracts/feature-tests/basic-features/src/types/example_enum_simple.rs b/contracts/feature-tests/basic-features/src/types/example_enum_simple.rs index b752f712c6..d75a5309cc 100644 --- a/contracts/feature-tests/basic-features/src/types/example_enum_simple.rs +++ b/contracts/feature-tests/basic-features/src/types/example_enum_simple.rs @@ -1,7 +1,8 @@ multiversx_sc::derive_imports!(); /// Copied from multiversx-sc serialization tests. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub enum ExampleEnumSimple { /// Variant 0 doc comment. /// This will show up in the ABI. diff --git a/contracts/feature-tests/basic-features/src/types/example_enum_with_fields.rs b/contracts/feature-tests/basic-features/src/types/example_enum_with_fields.rs index 246a9ca658..4b5acd7661 100644 --- a/contracts/feature-tests/basic-features/src/types/example_enum_with_fields.rs +++ b/contracts/feature-tests/basic-features/src/types/example_enum_with_fields.rs @@ -1,7 +1,8 @@ multiversx_sc::derive_imports!(); /// Copied from multiversx-sc serialization tests. -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub enum ExampleEnumWithFields { Unit, Newtype(u32), diff --git a/contracts/feature-tests/basic-features/src/types/example_struct_managed.rs b/contracts/feature-tests/basic-features/src/types/example_struct_managed.rs index cf23b5767c..b68060e80b 100644 --- a/contracts/feature-tests/basic-features/src/types/example_struct_managed.rs +++ b/contracts/feature-tests/basic-features/src/types/example_struct_managed.rs @@ -5,9 +5,8 @@ use multiversx_sc::{ multiversx_sc::derive_imports!(); -#[derive( - NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi, PartialEq, Eq, Debug, Clone, -)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, PartialEq, Eq, Debug, Clone)] pub struct ExampleStructManaged { pub big_uint: BigUint, pub int: u32, diff --git a/contracts/feature-tests/basic-features/tests/basic_features_egld_decimal_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_egld_decimal_test.rs index 96a01cfc00..3f9589e01f 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_egld_decimal_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_egld_decimal_test.rs @@ -1,49 +1,34 @@ -use multiversx_sc::types::{ - BigUint, ConstDecimals, ContractCallWithEgld, ManagedAddress, ManagedDecimal, -}; -use multiversx_sc_scenario::{api::StaticApi, scenario_model::*, *}; +use imports::{MxscPath, ReturnsResult, TestAddress, TestSCAddress}; +use multiversx_sc::types::{BigUint, ConstDecimals, ManagedDecimal}; +use multiversx_sc_scenario::{api::StaticApi, imports, ScenarioTxRun, ScenarioWorld}; -const BASIC_FEATURES_PATH_EXPR: &str = "file:../output/basic-features.wasm"; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const BASIC_FEATURES_ADDRESS_EXPR: &str = "sc:basic-features"; - -type BasicFeatures = ContractInfo>; +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const BASIC_FEATURES_ADDRESS: TestSCAddress = TestSCAddress::new("basic-features"); +const BASIC_FEATURES_PATH: MxscPath = MxscPath::new("output/basic-features.mxsc.json"); struct BasicFeaturesState { world: ScenarioWorld, - basic_features: BasicFeatures, } impl BasicFeaturesState { fn new() -> Self { let mut world = world(); - let basic_features_code = world.code_expression(BASIC_FEATURES_PATH_EXPR); - - world.set_state_step( - SetStateStep::new() - .put_account( - OWNER_ADDRESS_EXPR, - Account::new().nonce(1).balance(BigUintValue::from(100u64)), - ) - .put_account( - BASIC_FEATURES_ADDRESS_EXPR, - Account::new().nonce(1).code(basic_features_code), - ), - ); + let basic_features_code = + world.code_expression(BASIC_FEATURES_PATH.eval_to_expr().as_str()); - let basic_features = BasicFeatures::new(BASIC_FEATURES_ADDRESS_EXPR); + world.account(OWNER_ADDRESS).nonce(1).balance(100); + world + .account(BASIC_FEATURES_ADDRESS) + .nonce(1) + .code(basic_features_code); - Self { - world, - basic_features, - } + Self { world } } } fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/basic-features"); - blockchain.register_contract(BASIC_FEATURES_PATH_EXPR, basic_features::ContractBuilder); + blockchain.register_contract(BASIC_FEATURES_PATH, basic_features::ContractBuilder); blockchain } @@ -51,19 +36,19 @@ fn world() -> ScenarioWorld { fn egld_decimal_blackbox_test() { let mut state = BasicFeaturesState::new(); - let sc_call = - ContractCallWithEgld::>>::new( - ManagedAddress::from(state.basic_features.to_address()), - "returns_egld_decimal", - BigUint::from(5u64), - ); - - let egld_decimal: ManagedDecimal> = state + let egld_decimal_result = state .world - .sc_call_get_result(ScCallStep::new().call(sc_call).from("address:owner")); + .tx() + .from(OWNER_ADDRESS) + .to(BASIC_FEATURES_ADDRESS) + .typed(basic_features::basic_features_proxy::BasicFeaturesProxy) + .returns_egld_decimal() + .egld(5) + .returns(ReturnsResult) + .run(); assert_eq!( - egld_decimal, + egld_decimal_result, ManagedDecimal::>::const_decimals_from_raw(BigUint::from( 5u64 )) diff --git a/contracts/feature-tests/basic-features/tests/basic_features_is_builtin_function_rs_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_is_builtin_function_rs_test.rs index 836cdd5a9c..d2cc2d269b 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_is_builtin_function_rs_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_is_builtin_function_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/basic-features"); blockchain.register_contract( "mxsc:output/basic-features.mxsc.json", diff --git a/contracts/feature-tests/basic-features/tests/basic_features_managed_buffer_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_managed_buffer_test.rs index cde4caa56e..88320b17f6 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_managed_buffer_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_managed_buffer_test.rs @@ -1,5 +1,4 @@ -use multiversx_sc::types::{ManagedAddress, ManagedBuffer}; -use multiversx_sc_scenario::{api::StaticApi, *}; +use multiversx_sc_scenario::imports::*; use basic_features::managed_buffer_features::ManagedBufferFeatures; diff --git a/contracts/feature-tests/basic-features/tests/basic_features_managed_decimal_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_managed_decimal_test.rs index 42473aec9b..d4257fe078 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_managed_decimal_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_managed_decimal_test.rs @@ -2,13 +2,10 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/basic-features"); - blockchain.register_contract( "mxsc:output/basic-features.mxsc.json", basic_features::ContractBuilder, ); - blockchain } diff --git a/contracts/feature-tests/basic-features/tests/basic_features_managed_vec_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_managed_vec_test.rs index 62790660d0..fccc91e431 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_managed_vec_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_managed_vec_test.rs @@ -1,5 +1,4 @@ -use multiversx_sc::types::{BigUint, ManagedVec}; -use multiversx_sc_scenario::{api::StaticApi, *}; +use multiversx_sc_scenario::imports::*; use basic_features::managed_vec_features::ManagedVecFeatures; diff --git a/contracts/feature-tests/basic-features/tests/basic_features_ordered_binary_tree_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_ordered_binary_tree_test.rs index 071da4a958..fe48caecba 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_ordered_binary_tree_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_ordered_binary_tree_test.rs @@ -1,10 +1,8 @@ #![allow(deprecated)] use basic_features::BasicFeatures; -use multiversx_sc::imports::{OrderedBinaryTreeNode, NULL_NODE_ID}; -use multiversx_sc_scenario::{ - managed_biguint, rust_biguint, testing_framework::BlockchainStateWrapper, -}; + +use multiversx_sc_scenario::imports::*; #[test] fn ordered_binary_tree_test() { diff --git a/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs index 3c75401525..6ef518cf9f 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_scenario_go_test.rs @@ -255,11 +255,6 @@ fn managed_vec_address_push_go() { world().run("scenarios/managed_vec_address_push.scen.json"); } -#[test] -fn managed_vec_array_push_go() { - world().run("scenarios/managed_vec_array_push.scen.json"); -} - #[test] fn managed_vec_biguint_push_go() { world().run("scenarios/managed_vec_biguint_push.scen.json"); diff --git a/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs index 0129da845e..48762ce617 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/basic-features"); blockchain.register_contract( "mxsc:output/basic-features.mxsc.json", @@ -271,11 +270,6 @@ fn managed_vec_address_push_rs() { world().run("scenarios/managed_vec_address_push.scen.json"); } -#[test] -fn managed_vec_array_push_rs() { - world().run("scenarios/managed_vec_array_push.scen.json"); -} - #[test] fn managed_vec_biguint_push_rs() { world().run("scenarios/managed_vec_biguint_push.scen.json"); diff --git a/contracts/feature-tests/basic-features/tests/basic_features_token_identifier_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_token_identifier_test.rs index 3b85d24b4f..8cfe9ba2d2 100644 --- a/contracts/feature-tests/basic-features/tests/basic_features_token_identifier_test.rs +++ b/contracts/feature-tests/basic-features/tests/basic_features_token_identifier_test.rs @@ -1,5 +1,4 @@ -use multiversx_sc::types::{EgldOrEsdtTokenIdentifier, ManagedBuffer, TokenIdentifier}; -use multiversx_sc_scenario::{api::StaticApi, *}; +use multiversx_sc_scenario::imports::*; use basic_features::token_identifier_features::TokenIdentifierFeatures; diff --git a/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/Cargo.lock b/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/Cargo.lock index fd4d59761c..8a3c056b0d 100644 --- a/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/Cargo.lock +++ b/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/Cargo.lock @@ -10,9 +10,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "basic-features" @@ -32,9 +32,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -56,26 +56,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +87,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,14 +98,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/Cargo.toml b/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/Cargo.toml index 22d26cd5d5..9b97339220 100644 --- a/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/Cargo.toml +++ b/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.basic-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/src/lib.rs b/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/src/lib.rs index af26877c00..94dd839f14 100644 --- a/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/src/lib.rs +++ b/contracts/feature-tests/basic-features/wasm-basic-features-storage-bytes/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/basic-features/wasm/Cargo.lock b/contracts/feature-tests/basic-features/wasm/Cargo.lock index e4bb971005..e2f26179b1 100755 --- a/contracts/feature-tests/basic-features/wasm/Cargo.lock +++ b/contracts/feature-tests/basic-features/wasm/Cargo.lock @@ -10,9 +10,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "basic-features" @@ -32,9 +32,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -56,26 +56,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +87,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,14 +98,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/basic-features/wasm/Cargo.toml b/contracts/feature-tests/basic-features/wasm/Cargo.toml index 5b2c30319d..e216d4cd5f 100644 --- a/contracts/feature-tests/basic-features/wasm/Cargo.toml +++ b/contracts/feature-tests/basic-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = true +[profile.dev] +panic = "abort" + [dependencies.basic-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/basic-features/wasm/src/lib.rs b/contracts/feature-tests/basic-features/wasm/src/lib.rs index 3982c3a723..07b590d9f6 100644 --- a/contracts/feature-tests/basic-features/wasm/src/lib.rs +++ b/contracts/feature-tests/basic-features/wasm/src/lib.rs @@ -5,13 +5,11 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 384 +// Endpoints: 395 // Async Callback: 1 -// Total number of exported functions: 386 +// Total number of exported functions: 397 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -218,7 +216,6 @@ multiversx_sc_wasm_adapter::endpoints! { managed_vec_remove => managed_vec_remove managed_vec_find => managed_vec_find managed_vec_contains => managed_vec_contains - managed_vec_array_push => managed_vec_array_push managed_ref_explicit => managed_ref_explicit storage_read_raw => storage_read_raw storage_write_raw => storage_write_raw @@ -406,13 +403,16 @@ multiversx_sc_wasm_adapter::endpoints! { back_at_address => back_at_address keys_at_address => keys_at_address values_at_address => values_at_address + contains_unordered_at_address => contains_unordered_at_address + get_by_index => get_by_index fill_set_mapper => fill_set_mapper + fill_map_mapper => fill_map_mapper + fill_unordered_set_mapper => fill_unordered_set_mapper managed_decimal_addition => managed_decimal_addition managed_decimal_subtraction => managed_decimal_subtraction managed_decimal_eq => managed_decimal_eq managed_decimal_trunc => managed_decimal_trunc managed_decimal_into_raw_units => managed_decimal_into_raw_units - fill_map_mapper => fill_map_mapper ) } diff --git a/contracts/feature-tests/big-float-features/Cargo.toml b/contracts/feature-tests/big-float-features/Cargo.toml index 3444fe9e30..4f745603da 100644 --- a/contracts/feature-tests/big-float-features/Cargo.toml +++ b/contracts/feature-tests/big-float-features/Cargo.toml @@ -9,11 +9,11 @@ publish = false path = "src/big_float_main.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dev-dependencies.esdt-system-sc-mock] diff --git a/contracts/feature-tests/big-float-features/meta/Cargo.toml b/contracts/feature-tests/big-float-features/meta/Cargo.toml index 9d7b7d3850..13aaa4c639 100644 --- a/contracts/feature-tests/big-float-features/meta/Cargo.toml +++ b/contracts/feature-tests/big-float-features/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.big-float-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/big-float-features/meta/src/main.rs b/contracts/feature-tests/big-float-features/meta/src/main.rs index 5f01181a29..5e5895e70c 100644 --- a/contracts/feature-tests/big-float-features/meta/src/main.rs +++ b/contracts/feature-tests/big-float-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/big-float-features/tests/big_float_scenario_rs_test.rs b/contracts/feature-tests/big-float-features/tests/big_float_scenario_rs_test.rs index 439c098def..66ca09ab86 100644 --- a/contracts/feature-tests/big-float-features/tests/big_float_scenario_rs_test.rs +++ b/contracts/feature-tests/big-float-features/tests/big_float_scenario_rs_test.rs @@ -3,7 +3,6 @@ use multiversx_sc_scenario::{api::StaticApi, *}; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/big-float-features"); blockchain.register_contract( "mxsc:output/big-float-features.mxsc.json", diff --git a/contracts/feature-tests/big-float-features/wasm/Cargo.lock b/contracts/feature-tests/big-float-features/wasm/Cargo.lock index 8de5fab712..d694885d17 100644 --- a/contracts/feature-tests/big-float-features/wasm/Cargo.lock +++ b/contracts/feature-tests/big-float-features/wasm/Cargo.lock @@ -10,9 +10,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "big-float-features" @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/big-float-features/wasm/Cargo.toml b/contracts/feature-tests/big-float-features/wasm/Cargo.toml index e62efe10e7..37b666405d 100644 --- a/contracts/feature-tests/big-float-features/wasm/Cargo.toml +++ b/contracts/feature-tests/big-float-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.big-float-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/big-float-features/wasm/src/lib.rs b/contracts/feature-tests/big-float-features/wasm/src/lib.rs index 1219ed8ad0..6ec41ff9e9 100644 --- a/contracts/feature-tests/big-float-features/wasm/src/lib.rs +++ b/contracts/feature-tests/big-float-features/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 72 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/Cargo.toml b/contracts/feature-tests/composability/Cargo.toml index d9ae0995ca..33f3dfe9c4 100644 --- a/contracts/feature-tests/composability/Cargo.toml +++ b/contracts/feature-tests/composability/Cargo.toml @@ -11,6 +11,9 @@ path = "builtin-func-features" [dev-dependencies.forwarder] path = "forwarder" +[dev-dependencies.forwarder-legacy] +path = "forwarder-legacy" + [dev-dependencies.forwarder-queue] path = "forwarder-queue" @@ -33,9 +36,9 @@ path = "recursive-caller" path = "vault" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/feature-tests/composability/builtin-func-features/Cargo.toml b/contracts/feature-tests/composability/builtin-func-features/Cargo.toml index c3f3d304ed..1e74ef58f9 100644 --- a/contracts/feature-tests/composability/builtin-func-features/Cargo.toml +++ b/contracts/feature-tests/composability/builtin-func-features/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/builtin_func_features.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/builtin-func-features/meta/Cargo.toml b/contracts/feature-tests/composability/builtin-func-features/meta/Cargo.toml index ab7adb1818..272016644a 100644 --- a/contracts/feature-tests/composability/builtin-func-features/meta/Cargo.toml +++ b/contracts/feature-tests/composability/builtin-func-features/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.builtin-func-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/builtin-func-features/meta/src/main.rs b/contracts/feature-tests/composability/builtin-func-features/meta/src/main.rs index 2f9740634f..2b091f5799 100644 --- a/contracts/feature-tests/composability/builtin-func-features/meta/src/main.rs +++ b/contracts/feature-tests/composability/builtin-func-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/builtin-func-features/src/builtin_func_features.rs b/contracts/feature-tests/composability/builtin-func-features/src/builtin_func_features.rs index 81df199e68..de33932a9e 100644 --- a/contracts/feature-tests/composability/builtin-func-features/src/builtin_func_features.rs +++ b/contracts/feature-tests/composability/builtin-func-features/src/builtin_func_features.rs @@ -1,31 +1,28 @@ #![no_std] -pub mod builtin_func_proxy; - multiversx_sc::imports!(); /// Test contract for investigating async calls. #[multiversx_sc::contract] pub trait BuiltinFuncFeatures { - #[proxy] - fn builtin_func_proxy(&self, to: ManagedAddress) -> builtin_func_proxy::Proxy; - #[init] fn init(&self) {} #[endpoint] fn call_set_user_name(&self, address: ManagedAddress, name: ManagedBuffer) { - self.builtin_func_proxy(address) - .set_user_name(&name) - .async_call() - .call_and_exit() + self.tx() + .to(&address) + .typed(system_proxy::UserBuiltinProxy) + .set_user_name(name) + .async_call_and_exit() } #[endpoint] fn call_delete_user_name(&self, address: ManagedAddress) { - self.builtin_func_proxy(address) + self.tx() + .to(&address) + .typed(system_proxy::UserBuiltinProxy) .delete_user_name() - .async_call() - .call_and_exit(); + .async_call_and_exit() } } diff --git a/contracts/feature-tests/composability/builtin-func-features/src/builtin_func_proxy.rs b/contracts/feature-tests/composability/builtin-func-features/src/builtin_func_proxy.rs deleted file mode 100644 index 5499deee5e..0000000000 --- a/contracts/feature-tests/composability/builtin-func-features/src/builtin_func_proxy.rs +++ /dev/null @@ -1,10 +0,0 @@ -multiversx_sc::imports!(); - -#[multiversx_sc::derive::proxy] -pub trait UserBuiltin { - #[endpoint(SetUserName)] - fn set_user_name(&self, name: &ManagedBuffer); - - #[endpoint(DeleteUserName)] - fn delete_user_name(&self); -} diff --git a/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.lock b/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.lock index 4e9e07752c..c7c6efa6c9 100644 --- a/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "builtin-func-features" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.toml b/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.toml index fb43fc2f21..2ee4f9c664 100644 --- a/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.builtin-func-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/builtin-func-features/wasm/src/lib.rs b/contracts/feature-tests/composability/builtin-func-features/wasm/src/lib.rs index b6175c29b0..832df1781b 100644 --- a/contracts/feature-tests/composability/builtin-func-features/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/builtin-func-features/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/esdt-contract-pair/Cargo.toml b/contracts/feature-tests/composability/esdt-contract-pair/Cargo.toml index d5cae9e497..64af863597 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/Cargo.toml +++ b/contracts/feature-tests/composability/esdt-contract-pair/Cargo.toml @@ -12,9 +12,9 @@ path = "first-contract" path = "second-contract" [dev-dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/Cargo.toml b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/Cargo.toml index 710f03fd71..8b0d3678a2 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/Cargo.toml +++ b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/Cargo.toml @@ -8,12 +8,11 @@ publish = false [lib] path = "src/lib.rs" - [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/meta/Cargo.toml b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/meta/Cargo.toml index c2449efbf6..4a5d2ad11e 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/meta/Cargo.toml +++ b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/meta/Cargo.toml @@ -8,10 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/meta/src/main.rs b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/meta/src/main.rs index d40ed0c2cc..103f097eea 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/meta/src/main.rs +++ b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs index dfa6ff75e5..2d35ac5ea8 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs +++ b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/src/lib.rs @@ -2,9 +2,9 @@ multiversx_sc::imports!(); -const ESDT_TRANSFER_STRING: &[u8] = b"ESDTTransfer"; -const SECOND_CONTRACT_ACCEPT_ESDT_PAYMENT: &[u8] = b"acceptEsdtPayment"; -const SECOND_CONTRACT_REJECT_ESDT_PAYMENT: &[u8] = b"rejectEsdtPayment"; +const ESDT_TRANSFER_STRING: &str = "ESDTTransfer"; +const SECOND_CONTRACT_ACCEPT_ESDT_PAYMENT: &str = "acceptEsdtPayment"; +const SECOND_CONTRACT_REJECT_ESDT_PAYMENT: &str = "rejectEsdtPayment"; #[multiversx_sc::contract] pub trait FirstContract { @@ -90,14 +90,13 @@ pub trait FirstContract { "Wrong esdt token" ); - let _ = self.send_raw().transfer_esdt_execute( - &second_contract_address, - &expected_token_identifier, - &esdt_value, - self.blockchain().get_gas_left(), - &ManagedBuffer::from(SECOND_CONTRACT_REJECT_ESDT_PAYMENT), - &ManagedArgBuffer::new(), - ); + let gas_left = self.blockchain().get_gas_left(); + self.tx() + .to(&second_contract_address) + .gas(gas_left) + .raw_call(SECOND_CONTRACT_REJECT_ESDT_PAYMENT) + .single_esdt(&expected_token_identifier, 0u64, &esdt_value) + .transfer_execute(); } #[payable("*")] @@ -112,14 +111,13 @@ pub trait FirstContract { "Wrong esdt token" ); - let _ = self.send_raw().transfer_esdt_execute( - &second_contract_address, - &expected_token_identifier, - &esdt_value, - self.blockchain().get_gas_left(), - &ManagedBuffer::from(SECOND_CONTRACT_ACCEPT_ESDT_PAYMENT), - &ManagedArgBuffer::new(), - ); + let gas_left = self.blockchain().get_gas_left(); + self.tx() + .to(&second_contract_address) + .gas(gas_left) + .raw_call(SECOND_CONTRACT_ACCEPT_ESDT_PAYMENT) + .single_esdt(&expected_token_identifier, 0u64, &esdt_value) + .transfer_execute(); } fn call_esdt_second_contract( @@ -138,12 +136,11 @@ pub trait FirstContract { arg_buffer.push_arg_raw(arg); } - self.send_raw().async_call_raw( - to, - &BigUint::zero(), - &ManagedBuffer::from(ESDT_TRANSFER_STRING), - &arg_buffer, - ); + self.tx() + .to(to) + .raw_call(ESDT_TRANSFER_STRING) + .arguments_raw(arg_buffer) + .async_call_and_exit(); } // storage diff --git a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/Cargo.lock b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/Cargo.lock index c38b6fb0ce..334d6e5acc 100755 --- a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/Cargo.toml b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/Cargo.toml index 544a09a21e..f045ce6899 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.first-contract] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/src/lib.rs b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/src/lib.rs index 163070bd0a..d9f268f9e4 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/esdt-contract-pair/first-contract/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 9 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/Cargo.toml b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/Cargo.toml index 6d5c7636d0..5456487df0 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/Cargo.toml +++ b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/Cargo.toml @@ -10,10 +10,10 @@ path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/meta/Cargo.toml b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/meta/Cargo.toml index 144cff2dbc..2ea12ab49f 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/meta/Cargo.toml +++ b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/meta/Cargo.toml @@ -8,10 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/meta/src/main.rs b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/meta/src/main.rs index 270dd07b1a..690311c6df 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/meta/src/main.rs +++ b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/Cargo.lock b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/Cargo.lock index b6b9fc008d..98cb1a7ec8 100755 --- a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/Cargo.toml b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/Cargo.toml index 6a878e1822..950c3a44fc 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.second-contract] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/src/lib.rs b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/src/lib.rs index 574e5e91d2..98c500b82d 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/esdt-contract-pair/second-contract/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 5 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/Cargo.toml b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/Cargo.toml index 298cc38ea3..c374d4135d 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/Cargo.toml +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/Cargo.toml @@ -16,9 +16,9 @@ path = "parent" path = "child" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/Cargo.toml b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/Cargo.toml index f1bd614d0b..0f60e6e736 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/Cargo.toml +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/Cargo.toml @@ -10,9 +10,9 @@ path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta/Cargo.toml b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta/Cargo.toml index 159ee29fa7..dd4352ccf2 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta/Cargo.toml +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta/Cargo.toml @@ -8,10 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta/src/main.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta/src/main.rs index 84abd4cae4..765eadcb7d 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta/src/main.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/sc-config.toml b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/sc-config.toml new file mode 100644 index 0000000000..14d4385ae3 --- /dev/null +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "../parent/src/child_proxy.rs" diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs index 3126cdbfd8..e763a222af 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/src/lib.rs @@ -37,9 +37,8 @@ pub trait Child { can_add_special_roles: true, }, ) - .async_call() .with_callback(self.callbacks().esdt_issue_callback()) - .call_and_exit() + .async_call_and_exit() } // callbacks diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/Cargo.lock b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/Cargo.lock index 1fcf243263..e5e29b685b 100755 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "child" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/Cargo.toml b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/Cargo.toml index 8737c18b6a..601687a269 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.child] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/src/lib.rs index 0610352c5f..53bbaadccd 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/child/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/Cargo.toml b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/Cargo.toml index 7062232070..311bb0c805 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/Cargo.toml +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/Cargo.toml @@ -8,15 +8,11 @@ publish = false [lib] path = "src/lib.rs" - -[dependencies.child] -path = "../child" - [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/meta/Cargo.toml b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/meta/Cargo.toml index 5649f09d1f..27c42d4b62 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/meta/Cargo.toml +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/meta/Cargo.toml @@ -8,10 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/meta/src/main.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/meta/src/main.rs index c62ef2dbe0..99ed37ffd7 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/meta/src/main.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/child_proxy.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/child_proxy.rs new file mode 100644 index 0000000000..3f60b0cc2e --- /dev/null +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/child_proxy.rs @@ -0,0 +1,91 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct ChildProxy; + +impl TxProxyTrait for ChildProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = ChildProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + ChildProxyMethods { wrapped_tx: tx } + } +} + +pub struct ChildProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl ChildProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl ChildProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn issue_wrapped_egld< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + initial_supply: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("issueWrappedEgld") + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&initial_supply) + .original_result() + } + + pub fn wrapped_egld_token_identifier( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getWrappedEgldTokenIdentifier") + .original_result() + } +} diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs index ddb8a09a09..5c4bff50d0 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/src/lib.rs @@ -2,14 +2,13 @@ multiversx_sc::imports!(); +pub mod child_proxy; + // Base cost for standalone + estimate cost of actual sc call const ISSUE_EXPECTED_GAS_COST: u64 = 90_000_000 + 25_000_000; #[multiversx_sc::contract] pub trait Parent { - #[proxy] - fn child_proxy(&self, to: ManagedAddress) -> child::Proxy; - #[init] fn init(&self) {} @@ -19,13 +18,14 @@ pub trait Parent { #[endpoint(deployChildContract)] fn deploy_child_contract(&self, code: ManagedBuffer) { - let (child_contract_address, _) = self.send_raw().deploy_contract( - self.blockchain().get_gas_left(), - &BigUint::zero(), - &code, - CodeMetadata::DEFAULT, - &ManagedArgBuffer::new(), - ); + let gas_left = self.blockchain().get_gas_left(); + let child_contract_address = self + .tx() + .raw_deploy() + .code(code) + .gas(gas_left) + .returns(ReturnsNewManagedAddress) + .sync_call(); self.child_contract_address().set(&child_contract_address); } @@ -40,12 +40,14 @@ pub trait Parent { ) { let issue_cost = self.call_value().egld_value(); let child_contract_adress = self.child_contract_address().get(); - let _: IgnoreValue = self - .child_proxy(child_contract_adress) + + self.tx() + .to(&child_contract_adress) + .typed(child_proxy::ChildProxy) .issue_wrapped_egld(token_display_name, token_ticker, initial_supply) - .with_egld_transfer(issue_cost.clone_value()) - .with_gas_limit(ISSUE_EXPECTED_GAS_COST) - .execute_on_dest_context(); + .egld(issue_cost) + .gas(ISSUE_EXPECTED_GAS_COST) + .sync_call(); } // storage diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/Cargo.lock b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/Cargo.lock index a1695205f6..5df8629850 100755 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/Cargo.lock @@ -10,22 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "child" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -47,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -76,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -87,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,9 +98,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -114,7 +109,6 @@ dependencies = [ name = "parent" version = "0.0.0" dependencies = [ - "child", "multiversx-sc", ] @@ -128,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/Cargo.toml b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/Cargo.toml index 38c12cb392..b06bd997cc 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.parent] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/src/lib.rs b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/src/lib.rs index 6af21719dc..2f027b22cd 100644 --- a/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/execute-on-dest-esdt-issue-callback/parent/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 6 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/forwarder-legacy/Cargo.toml b/contracts/feature-tests/composability/forwarder-legacy/Cargo.toml new file mode 100644 index 0000000000..b4b6c5a6e7 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-legacy/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "forwarder-legacy" +version = "0.0.0" +authors = ["Andrei Marinica "] +edition = "2021" +publish = false + +[lib] +path = "src/forwarder_legacy_main.rs" + +[dependencies.vault] +path = "../vault" + +[dependencies.multiversx-sc] +version = "0.50.3" +path = "../../../../framework/base" + +[dev-dependencies.multiversx-sc-scenario] +version = "0.50.3" +path = "../../../../framework/scenario" + diff --git a/contracts/feature-tests/composability/forwarder-legacy/meta/Cargo.toml b/contracts/feature-tests/composability/forwarder-legacy/meta/Cargo.toml new file mode 100644 index 0000000000..3576da56da --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-legacy/meta/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "forwarder-legacy-meta" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies.forwarder-legacy] +path = ".." + +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" +default-features = false diff --git a/contracts/feature-tests/composability/forwarder-legacy/meta/src/main.rs b/contracts/feature-tests/composability/forwarder-legacy/meta/src/main.rs new file mode 100644 index 0000000000..693a01816f --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-legacy/meta/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + multiversx_sc_meta_lib::cli_main::(); +} diff --git a/contracts/feature-tests/composability/forwarder-legacy/multiversx.json b/contracts/feature-tests/composability/forwarder-legacy/multiversx.json new file mode 100644 index 0000000000..8d77ca316c --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-legacy/multiversx.json @@ -0,0 +1,3 @@ +{ + "language": "rust" +} diff --git a/contracts/feature-tests/composability/forwarder-legacy/src/forwarder_legacy_main.rs b/contracts/feature-tests/composability/forwarder-legacy/src/forwarder_legacy_main.rs new file mode 100644 index 0000000000..39683249b2 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-legacy/src/forwarder_legacy_main.rs @@ -0,0 +1,42 @@ +#![no_std] +#![allow(clippy::type_complexity)] +#![allow(clippy::let_unit_value)] +#![allow(deprecated)] + +pub mod fwd_call_async_legacy; +pub mod fwd_call_sync_legacy; +pub mod fwd_call_transf_exec_legacy; +pub mod fwd_change_owner_legacy; +pub mod fwd_deploy_legacy; +pub mod fwd_esdt_legacy; +pub mod fwd_nft_legacy; +pub mod fwd_roles_legacy; +pub mod fwd_sft_legacy; +pub mod fwd_storage_legacy; +pub mod fwd_upgrade_legacy; + +multiversx_sc::imports!(); + +/// Test contract for investigating backwards compatibility in smart contract calls. +#[multiversx_sc::contract] +pub trait ForwarderLegacy: + fwd_call_sync_legacy::ForwarderSyncCallModule + + fwd_call_async_legacy::ForwarderAsyncCallModule + + fwd_call_transf_exec_legacy::ForwarderTransferExecuteModule + + fwd_change_owner_legacy::ChangeOwnerModule + + fwd_deploy_legacy::DeployContractModule + + fwd_upgrade_legacy::UpgradeContractModule + + fwd_esdt_legacy::ForwarderEsdtModule + + fwd_sft_legacy::ForwarderSftModule + + fwd_nft_legacy::ForwarderNftModule + + fwd_roles_legacy::ForwarderRolesModule + + fwd_storage_legacy::ForwarderStorageModule +{ + #[init] + fn init(&self) {} + + #[endpoint] + fn send_egld(&self, to: &ManagedAddress, amount: &BigUint) { + self.send().direct_egld(to, amount); + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/call_async.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_async_legacy.rs similarity index 100% rename from contracts/feature-tests/composability/forwarder/src/call_async.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_async_legacy.rs diff --git a/contracts/feature-tests/composability/forwarder/src/call_sync.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_sync_legacy.rs similarity index 100% rename from contracts/feature-tests/composability/forwarder/src/call_sync.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_sync_legacy.rs diff --git a/contracts/feature-tests/composability/forwarder/src/call_transf_exec.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_transf_exec_legacy.rs similarity index 82% rename from contracts/feature-tests/composability/forwarder/src/call_transf_exec.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_transf_exec_legacy.rs index e402ea5316..e789e4644f 100644 --- a/contracts/feature-tests/composability/forwarder/src/call_transf_exec.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_call_transf_exec_legacy.rs @@ -18,6 +18,20 @@ pub trait ForwarderTransferExecuteModule { .transfer_execute(); } + /// Tests triple as ESDTTokenPayment. + /// + /// TODO: move somewhere else after release + #[endpoint] + #[payable("*")] + fn forward_transf_exec_accept_single_esdt(&self, to: ManagedAddress) { + let payment = self.call_value().single_esdt(); + self.vault_proxy() + .contract(to) + .accept_funds() + .payment((payment.token_identifier, 0, payment.amount)) + .transfer_execute(); + } + #[endpoint] #[payable("*")] fn forward_transf_execu_accept_funds_with_fees( @@ -109,6 +123,27 @@ pub trait ForwarderTransferExecuteModule { .transfer_execute() } + #[endpoint] + fn transf_exec_multi_accept_funds_v2( + &self, + to: ManagedAddress, + token_payments: MultiValueEncoded>, + ) { + let mut tx = self + .vault_proxy() + .contract(to) + .accept_funds() + .multi_esdt(()); + + for multi_arg in token_payments.into_iter() { + let (token_identifier, token_nonce, amount) = multi_arg.into_tuple(); + let payment_triple = (token_identifier, token_nonce, amount); + tx = tx.with_esdt_transfer(payment_triple); + } + + tx.transfer_execute() + } + #[endpoint] fn forward_transf_exec_reject_funds_multi_transfer( &self, diff --git a/contracts/feature-tests/composability/forwarder/src/contract_change_owner.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_change_owner_legacy.rs similarity index 100% rename from contracts/feature-tests/composability/forwarder/src/contract_change_owner.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_change_owner_legacy.rs diff --git a/contracts/feature-tests/composability/forwarder/src/contract_deploy.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_deploy_legacy.rs similarity index 100% rename from contracts/feature-tests/composability/forwarder/src/contract_deploy.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_deploy_legacy.rs diff --git a/contracts/feature-tests/composability/forwarder/src/esdt.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs similarity index 98% rename from contracts/feature-tests/composability/forwarder/src/esdt.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs index ed809e514a..b56db69bb8 100644 --- a/contracts/feature-tests/composability/forwarder/src/esdt.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_esdt_legacy.rs @@ -1,6 +1,6 @@ multiversx_sc::imports!(); -use super::storage; +use super::fwd_storage_legacy; const PERCENTAGE_TOTAL: u64 = 10_000; // 100% @@ -17,7 +17,7 @@ pub type EsdtTokenDataMultiValue = MultiValue9< >; #[multiversx_sc::module] -pub trait ForwarderEsdtModule: storage::ForwarderStorageModule { +pub trait ForwarderEsdtModule: fwd_storage_legacy::ForwarderStorageModule { #[view(getFungibleEsdtBalance)] fn get_fungible_esdt_balance(&self, token_identifier: &TokenIdentifier) -> BigUint { self.blockchain() diff --git a/contracts/feature-tests/composability/forwarder/src/nft.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs similarity index 98% rename from contracts/feature-tests/composability/forwarder/src/nft.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs index 97d7a2dbd2..0cd0b57f4e 100644 --- a/contracts/feature-tests/composability/forwarder/src/nft.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_nft_legacy.rs @@ -1,7 +1,7 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -use super::storage; +use super::fwd_storage_legacy; // used as mock attributes for NFTs #[derive(TopEncode, TopDecode, TypeAbi, Clone, Copy, PartialEq, Debug)] @@ -21,7 +21,7 @@ pub struct ComplexAttributes { } #[multiversx_sc::module] -pub trait ForwarderNftModule: storage::ForwarderStorageModule { +pub trait ForwarderNftModule: fwd_storage_legacy::ForwarderStorageModule { #[view] fn get_nft_balance(&self, token_identifier: &TokenIdentifier, nonce: u64) -> BigUint { self.blockchain().get_esdt_balance( diff --git a/contracts/feature-tests/composability/forwarder/src/roles.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_roles_legacy.rs similarity index 92% rename from contracts/feature-tests/composability/forwarder/src/roles.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_roles_legacy.rs index ec90a2e2bd..792de8911a 100644 --- a/contracts/feature-tests/composability/forwarder/src/roles.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_roles_legacy.rs @@ -1,9 +1,9 @@ multiversx_sc::imports!(); -use super::storage; +use super::fwd_storage_legacy; #[multiversx_sc::module] -pub trait ForwarderRolesModule: storage::ForwarderStorageModule { +pub trait ForwarderRolesModule: fwd_storage_legacy::ForwarderStorageModule { #[endpoint(setLocalRoles)] fn set_local_roles( &self, diff --git a/contracts/feature-tests/composability/forwarder/src/sft.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs similarity index 94% rename from contracts/feature-tests/composability/forwarder/src/sft.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs index 12e1a2f431..41d01c6f7a 100644 --- a/contracts/feature-tests/composability/forwarder/src/sft.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_sft_legacy.rs @@ -1,9 +1,9 @@ multiversx_sc::imports!(); -use super::storage; +use super::fwd_storage_legacy; #[multiversx_sc::module] -pub trait ForwarderSftModule: storage::ForwarderStorageModule { +pub trait ForwarderSftModule: fwd_storage_legacy::ForwarderStorageModule { #[payable("EGLD")] #[endpoint] fn sft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { diff --git a/contracts/feature-tests/composability/forwarder/src/storage.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_storage_legacy.rs similarity index 100% rename from contracts/feature-tests/composability/forwarder/src/storage.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_storage_legacy.rs diff --git a/contracts/feature-tests/composability/forwarder/src/contract_upgrade.rs b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_upgrade_legacy.rs similarity index 97% rename from contracts/feature-tests/composability/forwarder/src/contract_upgrade.rs rename to contracts/feature-tests/composability/forwarder-legacy/src/fwd_upgrade_legacy.rs index b1629eeaa1..32e92844c7 100644 --- a/contracts/feature-tests/composability/forwarder/src/contract_upgrade.rs +++ b/contracts/feature-tests/composability/forwarder-legacy/src/fwd_upgrade_legacy.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + multiversx_sc::imports!(); #[multiversx_sc::module] diff --git a/contracts/feature-tests/composability/forwarder-legacy/wasm/Cargo.lock b/contracts/feature-tests/composability/forwarder-legacy/wasm/Cargo.lock new file mode 100644 index 0000000000..f0b4c69df9 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-legacy/wasm/Cargo.lock @@ -0,0 +1,186 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "forwarder-legacy" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "vault", +] + +[[package]] +name = "forwarder-legacy-wasm" +version = "0.0.0" +dependencies = [ + "forwarder-legacy", + "multiversx-sc-wasm-adapter", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "multiversx-sc" +version = "0.50.3" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.19.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.19.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.50.3" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.50.3" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + +[[package]] +name = "vault" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] diff --git a/contracts/feature-tests/composability/forwarder-legacy/wasm/Cargo.toml b/contracts/feature-tests/composability/forwarder-legacy/wasm/Cargo.toml new file mode 100644 index 0000000000..8102196a6c --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-legacy/wasm/Cargo.toml @@ -0,0 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "forwarder-legacy-wasm" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" + +[dependencies.forwarder-legacy] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.50.3" +path = "../../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/feature-tests/composability/forwarder-legacy/wasm/src/lib.rs b/contracts/feature-tests/composability/forwarder-legacy/wasm/src/lib.rs new file mode 100644 index 0000000000..120b11b7cf --- /dev/null +++ b/contracts/feature-tests/composability/forwarder-legacy/wasm/src/lib.rs @@ -0,0 +1,92 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 68 +// Async Callback: 1 +// Total number of exported functions: 70 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + forwarder_legacy + ( + init => init + send_egld => send_egld + echo_arguments_sync => echo_arguments_sync + echo_arguments_sync_twice => echo_arguments_sync_twice + forward_sync_accept_funds => forward_sync_accept_funds + forward_sync_accept_funds_with_fees => forward_sync_accept_funds_with_fees + forward_sync_accept_funds_then_read => forward_sync_accept_funds_then_read + forward_sync_retrieve_funds => forward_sync_retrieve_funds + forward_sync_retrieve_funds_with_accept_func => forward_sync_retrieve_funds_with_accept_func + accept_funds_func => accept_funds_func + forward_sync_accept_funds_multi_transfer => forward_sync_accept_funds_multi_transfer + echo_args_async => echo_args_async + forward_async_accept_funds => forward_async_accept_funds + forward_async_accept_funds_half_payment => forward_async_accept_funds_half_payment + forward_async_accept_funds_with_fees => forward_async_accept_funds_with_fees + forward_async_retrieve_funds => forward_async_retrieve_funds + send_funds_twice => send_funds_twice + send_async_accept_multi_transfer => send_async_accept_multi_transfer + callback_data => callback_data + callback_data_at_index => callback_data_at_index + clear_callback_data => clear_callback_data + forward_transf_exec_accept_funds => forward_transf_exec_accept_funds + forward_transf_exec_accept_single_esdt => forward_transf_exec_accept_single_esdt + forward_transf_execu_accept_funds_with_fees => forward_transf_execu_accept_funds_with_fees + forward_transf_exec_accept_funds_twice => forward_transf_exec_accept_funds_twice + forward_transf_exec_accept_funds_return_values => forward_transf_exec_accept_funds_return_values + transf_exec_multi_accept_funds => transf_exec_multi_accept_funds + transf_exec_multi_accept_funds_v2 => transf_exec_multi_accept_funds_v2 + forward_transf_exec_reject_funds_multi_transfer => forward_transf_exec_reject_funds_multi_transfer + transf_exec_multi_reject_funds => transf_exec_multi_reject_funds + changeOwnerAddress => change_owner + deploy_contract => deploy_contract + deploy_two_contracts => deploy_two_contracts + deploy_vault_from_source => deploy_vault_from_source + upgradeVault => upgrade_vault + upgrade_vault_from_source => upgrade_vault_from_source + getFungibleEsdtBalance => get_fungible_esdt_balance + getCurrentNftNonce => get_current_nft_nonce + send_esdt => send_esdt + send_esdt_with_fees => send_esdt_with_fees + send_esdt_twice => send_esdt_twice + send_esdt_direct_multi_transfer => send_esdt_direct_multi_transfer + issue_fungible_token => issue_fungible_token + local_mint => local_mint + local_burn => local_burn + get_esdt_local_roles => get_esdt_local_roles + get_esdt_token_data => get_esdt_token_data + is_esdt_frozen => is_esdt_frozen + is_esdt_paused => is_esdt_paused + is_esdt_limited_transfer => is_esdt_limited_transfer + validate_token_identifier => validate_token_identifier + sft_issue => sft_issue + get_nft_balance => get_nft_balance + buy_nft => buy_nft + nft_issue => nft_issue + nft_create => nft_create + nft_create_compact => nft_create_compact + nft_add_uris => nft_add_uris + nft_update_attributes => nft_update_attributes + nft_decode_complex_attributes => nft_decode_complex_attributes + nft_add_quantity => nft_add_quantity + nft_burn => nft_burn + transfer_nft_via_async_call => transfer_nft_via_async_call + transfer_nft_and_execute => transfer_nft_and_execute + create_and_send => create_and_send + setLocalRoles => set_local_roles + unsetLocalRoles => unset_local_roles + lastIssuedToken => last_issued_token + lastErrorMessage => last_error_message + ) +} + +multiversx_sc_wasm_adapter::async_callback! { forwarder_legacy } diff --git a/contracts/feature-tests/composability/forwarder-queue/Cargo.toml b/contracts/feature-tests/composability/forwarder-queue/Cargo.toml index 943ec49253..130bba0ff3 100644 --- a/contracts/feature-tests/composability/forwarder-queue/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-queue/Cargo.toml @@ -8,18 +8,15 @@ publish = false [lib] path = "src/forwarder_queue.rs" -[dependencies.vault] -path = "../vault" - [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" optional = true [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/forwarder-queue/meta/Cargo.toml b/contracts/feature-tests/composability/forwarder-queue/meta/Cargo.toml index e9eb852173..52ffaa1369 100644 --- a/contracts/feature-tests/composability/forwarder-queue/meta/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-queue/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.forwarder-queue] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/forwarder-queue/meta/src/main.rs b/contracts/feature-tests/composability/forwarder-queue/meta/src/main.rs index 7b268b4926..7dcfb10214 100644 --- a/contracts/feature-tests/composability/forwarder-queue/meta/src/main.rs +++ b/contracts/feature-tests/composability/forwarder-queue/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/forwarder-queue/sc-config.toml b/contracts/feature-tests/composability/forwarder-queue/sc-config.toml index 7ace04ba7c..161c5f7ce3 100644 --- a/contracts/feature-tests/composability/forwarder-queue/sc-config.toml +++ b/contracts/feature-tests/composability/forwarder-queue/sc-config.toml @@ -8,3 +8,6 @@ name = "forwarder-queue" name = "forwarder-queue-promises" add-labels = ["promises-callback"] ei = "1.3" + +[[proxy]] +path = "../interact/src/forwarder_queue_proxy.rs" diff --git a/contracts/feature-tests/composability/forwarder-queue/src/forwarder_queue.rs b/contracts/feature-tests/composability/forwarder-queue/src/forwarder_queue.rs index 66595bc54f..1d97b48fc3 100644 --- a/contracts/feature-tests/composability/forwarder-queue/src/forwarder_queue.rs +++ b/contracts/feature-tests/composability/forwarder-queue/src/forwarder_queue.rs @@ -4,7 +4,8 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone)] +#[type_abi] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, Clone)] pub enum QueuedCallType { Sync, LegacyAsync, @@ -12,7 +13,8 @@ pub enum QueuedCallType { Promise, } -#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone)] +#[type_abi] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, Clone)] pub struct QueuedCall { pub call_type: QueuedCallType, pub to: ManagedAddress, @@ -172,30 +174,27 @@ pub trait ForwarderQueue { }, }; - let contract_call = ContractCallWithAnyPayment::<_, ()>::new( - call.to, - call.endpoint_name, - call.payments, - ); + let contract_call = self + .tx() + .raw_call(call.endpoint_name) + .to(&call.to) + .payment(&call.payments); match call.call_type { QueuedCallType::Sync => { - contract_call.execute_on_dest_context::<()>(); + contract_call.sync_call(); }, QueuedCallType::LegacyAsync => { - contract_call.async_call().call_and_exit(); + contract_call.async_call_and_exit(); }, QueuedCallType::TransferExecute => { - contract_call - .with_gas_limit(call.gas_limit) - .transfer_execute(); + contract_call.gas(call.gas_limit).transfer_execute(); }, QueuedCallType::Promise => { contract_call - .with_gas_limit(call.gas_limit) - .with_raw_arguments(call.args) - .async_call_promise() - .with_callback(self.callbacks().promises_callback_method()) + .gas(call.gas_limit) + .arguments_raw(call.args) + .callback(self.callbacks().promises_callback_method()) .register_promise(); }, } @@ -208,10 +207,13 @@ pub trait ForwarderQueue { self.callback_count().update(|c| *c += 1); let payments = self.call_value().any_payment(); - let payments_data_string = - ContractCallNoPayment::<_, ()>::new(ManagedAddress::default(), ManagedBuffer::new()) - .with_any_payment(payments) - .into_call_data_string(); + let payments_data_string = self + .tx() + .to(&ManagedAddress::default()) + .payment(payments) + .raw_call("") + .to_call_data_string(); + self.callback_payments().set(payments_data_string); } diff --git a/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/Cargo.lock b/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/Cargo.lock index 77b8dddef6..b8ab6256c2 100644 --- a/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/Cargo.lock +++ b/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -31,7 +31,6 @@ name = "forwarder-queue" version = "0.0.0" dependencies = [ "multiversx-sc", - "vault", ] [[package]] @@ -56,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -112,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -149,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -171,8 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "vault" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/Cargo.toml b/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/Cargo.toml index 38dd4a6e53..4b1dbfe684 100644 --- a/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.forwarder-queue] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/src/lib.rs b/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/src/lib.rs index 639d22d1e1..1d83661126 100644 --- a/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder-queue/wasm-forwarder-queue-promises/src/lib.rs @@ -11,8 +11,6 @@ // Total number of exported functions: 13 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.lock b/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.lock index 16c620e6f3..fe79f9145e 100644 --- a/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -31,7 +31,6 @@ name = "forwarder-queue" version = "0.0.0" dependencies = [ "multiversx-sc", - "vault", ] [[package]] @@ -56,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -112,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -149,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -171,8 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "vault" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.toml b/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.toml index 23944ba669..f8eec572f9 100644 --- a/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.forwarder-queue] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/forwarder-queue/wasm/src/lib.rs b/contracts/feature-tests/composability/forwarder-queue/wasm/src/lib.rs index 45c5b3c92f..7613a7ad95 100644 --- a/contracts/feature-tests/composability/forwarder-queue/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder-queue/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 12 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/forwarder-raw/Cargo.toml b/contracts/feature-tests/composability/forwarder-raw/Cargo.toml index 759a6a64cd..1f7fa6175f 100644 --- a/contracts/feature-tests/composability/forwarder-raw/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-raw/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/forwarder_raw.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/forwarder-raw/meta/Cargo.toml b/contracts/feature-tests/composability/forwarder-raw/meta/Cargo.toml index 8fc82f5db3..6ffc1c01d3 100644 --- a/contracts/feature-tests/composability/forwarder-raw/meta/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-raw/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.forwarder-raw] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/forwarder-raw/meta/src/main.rs b/contracts/feature-tests/composability/forwarder-raw/meta/src/main.rs index fde34fe5c9..e35f2df91c 100644 --- a/contracts/feature-tests/composability/forwarder-raw/meta/src/main.rs +++ b/contracts/feature-tests/composability/forwarder-raw/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs index 79cab17a11..f00a10d434 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_alt_init.rs @@ -17,11 +17,11 @@ pub trait ForwarderRawAlterativeInit: super::forwarder_raw_common::ForwarderRawC endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - self.send() - .contract_call::<()>(to, endpoint_name) - .with_raw_arguments(args.to_arg_buffer()) - .async_call() - .call_and_exit(); + self.tx() + .to(&to) + .raw_call(endpoint_name) + .arguments_raw(args.to_arg_buffer()) + .async_call_and_exit(); } /// Will not work, only written for VM testing. @@ -29,7 +29,7 @@ pub trait ForwarderRawAlterativeInit: super::forwarder_raw_common::ForwarderRawC /// Async calls are explicitly forbidden in upgrade constructors. /// /// TODO: write test once scenario tests support upgrades directly. - #[endpoint(upgrade)] + #[upgrade] #[label("init-async-call")] fn upgrade_async_call( &self, @@ -54,13 +54,16 @@ pub trait ForwarderRawAlterativeInit: super::forwarder_raw_common::ForwarderRawC ) { let payment = self.call_value().egld_value(); let half_gas = self.blockchain().get_gas_left() / 2; - let result = self.send_raw().execute_on_dest_context_raw( - half_gas, - &to, - &payment, - &endpoint_name, - &args.to_arg_buffer(), - ); + + let result = self + .tx() + .to(&to) + .gas(half_gas) + .egld(payment) + .raw_call(endpoint_name) + .arguments_raw(args.to_arg_buffer()) + .returns(ReturnsRawResult) + .sync_call(); self.execute_on_dest_context_result(result); } diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs index 25d8868298..47240f3c52 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs @@ -6,21 +6,27 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { #[payable("*")] fn forward_payment(&self, to: ManagedAddress) { let (token, payment) = self.call_value().egld_or_single_fungible_esdt(); - self.send().direct(&to, &token, 0, &payment); + self.tx() + .to(to) + .egld_or_single_esdt(&token, 0, &payment) + .transfer(); } #[endpoint] #[payable("*")] fn forward_direct_esdt_via_transf_exec(&self, to: ManagedAddress) { let (token, payment) = self.call_value().single_fungible_esdt(); - self.send().direct_esdt(&to, &token, 0, &payment); + self.tx() + .to(&to) + .single_esdt(&token, 0, &payment) + .transfer(); } #[endpoint] #[payable("*")] fn forward_direct_esdt_multi(&self, to: ManagedAddress) { let payments = self.call_value().all_esdt_transfers(); - self.send().direct_multi(&to, &payments); + self.tx().to(&to).payment(payments).transfer(); } fn forward_contract_call( @@ -30,11 +36,24 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { payment_amount: BigUint, endpoint_name: ManagedBuffer, args: MultiValueEncoded, - ) -> ContractCallWithEgldOrSingleEsdt { - self.send() - .contract_call(to, endpoint_name) - .with_raw_arguments(args.to_arg_buffer()) - .with_egld_or_single_esdt_transfer((payment_token, 0, payment_amount)) + ) -> Tx< + TxScEnv, + (), + ManagedAddress, + EgldOrEsdtTokenPayment, + (), + FunctionCall, + (), + > { + self.tx() + .to(to) + .raw_call(endpoint_name) + .arguments_raw(args.to_arg_buffer()) + .payment(EgldOrEsdtTokenPayment::new( + payment_token, + 0, + payment_amount, + )) } #[endpoint] @@ -47,8 +66,7 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { ) { let (token, payment) = self.call_value().egld_or_single_fungible_esdt(); self.forward_contract_call(to, token, payment, endpoint_name, args) - .async_call() - .call_and_exit() + .async_call_and_exit() } #[endpoint] @@ -62,8 +80,7 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { let (token, payment) = self.call_value().egld_or_single_fungible_esdt(); let half_payment = payment / 2u32; self.forward_contract_call(to, token, half_payment, endpoint_name, args) - .async_call() - .call_and_exit() + .async_call_and_exit() } #[endpoint] @@ -82,7 +99,7 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name, args, ) - .with_gas_limit(self.blockchain().get_gas_left() / 2) + .gas(self.blockchain().get_gas_left() / 2) .transfer_execute(); } @@ -102,7 +119,7 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name, args, ) - .with_gas_limit(self.blockchain().get_gas_left() / 2) + .gas(self.blockchain().get_gas_left() / 2) .transfer_execute(); } @@ -116,7 +133,7 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { ) { let (token, payment) = self.call_value().egld_or_single_fungible_esdt(); self.forward_contract_call(to, token, payment, endpoint_name, args) - .with_gas_limit(self.blockchain().get_gas_left() / 2) + .gas(self.blockchain().get_gas_left() / 2) .transfer_execute(); } @@ -137,10 +154,10 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name.clone(), args.clone(), ) - .with_gas_limit(self.blockchain().get_gas_left() / 2) + .gas(self.blockchain().get_gas_left() / 2) .transfer_execute(); self.forward_contract_call(to, token, half_payment, endpoint_name, args) - .with_gas_limit(self.blockchain().get_gas_left() / 2) + .gas(self.blockchain().get_gas_left() / 2) .transfer_execute(); } @@ -159,12 +176,11 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { arg_buffer.push_arg(amount); } - self.send_raw().async_call_raw( - &to, - &BigUint::zero(), - &ManagedBuffer::from(&b"retrieve_multi_funds_async"[..]), - &arg_buffer, - ); + self.tx() + .to(&to) + .raw_call("retrieve_multi_funds_async") + .arguments_raw(arg_buffer) + .async_call_and_exit(); } #[endpoint] @@ -180,12 +196,10 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { all_payments.push(EsdtTokenPayment::new(token_identifier, token_nonce, amount)); } - ContractCallWithMultiEsdt::::new( - to, - "burn_and_create_retrive_async", - all_payments, - ) - .async_call() - .call_and_exit_ignore_callback() + self.tx() + .raw_call("burn_and_create_retrieve_async") + .to(&to) + .payment(&all_payments) + .async_call_and_exit() } } diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_deploy_upgrade.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_deploy_upgrade.rs index 1f89186e0e..803119c140 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_deploy_upgrade.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_deploy_upgrade.rs @@ -9,14 +9,15 @@ pub trait ForwarderRawDeployUpgrade { code_metadata: CodeMetadata, args: MultiValueEncoded, ) -> MultiValue2> { - self.send_raw() - .deploy_contract( - self.blockchain().get_gas_left(), - &BigUint::zero(), - &code, - code_metadata, - &args.to_arg_buffer(), - ) + self.tx() + .raw_deploy() + .code(code) + .code_metadata(code_metadata) + .arguments_raw(args.to_arg_buffer()) + .gas(self.blockchain().get_gas_left()) + .returns(ReturnsNewManagedAddress) + .returns(ReturnsRawResult) + .sync_call() .into() } @@ -25,35 +26,33 @@ pub trait ForwarderRawDeployUpgrade { &self, source_contract_address: ManagedAddress, code_metadata: CodeMetadata, - arguments: MultiValueEncoded, + args: MultiValueEncoded, ) -> ManagedAddress { - let (address, _) = self.send_raw().deploy_from_source_contract( - self.blockchain().get_gas_left(), - &BigUint::zero(), - &source_contract_address, - code_metadata, - &arguments.to_arg_buffer(), - ); - - address + self.tx() + .raw_deploy() + .from_source(source_contract_address) + .code_metadata(code_metadata) + .arguments_raw(args.to_arg_buffer()) + .gas(self.blockchain().get_gas_left()) + .returns(ReturnsNewManagedAddress) + .sync_call() } #[endpoint] fn call_upgrade( &self, - child_sc_address: &ManagedAddress, - new_code: &ManagedBuffer, + child_sc_address: ManagedAddress, + new_code: ManagedBuffer, code_metadata: CodeMetadata, - arguments: MultiValueEncoded, + args: MultiValueEncoded, ) { - self.send_raw().upgrade_contract( - child_sc_address, - self.blockchain().get_gas_left(), - &BigUint::zero(), - new_code, - code_metadata, - &arguments.to_arg_buffer(), - ); + self.tx() + .to(child_sc_address) + .raw_upgrade() + .code(new_code) + .code_metadata(code_metadata) + .arguments_raw(args.to_arg_buffer()) + .upgrade_async_call_and_exit(); } #[endpoint] @@ -62,15 +61,15 @@ pub trait ForwarderRawDeployUpgrade { sc_address: ManagedAddress, source_contract_address: ManagedAddress, code_metadata: CodeMetadata, - arguments: MultiValueEncoded, + args: MultiValueEncoded, ) { - self.send_raw().upgrade_from_source_contract( - &sc_address, - self.blockchain().get_gas_left(), - &BigUint::zero(), - &source_contract_address, - code_metadata, - &arguments.to_arg_buffer(), - ) + self.tx() + .to(sc_address) + .raw_upgrade() + .from_source(source_contract_address) + .code_metadata(code_metadata) + .arguments_raw(args.to_arg_buffer()) + .gas(self.blockchain().get_gas_left()) + .upgrade_async_call_and_exit(); } } diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs index d01245ca59..799ce0cb83 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_sync.rs @@ -10,15 +10,17 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { endpoint_name: ManagedBuffer, args: MultiValueEncoded, ) { - let payment = self.call_value().egld_value(); + let payment = self.call_value().egld_value().clone_value(); let half_gas = self.blockchain().get_gas_left() / 2; - let result = self.send_raw().execute_on_dest_context_raw( - half_gas, - &to, - &payment, - &endpoint_name, - &args.to_arg_buffer(), - ); + let result = self + .tx() + .to(to) + .egld(payment) + .raw_call(endpoint_name) + .argument(&args) + .gas(half_gas) + .returns(ReturnsRawResult) + .sync_call(); self.execute_on_dest_context_result(result); } @@ -36,22 +38,28 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { let half_payment = &*payment / 2u32; let arg_buffer = args.to_arg_buffer(); - let result = self.send_raw().execute_on_dest_context_raw( - one_third_gas, - &to, - &half_payment, - &endpoint_name, - &arg_buffer, - ); + let result = self + .tx() + .to(&to) + .gas(one_third_gas) + .egld(&half_payment) + .raw_call(endpoint_name.clone()) + .arguments_raw(arg_buffer.clone()) + .returns(ReturnsRawResult) + .sync_call(); + self.execute_on_dest_context_result(result); - let result = self.send_raw().execute_on_dest_context_raw( - one_third_gas, - &to, - &half_payment, - &endpoint_name, - &arg_buffer, - ); + let result = self + .tx() + .to(&to) + .gas(one_third_gas) + .egld(&half_payment) + .raw_call(endpoint_name) + .arguments_raw(arg_buffer) + .returns(ReturnsRawResult) + .sync_call(); + self.execute_on_dest_context_result(result); } @@ -65,13 +73,16 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { ) { let payment = self.call_value().egld_value(); let half_gas = self.blockchain().get_gas_left() / 2; - let result = self.send_raw().execute_on_same_context_raw( - half_gas, - &to, - &payment, - &endpoint_name, - &args.to_arg_buffer(), - ); + + let result = self + .tx() + .to(&to) + .gas(half_gas) + .egld(payment) + .raw_call(endpoint_name) + .arguments_raw(args.to_arg_buffer()) + .returns(ReturnsRawResult) + .sync_call_same_context(); self.execute_on_same_context_result(result); } @@ -84,12 +95,14 @@ pub trait ForwarderRawSync: super::forwarder_raw_common::ForwarderRawCommon { args: MultiValueEncoded, ) { let half_gas = self.blockchain().get_gas_left() / 2; - let result = self.send_raw().execute_on_dest_context_readonly_raw( - half_gas, - &to, - &endpoint_name, - &args.to_arg_buffer(), - ); + let result = self + .tx() + .to(&to) + .gas(half_gas) + .raw_call(endpoint_name) + .arguments_raw(args.to_arg_buffer()) + .returns(ReturnsRawResult) + .sync_call_readonly(); self.execute_on_dest_context_result(result); } diff --git a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/Cargo.lock b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/Cargo.lock index dc9d4ac00a..8935e69d01 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/Cargo.lock +++ b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/Cargo.toml b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/Cargo.toml index e247aff0e9..64009abbe1 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.forwarder-raw] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/src/lib.rs b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/src/lib.rs index 01c9657fd7..590e75b609 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-async-call/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 1 +// Upgrade: 1 +// Endpoints: 0 // Async Callback: 1 // Total number of exported functions: 3 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/Cargo.lock b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/Cargo.lock index 1e3db2655b..d0888c7ae9 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/Cargo.lock +++ b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/Cargo.toml b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/Cargo.toml index 1752f95e34..84da48195a 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.forwarder-raw] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/src/lib.rs b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/src/lib.rs index dd5b4bb3b1..39a1ffb566 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder-raw/wasm-forwarder-raw-init-sync-call/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 2 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.lock b/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.lock index f5ba514af5..e889b2e95b 100755 --- a/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.toml b/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.toml index 23a0df99d8..410780a85a 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.forwarder-raw] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/forwarder-raw/wasm/src/lib.rs b/contracts/feature-tests/composability/forwarder-raw/wasm/src/lib.rs index 980ea6ce70..16ff76235c 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder-raw/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 27 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/forwarder/Cargo.toml b/contracts/feature-tests/composability/forwarder/Cargo.toml index bd5e426fce..9eb304af96 100644 --- a/contracts/feature-tests/composability/forwarder/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder/Cargo.toml @@ -8,14 +8,11 @@ publish = false [lib] path = "src/forwarder_main.rs" -[dependencies.vault] -path = "../vault" - [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/forwarder/meta/Cargo.toml b/contracts/feature-tests/composability/forwarder/meta/Cargo.toml index 709498d977..67d9b898c1 100644 --- a/contracts/feature-tests/composability/forwarder/meta/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.forwarder] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/forwarder/meta/src/main.rs b/contracts/feature-tests/composability/forwarder/meta/src/main.rs index ae1d190397..6be9c6c962 100644 --- a/contracts/feature-tests/composability/forwarder/meta/src/main.rs +++ b/contracts/feature-tests/composability/forwarder/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/forwarder/sc-config.toml b/contracts/feature-tests/composability/forwarder/sc-config.toml new file mode 100644 index 0000000000..b78f0086a5 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "src/forwarder_proxy.rs" diff --git a/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs b/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs index 71ddd886df..cd2254587c 100644 --- a/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs +++ b/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs @@ -1,41 +1,42 @@ #![no_std] #![allow(clippy::type_complexity)] -#![allow(clippy::let_unit_value)] -pub mod call_async; -pub mod call_sync; -pub mod call_transf_exec; -pub mod contract_change_owner; -pub mod contract_deploy; -pub mod contract_upgrade; -pub mod esdt; -pub mod nft; -pub mod roles; -pub mod sft; -pub mod storage; +pub mod forwarder_proxy; +pub mod fwd_call_async; +pub mod fwd_call_sync; +pub mod fwd_call_transf_exec; +pub mod fwd_change_owner; +pub mod fwd_deploy; +pub mod fwd_esdt; +pub mod fwd_nft; +pub mod fwd_roles; +pub mod fwd_sft; +pub mod fwd_storage; +pub mod fwd_upgrade; +pub mod vault_proxy; multiversx_sc::imports!(); /// Test contract for investigating contract calls. #[multiversx_sc::contract] pub trait Forwarder: - call_sync::ForwarderSyncCallModule - + call_async::ForwarderAsyncCallModule - + call_transf_exec::ForwarderTransferExecuteModule - + contract_change_owner::ChangeOwnerModule - + contract_deploy::DeployContractModule - + contract_upgrade::UpgradeContractModule - + esdt::ForwarderEsdtModule - + sft::ForwarderSftModule - + nft::ForwarderNftModule - + roles::ForwarderRolesModule - + storage::ForwarderStorageModule + fwd_call_sync::ForwarderSyncCallModule + + fwd_call_async::ForwarderAsyncCallModule + + fwd_call_transf_exec::ForwarderTransferExecuteModule + + fwd_change_owner::ChangeOwnerModule + + fwd_deploy::DeployContractModule + + fwd_upgrade::UpgradeContractModule + + fwd_esdt::ForwarderEsdtModule + + fwd_sft::ForwarderSftModule + + fwd_nft::ForwarderNftModule + + fwd_roles::ForwarderRolesModule + + fwd_storage::ForwarderStorageModule { #[init] fn init(&self) {} #[endpoint] fn send_egld(&self, to: &ManagedAddress, amount: &BigUint) { - self.send().direct_egld(to, amount); + self.tx().to(to).egld(amount).transfer(); } } diff --git a/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs new file mode 100644 index 0000000000..156241596d --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/forwarder_proxy.rs @@ -0,0 +1,1176 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct ForwarderProxy; + +impl TxProxyTrait for ForwarderProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = ForwarderProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + ForwarderProxyMethods { wrapped_tx: tx } + } +} + +pub struct ForwarderProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl ForwarderProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl ForwarderProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn send_egld< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_egld") + .argument(&to) + .argument(&amount) + .original_result() + } + + pub fn echo_arguments_sync< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + to: Arg0, + args: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("echo_arguments_sync") + .argument(&to) + .argument(&args) + .original_result() + } + + pub fn echo_arguments_sync_twice< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + to: Arg0, + args: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("echo_arguments_sync_twice") + .argument(&to) + .argument(&args) + .original_result() + } + + pub fn forward_sync_accept_funds< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_sync_accept_funds") + .argument(&to) + .original_result() + } + + pub fn forward_sync_accept_funds_with_fees< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + percentage_fees: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_sync_accept_funds_with_fees") + .argument(&to) + .argument(&percentage_fees) + .original_result() + } + + pub fn forward_sync_accept_funds_then_read< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_sync_accept_funds_then_read") + .argument(&to) + .original_result() + } + + pub fn forward_sync_retrieve_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + token_nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_sync_retrieve_funds") + .argument(&to) + .argument(&token) + .argument(&token_nonce) + .argument(&amount) + .original_result() + } + + pub fn forward_sync_retrieve_funds_with_accept_func< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_sync_retrieve_funds_with_accept_func") + .argument(&to) + .argument(&token) + .argument(&amount) + .original_result() + } + + pub fn accept_funds_func( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds_func") + .original_result() + } + + pub fn forward_sync_accept_funds_multi_transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_sync_accept_funds_multi_transfer") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn echo_args_async< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + to: Arg0, + args: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_args_async") + .argument(&to) + .argument(&args) + .original_result() + } + + pub fn forward_async_accept_funds< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_async_accept_funds") + .argument(&to) + .original_result() + } + + pub fn forward_async_accept_funds_half_payment< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_async_accept_funds_half_payment") + .argument(&to) + .original_result() + } + + pub fn forward_async_accept_funds_with_fees< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + percentage_fees: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_async_accept_funds_with_fees") + .argument(&to) + .argument(&percentage_fees) + .original_result() + } + + pub fn forward_async_retrieve_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + token_nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_async_retrieve_funds") + .argument(&to) + .argument(&token) + .argument(&token_nonce) + .argument(&amount) + .original_result() + } + + pub fn send_funds_twice< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + to: Arg0, + token_identifier: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_funds_twice") + .argument(&to) + .argument(&token_identifier) + .argument(&amount) + .original_result() + } + + pub fn send_async_accept_multi_transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_async_accept_multi_transfer") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn callback_data( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("callback_data") + .original_result() + } + + pub fn callback_data_at_index< + Arg0: ProxyArg, + >( + self, + index: Arg0, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier, u64, BigUint, MultiValueManagedVec>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("callback_data_at_index") + .argument(&index) + .original_result() + } + + pub fn clear_callback_data( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("clear_callback_data") + .original_result() + } + + pub fn forward_transf_exec_accept_funds< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_transf_exec_accept_funds") + .argument(&to) + .original_result() + } + + pub fn forward_transf_execu_accept_funds_with_fees< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + percentage_fees: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_transf_execu_accept_funds_with_fees") + .argument(&to) + .argument(&percentage_fees) + .original_result() + } + + pub fn forward_transf_exec_accept_funds_twice< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_transf_exec_accept_funds_twice") + .argument(&to) + .original_result() + } + + /// Test that the default gas provided to the transfer_execute call + /// leaves enough in the transaction for finish to happen. + pub fn forward_transf_exec_accept_funds_return_values< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier>> { + self.wrapped_tx + .raw_call("forward_transf_exec_accept_funds_return_values") + .argument(&to) + .original_result() + } + + pub fn transf_exec_multi_accept_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transf_exec_multi_accept_funds") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn forward_transf_exec_reject_funds_multi_transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_transf_exec_reject_funds_multi_transfer") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn transf_exec_multi_reject_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transf_exec_multi_reject_funds") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn change_owner< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + child_sc_address: Arg0, + new_owner: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("changeOwnerAddress") + .argument(&child_sc_address) + .argument(&new_owner) + .original_result() + } + + pub fn deploy_contract< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + code: Arg0, + opt_arg: Arg1, + ) -> TxTypedCall, OptionalValue>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("deploy_contract") + .argument(&code) + .argument(&opt_arg) + .original_result() + } + + pub fn deploy_two_contracts< + Arg0: ProxyArg>, + >( + self, + code: Arg0, + ) -> TxTypedCall, ManagedAddress>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("deploy_two_contracts") + .argument(&code) + .original_result() + } + + pub fn deploy_vault_from_source< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + source_address: Arg0, + opt_arg: Arg1, + ) -> TxTypedCall, OptionalValue>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("deploy_vault_from_source") + .argument(&source_address) + .argument(&opt_arg) + .original_result() + } + + pub fn upgrade_vault< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + child_sc_address: Arg0, + new_code: Arg1, + opt_arg: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("upgradeVault") + .argument(&child_sc_address) + .argument(&new_code) + .argument(&opt_arg) + .original_result() + } + + pub fn upgrade_vault_from_source< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + child_sc_address: Arg0, + source_address: Arg1, + opt_arg: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("upgrade_vault_from_source") + .argument(&child_sc_address) + .argument(&source_address) + .argument(&opt_arg) + .original_result() + } + + pub fn get_fungible_esdt_balance< + Arg0: ProxyArg>, + >( + self, + token_identifier: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getFungibleEsdtBalance") + .argument(&token_identifier) + .original_result() + } + + pub fn get_current_nft_nonce< + Arg0: ProxyArg>, + >( + self, + token_identifier: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getCurrentNftNonce") + .argument(&token_identifier) + .original_result() + } + + pub fn send_esdt< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + to: Arg0, + token_id: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_esdt") + .argument(&to) + .argument(&token_id) + .argument(&amount) + .original_result() + } + + pub fn send_esdt_with_fees< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + percentage_fees: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("send_esdt_with_fees") + .argument(&to) + .argument(&percentage_fees) + .original_result() + } + + pub fn send_esdt_twice< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token_id: Arg1, + amount_first_time: Arg2, + amount_second_time: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_esdt_twice") + .argument(&to) + .argument(&token_id) + .argument(&amount_first_time) + .argument(&amount_second_time) + .original_result() + } + + pub fn send_esdt_direct_multi_transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg, u64, BigUint>>>, + >( + self, + to: Arg0, + token_payments: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("send_esdt_direct_multi_transfer") + .argument(&to) + .argument(&token_payments) + .original_result() + } + + pub fn issue_fungible_token< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + initial_supply: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("issue_fungible_token") + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&initial_supply) + .original_result() + } + + pub fn local_mint< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("local_mint") + .argument(&token_identifier) + .argument(&amount) + .original_result() + } + + pub fn local_burn< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("local_burn") + .argument(&token_identifier) + .argument(&amount) + .original_result() + } + + pub fn get_esdt_local_roles< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_esdt_local_roles") + .argument(&token_id) + .original_result() + } + + pub fn get_esdt_token_data< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + address: Arg0, + token_id: Arg1, + nonce: Arg2, + ) -> TxTypedCall, bool, ManagedBuffer, ManagedBuffer, ManagedBuffer, ManagedAddress, BigUint, ManagedVec>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_esdt_token_data") + .argument(&address) + .argument(&token_id) + .argument(&nonce) + .original_result() + } + + pub fn is_esdt_frozen< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + address: Arg0, + token_id: Arg1, + nonce: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("is_esdt_frozen") + .argument(&address) + .argument(&token_id) + .argument(&nonce) + .original_result() + } + + pub fn is_esdt_paused< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("is_esdt_paused") + .argument(&token_id) + .original_result() + } + + pub fn is_esdt_limited_transfer< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("is_esdt_limited_transfer") + .argument(&token_id) + .original_result() + } + + pub fn validate_token_identifier< + Arg0: ProxyArg>, + >( + self, + token_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("validate_token_identifier") + .argument(&token_id) + .original_result() + } + + pub fn sft_issue< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("sft_issue") + .argument(&token_display_name) + .argument(&token_ticker) + .original_result() + } + + pub fn get_nft_balance< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_nft_balance") + .argument(&token_identifier) + .argument(&nonce) + .original_result() + } + + pub fn buy_nft< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + nft_id: Arg0, + nft_nonce: Arg1, + nft_amount: Arg2, + ) -> TxTypedCall> { + self.wrapped_tx + .raw_call("buy_nft") + .argument(&nft_id) + .argument(&nft_nonce) + .argument(&nft_amount) + .original_result() + } + + pub fn nft_issue< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_display_name: Arg0, + token_ticker: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("nft_issue") + .argument(&token_display_name) + .argument(&token_ticker) + .original_result() + } + + pub fn nft_create< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + Arg5: ProxyArg, + Arg6: ProxyArg>, + >( + self, + token_identifier: Arg0, + amount: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, + color: Arg5, + uri: Arg6, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_create") + .argument(&token_identifier) + .argument(&amount) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&color) + .argument(&uri) + .original_result() + } + + pub fn nft_create_compact< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + token_identifier: Arg0, + amount: Arg1, + color: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_create_compact") + .argument(&token_identifier) + .argument(&amount) + .argument(&color) + .original_result() + } + + pub fn nft_add_uris< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>>, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + uris: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_add_uris") + .argument(&token_identifier) + .argument(&nonce) + .argument(&uris) + .original_result() + } + + pub fn nft_update_attributes< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + new_attributes: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_update_attributes") + .argument(&token_identifier) + .argument(&nonce) + .argument(&new_attributes) + .original_result() + } + + pub fn nft_decode_complex_attributes< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + Arg5: ProxyArg>, + Arg6: ProxyArg, ManagedBuffer, TokenIdentifier, bool, ManagedBuffer>>, + >( + self, + token_identifier: Arg0, + amount: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, + uri: Arg5, + attrs_arg: Arg6, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_decode_complex_attributes") + .argument(&token_identifier) + .argument(&amount) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&uri) + .argument(&attrs_arg) + .original_result() + } + + pub fn nft_add_quantity< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_add_quantity") + .argument(&token_identifier) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn nft_burn< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + token_identifier: Arg0, + nonce: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("nft_burn") + .argument(&token_identifier) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn transfer_nft_via_async_call< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token_identifier: Arg1, + nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer_nft_via_async_call") + .argument(&to) + .argument(&token_identifier) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn transfer_nft_and_execute< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + Arg5: ProxyArg>>, + >( + self, + to: Arg0, + token_identifier: Arg1, + nonce: Arg2, + amount: Arg3, + function: Arg4, + arguments: Arg5, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer_nft_and_execute") + .argument(&to) + .argument(&token_identifier) + .argument(&nonce) + .argument(&amount) + .argument(&function) + .argument(&arguments) + .original_result() + } + + pub fn create_and_send< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + Arg5: ProxyArg>, + Arg6: ProxyArg, + Arg7: ProxyArg>, + >( + self, + to: Arg0, + token_identifier: Arg1, + amount: Arg2, + name: Arg3, + royalties: Arg4, + hash: Arg5, + color: Arg6, + uri: Arg7, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("create_and_send") + .argument(&to) + .argument(&token_identifier) + .argument(&amount) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&color) + .argument(&uri) + .original_result() + } + + pub fn set_local_roles< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + address: Arg0, + token_identifier: Arg1, + roles: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("setLocalRoles") + .argument(&address) + .argument(&token_identifier) + .argument(&roles) + .original_result() + } + + pub fn unset_local_roles< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + address: Arg0, + token_identifier: Arg1, + roles: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unsetLocalRoles") + .argument(&address) + .argument(&token_identifier) + .argument(&roles) + .original_result() + } + + pub fn last_issued_token( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("lastIssuedToken") + .original_result() + } + + pub fn last_error_message( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("lastErrorMessage") + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub struct CallbackData +where + Api: ManagedTypeApi, +{ + pub callback_name: ManagedBuffer, + pub token_identifier: EgldOrEsdtTokenIdentifier, + pub token_nonce: u64, + pub token_amount: BigUint, + pub args: ManagedVec>, +} + +#[type_abi] +#[derive(TopEncode, TopDecode, Clone, Copy, PartialEq, Debug)] +pub struct Color { + pub r: u8, + pub g: u8, + pub b: u8, +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs b/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs new file mode 100644 index 0000000000..5492a45a10 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_async.rs @@ -0,0 +1,229 @@ +use crate::vault_proxy; + +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub struct CallbackData { + callback_name: ManagedBuffer, + token_identifier: EgldOrEsdtTokenIdentifier, + token_nonce: u64, + token_amount: BigUint, + args: ManagedVec>, +} + +const PERCENTAGE_TOTAL: u64 = 10_000; // 100% + +#[multiversx_sc::module] +pub trait ForwarderAsyncCallModule { + #[endpoint] + fn echo_args_async(&self, to: ManagedAddress, args: MultiValueEncoded) { + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .echo_arguments(args) + .callback(self.callbacks().echo_args_callback()) + .async_call_and_exit(); + } + + #[callback] + fn echo_args_callback( + &self, + #[call_result] result: ManagedAsyncCallResult>, + ) -> MultiValueEncoded { + match result { + ManagedAsyncCallResult::Ok(results) => { + let mut cb_result = + ManagedVec::from_single_item(ManagedBuffer::new_from_bytes(b"success")); + cb_result.append_vec(results.into_vec_of_buffers()); + + cb_result.into() + }, + ManagedAsyncCallResult::Err(err) => { + let mut cb_result = + ManagedVec::from_single_item(ManagedBuffer::new_from_bytes(b"error")); + cb_result.push(ManagedBuffer::new_from_bytes( + &err.err_code.to_be_bytes()[..], + )); + cb_result.push(err.err_msg); + + cb_result.into() + }, + } + } + + #[endpoint] + #[payable("*")] + fn forward_async_accept_funds(&self, to: ManagedAddress) { + let payment = self.call_value().egld_or_single_esdt(); + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .payment(payment) + .async_call_and_exit() + } + + #[endpoint] + #[payable("*")] + fn forward_async_accept_funds_half_payment(&self, to: ManagedAddress) { + let payment = self.call_value().egld_or_single_esdt(); + let half_payment = payment.amount / 2u32; + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .egld_or_single_esdt( + &payment.token_identifier, + payment.token_nonce, + &half_payment, + ) + .async_call_and_exit() + } + + #[payable("*")] + #[endpoint] + fn forward_async_accept_funds_with_fees(&self, to: ManagedAddress, percentage_fees: BigUint) { + let payment = self.call_value().egld_or_single_esdt(); + let fees = &payment.amount * &percentage_fees / PERCENTAGE_TOTAL; + let amount_to_send = &payment.amount - &fees; + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .egld_or_single_esdt( + &payment.token_identifier, + payment.token_nonce, + &amount_to_send, + ) + .async_call_and_exit(); + } + + #[endpoint] + fn forward_async_retrieve_funds( + &self, + to: ManagedAddress, + token: EgldOrEsdtTokenIdentifier, + token_nonce: u64, + amount: BigUint, + ) { + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .retrieve_funds(token, token_nonce, amount) + .callback(self.callbacks().retrieve_funds_callback()) + .async_call_and_exit() + } + + #[callback] + fn retrieve_funds_callback(&self) { + let (token, nonce, payment) = self.call_value().egld_or_single_esdt().into_tuple(); + self.retrieve_funds_callback_event(&token, nonce, &payment); + + let _ = self.callback_data().push(&CallbackData { + callback_name: ManagedBuffer::from(b"retrieve_funds_callback"), + token_identifier: token, + token_nonce: nonce, + token_amount: payment, + args: ManagedVec::new(), + }); + } + + #[event("retrieve_funds_callback")] + fn retrieve_funds_callback_event( + &self, + #[indexed] token: &EgldOrEsdtTokenIdentifier, + #[indexed] nonce: u64, + #[indexed] payment: &BigUint, + ); + + #[endpoint] + fn send_funds_twice( + &self, + to: &ManagedAddress, + token_identifier: &EgldOrEsdtTokenIdentifier, + amount: &BigUint, + ) { + self.tx() + .to(to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .egld_or_single_esdt(token_identifier, 0u64, amount) + .callback( + self.callbacks() + .send_funds_twice_callback(to, token_identifier, amount), + ) + .async_call_and_exit(); + } + + #[callback] + fn send_funds_twice_callback( + &self, + to: &ManagedAddress, + token_identifier: &EgldOrEsdtTokenIdentifier, + cb_amount: &BigUint, + ) { + self.tx() + .to(to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .egld_or_single_esdt(token_identifier, 0u64, cb_amount) + .async_call_and_exit(); + } + + #[endpoint] + fn send_async_accept_multi_transfer( + &self, + to: ManagedAddress, + token_payments: MultiValueEncoded>, + ) { + let mut all_token_payments = ManagedVec::new(); + + for multi_arg in token_payments.into_iter() { + let (token_identifier, token_nonce, amount) = multi_arg.into_tuple(); + let payment = EsdtTokenPayment::new(token_identifier, token_nonce, amount); + + all_token_payments.push(payment); + } + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .payment(all_token_payments) + .async_call_and_exit(); + } + + #[view] + #[storage_mapper("callback_data")] + fn callback_data(&self) -> VecMapper>; + + #[view] + fn callback_data_at_index( + &self, + index: usize, + ) -> MultiValue5< + ManagedBuffer, + EgldOrEsdtTokenIdentifier, + u64, + BigUint, + MultiValueManagedVec, + > { + let cb_data = self.callback_data().get(index); + ( + cb_data.callback_name, + cb_data.token_identifier, + cb_data.token_nonce, + cb_data.token_amount, + cb_data.args.into(), + ) + .into() + } + + #[endpoint] + fn clear_callback_data(&self) { + self.callback_data().clear(); + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs b/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs new file mode 100644 index 0000000000..13fbcd40db --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_sync.rs @@ -0,0 +1,186 @@ +use crate::vault_proxy; + +multiversx_sc::imports!(); + +const PERCENTAGE_TOTAL: u64 = 10_000; // 100% + +#[multiversx_sc::module] +pub trait ForwarderSyncCallModule { + #[endpoint] + #[payable("*")] + fn echo_arguments_sync(&self, to: ManagedAddress, args: MultiValueEncoded) { + let half_gas = self.blockchain().get_gas_left() / 2; + + let result = self + .tx() + .to(&to) + .gas(half_gas) + .typed(vault_proxy::VaultProxy) + .echo_arguments(args) + .returns(ReturnsResult) + .sync_call(); + + self.execute_on_dest_context_result_event(&result.into_vec_of_buffers()); + } + + #[endpoint] + #[payable("*")] + fn echo_arguments_sync_twice( + &self, + to: ManagedAddress, + args: MultiValueEncoded, + ) { + let one_third_gas = self.blockchain().get_gas_left() / 3; + + let result = self + .tx() + .to(&to) + .gas(one_third_gas) + .typed(vault_proxy::VaultProxy) + .echo_arguments(args.clone()) + .returns(ReturnsResult) + .sync_call(); + + self.execute_on_dest_context_result_event(&result.into_vec_of_buffers()); + + let result = self + .tx() + .to(&to) + .gas(one_third_gas) + .typed(vault_proxy::VaultProxy) + .echo_arguments(args) + .returns(ReturnsResult) + .sync_call(); + + self.execute_on_dest_context_result_event(&result.into_vec_of_buffers()); + } + + #[event("echo_arguments_sync_result")] + fn execute_on_dest_context_result_event(&self, result: &ManagedVec); + + #[endpoint] + #[payable("*")] + fn forward_sync_accept_funds(&self, to: ManagedAddress) { + let payment = self.call_value().egld_or_single_esdt(); + let half_gas = self.blockchain().get_gas_left() / 2; + + let result = self + .tx() + .to(&to) + .gas(half_gas) + .typed(vault_proxy::VaultProxy) + .accept_funds_echo_payment() + .payment(payment) + .returns(ReturnsResult) + .sync_call(); + + let (egld_value, esdt_transfers_multi) = result.into_tuple(); + + self.accept_funds_sync_result_event(&egld_value, &esdt_transfers_multi); + } + + #[payable("*")] + #[endpoint] + fn forward_sync_accept_funds_with_fees(&self, to: ManagedAddress, percentage_fees: BigUint) { + let (token_id, payment) = self.call_value().egld_or_single_fungible_esdt(); + let fees = &payment * &percentage_fees / PERCENTAGE_TOTAL; + let amount_to_send = payment - fees; + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .egld_or_single_esdt(&token_id, 0u64, &amount_to_send) + .returns(ReturnsResult) + .sync_call(); + } + + #[event("accept_funds_sync_result")] + fn accept_funds_sync_result_event( + &self, + #[indexed] egld_value: &BigUint, + #[indexed] multi_esdt: &MultiValueEncoded, + ); + + #[endpoint] + #[payable("*")] + fn forward_sync_accept_funds_then_read(&self, to: ManagedAddress) -> usize { + let payment = self.call_value().egld_or_single_esdt(); + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .payment(payment) + .sync_call(); + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .call_counts(b"accept_funds") + .returns(ReturnsResult) + .sync_call() + } + + #[endpoint] + fn forward_sync_retrieve_funds( + &self, + to: ManagedAddress, + token: EgldOrEsdtTokenIdentifier, + token_nonce: u64, + amount: BigUint, + ) { + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .retrieve_funds(token, token_nonce, amount) + .sync_call(); + } + + #[payable("*")] + #[endpoint] + fn forward_sync_retrieve_funds_with_accept_func( + &self, + to: ManagedAddress, + token: TokenIdentifier, + amount: BigUint, + ) { + let payments = self.call_value().all_esdt_transfers(); + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .retrieve_funds_with_transfer_exec( + token, + amount, + OptionalValue::::Some(b"accept_funds_func".into()), + ) + .payment(payments) + .sync_call(); + } + + #[payable("*")] + #[endpoint] + fn accept_funds_func(&self) {} + + #[endpoint] + fn forward_sync_accept_funds_multi_transfer( + &self, + to: ManagedAddress, + token_payments: MultiValueEncoded>, + ) { + let mut all_token_payments = ManagedVec::new(); + + for multi_arg in token_payments.into_iter() { + let (token_identifier, token_nonce, amount) = multi_arg.into_tuple(); + let payment = EsdtTokenPayment::new(token_identifier, token_nonce, amount); + all_token_payments.push(payment); + } + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .payment(all_token_payments) + .sync_call(); + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_call_transf_exec.rs b/contracts/feature-tests/composability/forwarder/src/fwd_call_transf_exec.rs new file mode 100644 index 0000000000..952f50275c --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_call_transf_exec.rs @@ -0,0 +1,162 @@ +use crate::vault_proxy; + +multiversx_sc::imports!(); + +const PERCENTAGE_TOTAL: u64 = 10_000; // 100% + +#[multiversx_sc::module] +pub trait ForwarderTransferExecuteModule { + #[endpoint] + #[payable("*")] + fn forward_transf_exec_accept_funds(&self, to: ManagedAddress) { + let payment = self.call_value().egld_or_single_esdt(); + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .payment(payment) + .transfer_execute(); + } + + #[endpoint] + #[payable("*")] + fn forward_transf_execu_accept_funds_with_fees( + &self, + to: ManagedAddress, + percentage_fees: BigUint, + ) { + let (token_id, payment) = self.call_value().egld_or_single_fungible_esdt(); + let fees = &payment * &percentage_fees / PERCENTAGE_TOTAL; + let amount_to_send = payment - fees; + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .egld_or_single_esdt(&token_id, 0u64, &amount_to_send) + .transfer_execute(); + } + + #[endpoint] + #[payable("*")] + fn forward_transf_exec_accept_funds_twice(&self, to: ManagedAddress) { + let (token, token_nonce, payment) = self.call_value().egld_or_single_esdt().into_tuple(); + let half_payment = payment / 2u32; + let half_gas = self.blockchain().get_gas_left() / 2; + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .egld_or_single_esdt(&token, token_nonce, &half_payment) + .gas(half_gas) + .transfer_execute(); + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .egld_or_single_esdt(&token, token_nonce, &half_payment) + .gas(half_gas) + .transfer_execute(); + } + + /// Test that the default gas provided to the transfer_execute call + /// leaves enough in the transaction for finish to happen. + #[endpoint] + #[payable("*")] + fn forward_transf_exec_accept_funds_return_values( + &self, + to: ManagedAddress, + ) -> MultiValue4 { + let payment = self.call_value().egld_or_single_esdt(); + let payment_token = payment.token_identifier.clone(); + let gas_left_before = self.blockchain().get_gas_left(); + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .payment(payment) + .transfer_execute(); + + let gas_left_after = self.blockchain().get_gas_left(); + + ( + gas_left_before, + gas_left_after, + BigUint::zero(), + payment_token, + ) + .into() + } + + #[endpoint] + fn transf_exec_multi_accept_funds( + &self, + to: ManagedAddress, + token_payments: MultiValueEncoded>, + ) { + let mut all_token_payments = ManagedVec::new(); + + for multi_arg in token_payments.into_iter() { + let (token_identifier, token_nonce, amount) = multi_arg.into_tuple(); + let payment = EsdtTokenPayment::new(token_identifier, token_nonce, amount); + + all_token_payments.push(payment); + } + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .payment(all_token_payments) + .transfer_execute() + } + + #[endpoint] + fn forward_transf_exec_reject_funds_multi_transfer( + &self, + to: ManagedAddress, + token_payments: MultiValueEncoded>, + ) { + let mut all_token_payments = ManagedVec::new(); + + for multi_arg in token_payments.into_iter() { + let (token_identifier, token_nonce, amount) = multi_arg.into_tuple(); + let payment = EsdtTokenPayment::new(token_identifier, token_nonce, amount); + + all_token_payments.push(payment); + } + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .accept_funds() + .payment(all_token_payments) + .transfer_execute() + } + + #[endpoint] + fn transf_exec_multi_reject_funds( + &self, + to: ManagedAddress, + token_payments: MultiValueEncoded>, + ) { + let mut all_token_payments = ManagedVec::new(); + + for multi_arg in token_payments.into_iter() { + let (token_identifier, token_nonce, amount) = multi_arg.into_tuple(); + let payment = EsdtTokenPayment::new(token_identifier, token_nonce, amount); + + all_token_payments.push(payment); + } + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .reject_funds() + .payment(all_token_payments) + .transfer_execute() + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_change_owner.rs b/contracts/feature-tests/composability/forwarder/src/fwd_change_owner.rs new file mode 100644 index 0000000000..672d55c3f7 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_change_owner.rs @@ -0,0 +1,28 @@ +use crate::vault_proxy; + +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait ChangeOwnerModule { + #[endpoint(changeOwnerAddress)] + fn change_owner( + &self, + child_sc_address: ManagedAddress, + new_owner: ManagedAddress, + ) -> ManagedAddress { + self.send() + .change_owner_address(child_sc_address.clone(), &new_owner) + .sync_call(); + + self.get_owner_of_vault_contract(child_sc_address) + } + + fn get_owner_of_vault_contract(&self, address: ManagedAddress) -> ManagedAddress { + self.tx() + .to(&address) + .typed(vault_proxy::VaultProxy) + .get_owner_address() + .returns(ReturnsResult) + .sync_call() + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_deploy.rs b/contracts/feature-tests/composability/forwarder/src/fwd_deploy.rs new file mode 100644 index 0000000000..7145f2555a --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_deploy.rs @@ -0,0 +1,63 @@ +use crate::vault_proxy; + +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait DeployContractModule { + #[endpoint] + fn deploy_contract( + &self, + code: ManagedBuffer, + opt_arg: OptionalValue, + ) -> MultiValue2> { + self.perform_deploy_vault(&code, opt_arg).into() + } + + #[endpoint] + fn deploy_two_contracts( + &self, + code: ManagedBuffer, + ) -> MultiValue2 { + let (first_deployed_contract_address, _) = + self.perform_deploy_vault(&code, OptionalValue::None); + let (second_deployed_contract_address, _) = + self.perform_deploy_vault(&code, OptionalValue::None); + + ( + first_deployed_contract_address, + second_deployed_contract_address, + ) + .into() + } + + fn perform_deploy_vault( + &self, + code: &ManagedBuffer, + opt_arg: OptionalValue, + ) -> (ManagedAddress, OptionalValue) { + self.tx() + .typed(vault_proxy::VaultProxy) + .init(opt_arg) + .code(code.clone()) + .returns(ReturnsNewManagedAddress) + .returns(ReturnsResult) + .sync_call() + } + + #[endpoint] + fn deploy_vault_from_source( + &self, + source_address: ManagedAddress, + opt_arg: OptionalValue, + ) -> MultiValue2> { + self.tx() + .typed(vault_proxy::VaultProxy) + .init(opt_arg) + .code_metadata(CodeMetadata::DEFAULT) + .from_source(source_address) + .returns(ReturnsNewManagedAddress) + .returns(ReturnsResult) + .sync_call() + .into() + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs new file mode 100644 index 0000000000..fcc3912ecc --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs @@ -0,0 +1,219 @@ +multiversx_sc::imports!(); + +use super::fwd_storage; + +const PERCENTAGE_TOTAL: u64 = 10_000; // 100% + +pub type EsdtTokenDataMultiValue = MultiValue9< + EsdtTokenType, + BigUint, + bool, + ManagedBuffer, + ManagedBuffer, + ManagedBuffer, + ManagedAddress, + BigUint, + ManagedVec>, +>; + +#[multiversx_sc::module] +pub trait ForwarderEsdtModule: fwd_storage::ForwarderStorageModule { + #[view(getFungibleEsdtBalance)] + fn get_fungible_esdt_balance(&self, token_identifier: &TokenIdentifier) -> BigUint { + self.blockchain() + .get_esdt_balance(&self.blockchain().get_sc_address(), token_identifier, 0) + } + + #[view(getCurrentNftNonce)] + fn get_current_nft_nonce(&self, token_identifier: &TokenIdentifier) -> u64 { + self.blockchain() + .get_current_esdt_nft_nonce(&self.blockchain().get_sc_address(), token_identifier) + } + + #[endpoint] + fn send_esdt(&self, to: &ManagedAddress, token_id: TokenIdentifier, amount: &BigUint) { + self.tx() + .to(to) + .single_esdt(&token_id, 0, amount) + .transfer(); + } + + #[payable("*")] + #[endpoint] + fn send_esdt_with_fees(&self, to: ManagedAddress, percentage_fees: BigUint) { + let (token_id, payment) = self.call_value().single_fungible_esdt(); + let fees = &payment * &percentage_fees / PERCENTAGE_TOTAL; + let amount_to_send = payment - fees; + + self.tx() + .to(&to) + .single_esdt(&token_id, 0, &amount_to_send) + .transfer(); + } + + #[endpoint] + fn send_esdt_twice( + &self, + to: &ManagedAddress, + token_id: TokenIdentifier, + amount_first_time: &BigUint, + amount_second_time: &BigUint, + ) { + self.tx() + .to(to) + .single_esdt(&token_id, 0, amount_first_time) + .transfer(); + self.tx() + .to(to) + .single_esdt(&token_id, 0, amount_second_time) + .transfer(); + } + + #[endpoint] + fn send_esdt_direct_multi_transfer( + &self, + to: ManagedAddress, + token_payments: MultiValueEncoded>, + ) { + let mut all_token_payments = ManagedVec::new(); + + for multi_arg in token_payments.into_iter() { + let (token_identifier, token_nonce, amount) = multi_arg.into_tuple(); + let payment = EsdtTokenPayment::new(token_identifier, token_nonce, amount); + + all_token_payments.push(payment); + } + + self.tx().to(&to).payment(all_token_payments).transfer(); + } + + #[payable("EGLD")] + #[endpoint] + fn issue_fungible_token( + &self, + token_display_name: ManagedBuffer, + token_ticker: ManagedBuffer, + initial_supply: BigUint, + ) { + let issue_cost = self.call_value().egld_value(); + let caller = self.blockchain().get_caller(); + + self.send() + .esdt_system_sc_proxy() + .issue_fungible( + issue_cost.clone_value(), + &token_display_name, + &token_ticker, + &initial_supply, + FungibleTokenProperties { + num_decimals: 0, + can_freeze: true, + can_wipe: true, + can_pause: true, + can_mint: true, + can_burn: true, + can_change_owner: true, + can_upgrade: true, + can_add_special_roles: true, + }, + ) + .with_callback(self.callbacks().esdt_issue_callback(&caller)) + .async_call_and_exit() + } + + #[callback] + fn esdt_issue_callback( + &self, + caller: &ManagedAddress, + #[call_result] result: ManagedAsyncCallResult<()>, + ) { + let (token_identifier, returned_tokens) = self.call_value().egld_or_single_fungible_esdt(); + // callback is called with ESDTTransfer of the newly issued token, with the amount requested, + // so we can get the token identifier and amount from the call data + match result { + ManagedAsyncCallResult::Ok(()) => { + self.last_issued_token() + .set(&token_identifier.unwrap_esdt()); + self.last_error_message().clear(); + }, + ManagedAsyncCallResult::Err(message) => { + // return issue cost to the caller + if token_identifier.is_egld() && returned_tokens > 0 { + self.tx().to(caller).egld(&returned_tokens).transfer(); + } + + self.last_error_message().set(&message.err_msg); + }, + } + } + + #[endpoint] + fn local_mint(&self, token_identifier: TokenIdentifier, amount: BigUint) { + self.send().esdt_local_mint(&token_identifier, 0, &amount); + } + + #[endpoint] + fn local_burn(&self, token_identifier: TokenIdentifier, amount: BigUint) { + self.send().esdt_local_burn(&token_identifier, 0, &amount); + } + + #[view] + fn get_esdt_local_roles(&self, token_id: TokenIdentifier) -> MultiValueEncoded { + let roles = self.blockchain().get_esdt_local_roles(&token_id); + let mut result = MultiValueEncoded::new(); + for role in roles.iter_roles() { + result.push(role.as_role_name().into()); + } + result + } + + #[view] + fn get_esdt_token_data( + &self, + address: ManagedAddress, + token_id: TokenIdentifier, + nonce: u64, + ) -> EsdtTokenDataMultiValue { + let token_data = self + .blockchain() + .get_esdt_token_data(&address, &token_id, nonce); + + ( + token_data.token_type, + token_data.amount, + token_data.frozen, + token_data.hash, + token_data.name, + token_data.attributes, + token_data.creator, + token_data.royalties, + token_data.uris, + ) + .into() + } + + #[view] + fn is_esdt_frozen( + &self, + address: &ManagedAddress, + token_id: &TokenIdentifier, + nonce: u64, + ) -> bool { + self.blockchain().is_esdt_frozen(address, token_id, nonce) + } + + #[view] + fn is_esdt_paused(&self, token_id: &TokenIdentifier) -> bool { + self.blockchain().is_esdt_paused(token_id) + } + + #[view] + fn is_esdt_limited_transfer(&self, token_id: &TokenIdentifier) -> bool { + self.blockchain().is_esdt_limited_transfer(token_id) + } + + #[view] + fn validate_token_identifier(&self, token_id: TokenIdentifier) -> bool { + token_id.is_valid_esdt_identifier() + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs new file mode 100644 index 0000000000..5358397df9 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_nft.rs @@ -0,0 +1,298 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use super::fwd_storage; + +// used as mock attributes for NFTs +#[type_abi] +#[derive(TopEncode, TopDecode, Clone, Copy, PartialEq, Debug)] +pub struct Color { + pub r: u8, + pub g: u8, + pub b: u8, +} + +#[type_abi] +#[derive(TopEncode, TopDecode, PartialEq, Eq, Clone)] +pub struct ComplexAttributes { + pub biguint: BigUint, + pub vec_u8: ManagedBuffer, + pub token_id: TokenIdentifier, + pub boolean: bool, + pub boxed_bytes: ManagedBuffer, +} + +#[multiversx_sc::module] +pub trait ForwarderNftModule: fwd_storage::ForwarderStorageModule { + #[view] + fn get_nft_balance(&self, token_identifier: &TokenIdentifier, nonce: u64) -> BigUint { + self.blockchain().get_esdt_balance( + &self.blockchain().get_sc_address(), + token_identifier, + nonce, + ) + } + + #[payable("*")] + #[endpoint] + fn buy_nft(&self, nft_id: TokenIdentifier, nft_nonce: u64, nft_amount: BigUint) -> BigUint { + let payment = self.call_value().egld_or_single_esdt(); + + self.send().sell_nft( + &nft_id, + nft_nonce, + &nft_amount, + &self.blockchain().get_caller(), + &payment.token_identifier, + payment.token_nonce, + &payment.amount, + ) + } + + #[payable("EGLD")] + #[endpoint] + fn nft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { + let issue_cost = self.call_value().egld_value(); + let caller = self.blockchain().get_caller(); + + self.send() + .esdt_system_sc_proxy() + .issue_non_fungible( + issue_cost.clone_value(), + &token_display_name, + &token_ticker, + NonFungibleTokenProperties { + can_freeze: true, + can_wipe: true, + can_pause: true, + can_transfer_create_role: true, + can_change_owner: true, + can_upgrade: true, + can_add_special_roles: true, + }, + ) + .with_callback(self.callbacks().nft_issue_callback(&caller)) + .async_call_and_exit() + } + + #[callback] + fn nft_issue_callback( + &self, + caller: &ManagedAddress, + #[call_result] result: ManagedAsyncCallResult, + ) { + match result { + ManagedAsyncCallResult::Ok(token_identifier) => { + self.last_issued_token().set(&token_identifier); + self.last_error_message().clear(); + }, + ManagedAsyncCallResult::Err(message) => { + // return issue cost to the caller + let (token_identifier, returned_tokens) = + self.call_value().egld_or_single_fungible_esdt(); + if token_identifier.is_egld() && returned_tokens > 0 { + self.tx().to(caller).egld(&returned_tokens).transfer(); + } + + self.last_error_message().set(&message.err_msg); + }, + } + } + + #[endpoint] + fn nft_create( + &self, + token_identifier: TokenIdentifier, + amount: BigUint, + name: ManagedBuffer, + royalties: BigUint, + hash: ManagedBuffer, + color: Color, + uri: ManagedBuffer, + ) -> u64 { + let mut uris = ManagedVec::new(); + uris.push(uri); + let token_nonce = self.send().esdt_nft_create::( + &token_identifier, + &amount, + &name, + &royalties, + &hash, + &color, + &uris, + ); + + self.create_event(&token_identifier, token_nonce, &amount); + + token_nonce + } + + #[endpoint] + fn nft_create_compact(&self, token_identifier: TokenIdentifier, amount: BigUint, color: Color) { + self.send() + .esdt_nft_create_compact(&token_identifier, &amount, &color); + } + + #[endpoint] + fn nft_add_uris( + &self, + token_identifier: TokenIdentifier, + nonce: u64, + uris: MultiValueEncoded, + ) { + self.send() + .nft_add_multiple_uri(&token_identifier, nonce, &uris.to_vec()); + } + + #[endpoint] + fn nft_update_attributes( + &self, + token_identifier: TokenIdentifier, + nonce: u64, + new_attributes: Color, + ) { + self.send() + .nft_update_attributes(&token_identifier, nonce, &new_attributes); + } + + #[endpoint] + fn nft_decode_complex_attributes( + &self, + token_identifier: TokenIdentifier, + amount: BigUint, + name: ManagedBuffer, + royalties: BigUint, + hash: ManagedBuffer, + uri: ManagedBuffer, + attrs_arg: MultiValue5, + ) { + let attrs_pieces = attrs_arg.into_tuple(); + let orig_attr = ComplexAttributes { + biguint: attrs_pieces.0, + vec_u8: attrs_pieces.1, + token_id: attrs_pieces.2, + boolean: attrs_pieces.3, + boxed_bytes: attrs_pieces.4, + }; + + let mut uris = ManagedVec::new(); + uris.push(uri); + let token_nonce = self.send().esdt_nft_create::>( + &token_identifier, + &amount, + &name, + &royalties, + &hash, + &orig_attr, + &uris, + ); + + let token_info = self.blockchain().get_esdt_token_data( + &self.blockchain().get_sc_address(), + &token_identifier, + token_nonce, + ); + + let decoded_attr = token_info.decode_attributes::>(); + + require!( + orig_attr.biguint == decoded_attr.biguint + && orig_attr.vec_u8 == decoded_attr.vec_u8 + && orig_attr.token_id == decoded_attr.token_id + && orig_attr.boolean == decoded_attr.boolean + && orig_attr.boxed_bytes == decoded_attr.boxed_bytes, + "orig_attr != decoded_attr" + ); + } + + #[endpoint] + fn nft_add_quantity(&self, token_identifier: TokenIdentifier, nonce: u64, amount: BigUint) { + self.send() + .esdt_local_mint(&token_identifier, nonce, &amount); + } + + #[endpoint] + fn nft_burn(&self, token_identifier: TokenIdentifier, nonce: u64, amount: BigUint) { + self.send() + .esdt_local_burn(&token_identifier, nonce, &amount); + } + + #[endpoint] + fn transfer_nft_via_async_call( + &self, + to: ManagedAddress, + token_identifier: TokenIdentifier, + nonce: u64, + amount: BigUint, + ) { + self.send() + .transfer_esdt_via_async_call(to, token_identifier, nonce, amount); + } + + #[endpoint] + fn transfer_nft_and_execute( + &self, + to: ManagedAddress, + token_identifier: TokenIdentifier, + nonce: u64, + amount: BigUint, + function: ManagedBuffer, + arguments: MultiValueEncoded, + ) { + let gas_left = self.blockchain().get_gas_left(); + self.tx() + .to(&to) + .gas(gas_left) + .raw_call(function) + .arguments_raw(arguments.to_arg_buffer()) + .single_esdt(&token_identifier, nonce, &amount) + .transfer_execute(); + } + + #[endpoint] + fn create_and_send( + &self, + to: ManagedAddress, + token_identifier: TokenIdentifier, + amount: BigUint, + name: ManagedBuffer, + royalties: BigUint, + hash: ManagedBuffer, + color: Color, + uri: ManagedBuffer, + ) { + let token_nonce = self.nft_create( + token_identifier.clone(), + amount.clone(), + name, + royalties, + hash, + color, + uri, + ); + + self.tx() + .to(&to) + .single_esdt(&token_identifier, token_nonce, &amount) + .transfer(); + + self.send_event(&to, &token_identifier, token_nonce, &amount); + } + + #[event("create")] + fn create_event( + &self, + #[indexed] token_id: &TokenIdentifier, + #[indexed] token_nonce: u64, + #[indexed] amount: &BigUint, + ); + + #[event("send")] + fn send_event( + &self, + #[indexed] to: &ManagedAddress, + #[indexed] token_id: &TokenIdentifier, + #[indexed] token_nonce: u64, + #[indexed] amount: &BigUint, + ); +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_roles.rs b/contracts/feature-tests/composability/forwarder/src/fwd_roles.rs new file mode 100644 index 0000000000..e176b78991 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_roles.rs @@ -0,0 +1,46 @@ +multiversx_sc::imports!(); + +use super::fwd_storage; + +#[multiversx_sc::module] +pub trait ForwarderRolesModule: fwd_storage::ForwarderStorageModule { + #[endpoint(setLocalRoles)] + fn set_local_roles( + &self, + address: ManagedAddress, + token_identifier: TokenIdentifier, + roles: MultiValueEncoded, + ) { + self.send() + .esdt_system_sc_proxy() + .set_special_roles(&address, &token_identifier, roles.into_iter()) + .with_callback(self.callbacks().change_roles_callback()) + .async_call_and_exit() + } + + #[endpoint(unsetLocalRoles)] + fn unset_local_roles( + &self, + address: ManagedAddress, + token_identifier: TokenIdentifier, + roles: MultiValueEncoded, + ) { + self.send() + .esdt_system_sc_proxy() + .unset_special_roles(&address, &token_identifier, roles.into_iter()) + .with_callback(self.callbacks().change_roles_callback()) + .async_call_and_exit() + } + + #[callback] + fn change_roles_callback(&self, #[call_result] result: ManagedAsyncCallResult<()>) { + match result { + ManagedAsyncCallResult::Ok(()) => { + self.last_error_message().clear(); + }, + ManagedAsyncCallResult::Err(message) => { + self.last_error_message().set(&message.err_msg); + }, + } + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs b/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs new file mode 100644 index 0000000000..13d0b3a5ad --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_sft.rs @@ -0,0 +1,56 @@ +multiversx_sc::imports!(); + +use super::fwd_storage; + +#[multiversx_sc::module] +pub trait ForwarderSftModule: fwd_storage::ForwarderStorageModule { + #[payable("EGLD")] + #[endpoint] + fn sft_issue(&self, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer) { + let issue_cost = self.call_value().egld_value(); + let caller = self.blockchain().get_caller(); + + self.send() + .esdt_system_sc_proxy() + .issue_semi_fungible( + issue_cost.clone_value(), + &token_display_name, + &token_ticker, + SemiFungibleTokenProperties { + can_freeze: true, + can_wipe: true, + can_pause: true, + can_transfer_create_role: true, + can_change_owner: true, + can_upgrade: true, + can_add_special_roles: true, + }, + ) + .with_callback(self.callbacks().sft_issue_callback(&caller)) + .async_call_and_exit() + } + + #[callback] + fn sft_issue_callback( + &self, + caller: &ManagedAddress, + #[call_result] result: ManagedAsyncCallResult, + ) { + match result { + ManagedAsyncCallResult::Ok(token_identifier) => { + self.last_issued_token().set(&token_identifier); + self.last_error_message().clear(); + }, + ManagedAsyncCallResult::Err(message) => { + // return issue cost to the caller + let (token_identifier, returned_tokens) = + self.call_value().egld_or_single_fungible_esdt(); + if token_identifier.is_egld() && returned_tokens > 0 { + self.tx().to(caller).egld(&returned_tokens).transfer(); + } + + self.last_error_message().set(&message.err_msg); + }, + } + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_storage.rs b/contracts/feature-tests/composability/forwarder/src/fwd_storage.rs new file mode 100644 index 0000000000..f27887b63f --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_storage.rs @@ -0,0 +1,12 @@ +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait ForwarderStorageModule { + #[view(lastIssuedToken)] + #[storage_mapper("lastIssuedToken")] + fn last_issued_token(&self) -> SingleValueMapper; + + #[view(lastErrorMessage)] + #[storage_mapper("lastErrorMessage")] + fn last_error_message(&self) -> SingleValueMapper; +} diff --git a/contracts/feature-tests/composability/forwarder/src/fwd_upgrade.rs b/contracts/feature-tests/composability/forwarder/src/fwd_upgrade.rs new file mode 100644 index 0000000000..f4782821e0 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_upgrade.rs @@ -0,0 +1,38 @@ +use crate::vault_proxy; + +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait UpgradeContractModule { + #[endpoint(upgradeVault)] + fn upgrade_vault( + &self, + child_sc_address: ManagedAddress, + new_code: ManagedBuffer, + opt_arg: OptionalValue, + ) { + self.tx() + .to(child_sc_address) + .typed(vault_proxy::VaultProxy) + .upgrade(opt_arg) + .code(new_code) + .code_metadata(CodeMetadata::UPGRADEABLE) + .upgrade_async_call_and_exit(); + } + + #[endpoint] + fn upgrade_vault_from_source( + &self, + child_sc_address: ManagedAddress, + source_address: ManagedAddress, + opt_arg: OptionalValue, + ) { + self.tx() + .to(child_sc_address) + .typed(vault_proxy::VaultProxy) + .upgrade(opt_arg) + .code_metadata(CodeMetadata::UPGRADEABLE) + .from_source(source_address) + .upgrade_async_call_and_exit(); + } +} diff --git a/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs b/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs new file mode 100644 index 0000000000..24e6f12e69 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs @@ -0,0 +1,273 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct VaultProxy; + +impl TxProxyTrait for VaultProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = VaultProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + VaultProxyMethods { wrapped_tx: tx } + } +} + +pub struct VaultProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>>, + >( + self, + opt_arg_to_echo: Arg0, + ) -> TxTypedDeploy>> { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&opt_arg_to_echo) + .original_result() + } +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade< + Arg0: ProxyArg>>, + >( + self, + opt_arg_to_echo: Arg0, + ) -> TxTypedUpgrade>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .argument(&opt_arg_to_echo) + .original_result() + } +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn echo_arguments< + Arg0: ProxyArg>>, + >( + self, + args: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_arguments") + .argument(&args) + .original_result() + } + + pub fn echo_arguments_without_storage< + Arg0: ProxyArg>>, + >( + self, + args: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_arguments_without_storage") + .argument(&args) + .original_result() + } + + pub fn echo_caller( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_caller") + .original_result() + } + + pub fn accept_funds( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds") + .original_result() + } + + pub fn accept_funds_echo_payment( + self, + ) -> TxTypedCall, MultiValueEncoded>>> { + self.wrapped_tx + .raw_call("accept_funds_echo_payment") + .original_result() + } + + pub fn accept_funds_single_esdt_transfer( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds_single_esdt_transfer") + .original_result() + } + + pub fn reject_funds( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("reject_funds") + .original_result() + } + + pub fn retrieve_funds_with_transfer_exec< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + token: Arg0, + amount: Arg1, + opt_receive_func: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("retrieve_funds_with_transfer_exec") + .argument(&token) + .argument(&amount) + .argument(&opt_receive_func) + .original_result() + } + + pub fn retrieve_funds_promises< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + back_transfers: Arg0, + back_transfer_value: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("retrieve_funds_promises") + .argument(&back_transfers) + .argument(&back_transfer_value) + .original_result() + } + + pub fn retrieve_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + token: Arg0, + nonce: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("retrieve_funds") + .argument(&token) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn retrieve_multi_funds_async< + Arg0: ProxyArg, u64, BigUint>>>, + >( + self, + token_payments: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("retrieve_multi_funds_async") + .argument(&token_payments) + .original_result() + } + + pub fn burn_and_create_retrieve_async( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("burn_and_create_retrieve_async") + .original_result() + } + + pub fn get_owner_address( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_owner_address") + .original_result() + } + + /// We already leave a trace of the calls using the event logs; + /// this additional counter has the role of showing that storage also gets saved correctly. + pub fn call_counts< + Arg0: ProxyArg>, + >( + self, + endpoint: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("call_counts") + .argument(&endpoint) + .original_result() + } + + pub fn num_called_retrieve_funds_promises( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("num_called_retrieve_funds_promises") + .original_result() + } + + pub fn num_async_calls_sent_from_child( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("num_async_calls_sent_from_child") + .original_result() + } +} diff --git a/contracts/feature-tests/composability/forwarder/wasm/Cargo.lock b/contracts/feature-tests/composability/forwarder/wasm/Cargo.lock index 3d866d859a..b7dd35fde6 100755 --- a/contracts/feature-tests/composability/forwarder/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/forwarder/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -31,7 +31,6 @@ name = "forwarder" version = "0.0.0" dependencies = [ "multiversx-sc", - "vault", ] [[package]] @@ -56,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -85,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -96,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -112,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -149,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -171,8 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "vault" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/forwarder/wasm/Cargo.toml b/contracts/feature-tests/composability/forwarder/wasm/Cargo.toml index e9af598856..07085abea6 100644 --- a/contracts/feature-tests/composability/forwarder/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.forwarder] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs b/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs index 2fe9d2486c..fd2567f244 100644 --- a/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 68 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/interact/Cargo.toml b/contracts/feature-tests/composability/interact/Cargo.toml index 3ca2ae6953..a041e0518f 100644 --- a/contracts/feature-tests/composability/interact/Cargo.toml +++ b/contracts/feature-tests/composability/interact/Cargo.toml @@ -14,19 +14,10 @@ clap = { version = "4.4.7", features = ["derive"] } serde = { version = "1.0", features = ["derive"] } toml = "0.8.6" -[dependencies.vault] -path = "../vault" - -[dependencies.forwarder-queue] -path = "../forwarder-queue" - -[dependencies.promises-features] -path = "../promises-features" - -[dependencies.multiversx-sc-modules] -version = "0.47.5" -path = "../../../../contracts/modules" +[dependencies.multiversx-sc] +version = "0.50.3" +path = "../../../../framework/base" [dependencies.multiversx-sc-snippets] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/snippets" diff --git a/contracts/feature-tests/composability/interact/src/call_tree_calling_functions.rs b/contracts/feature-tests/composability/interact/src/call_tree_calling_functions.rs index 9e86f5dfdb..0cb35bdbec 100644 --- a/contracts/feature-tests/composability/interact/src/call_tree_calling_functions.rs +++ b/contracts/feature-tests/composability/interact/src/call_tree_calling_functions.rs @@ -1,22 +1,13 @@ use std::{cell::RefCell, rc::Rc}; -use forwarder_queue::QueuedCallType; -use multiversx_sc_snippets::{ - multiversx_sc::types::{EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, MultiValueEncoded}, - multiversx_sc_scenario::{ - api::StaticApi, - bech32, - num_bigint::BigUint, - scenario_model::{ScCallStep, TxExpect}, - }, - StepBuffer, -}; +use multiversx_sc_snippets::imports::*; +use num_bigint::BigUint; use crate::{ call_tree::{CallNode, CallState, ForwarderQueueTarget}, comp_interact_controller::ComposabilityInteract, + forwarder_queue_proxy::{self, QueuedCallType}, }; -use forwarder_queue::ProxyTrait; const FORWARD_QUEUED_CALLS_ENDPOINT: &str = "forward_queued_calls"; const DEFAULT_GAS_LIMIT: u64 = 10_000_000; @@ -31,7 +22,7 @@ impl ComposabilityInteract { payment_nonce: u64, payment_amount: BigUint, ) { - let mut steps = Vec::new(); + let mut buffer = self.interactor.homogenous_call_buffer(); for fwd_rc in forwarders { let (fwd_name, fwd_children) = { @@ -42,8 +33,6 @@ impl ComposabilityInteract { let fwd = fwd_rc.borrow(); fwd.address.clone().unwrap() }; - let fwd_addr_bech32 = bech32::encode(&fwd_addr); - let fwd_addr_expr = format!("bech32:{fwd_addr_bech32}"); for child in &fwd_children { match child { @@ -55,29 +44,26 @@ impl ComposabilityInteract { child_fwd.address.clone().unwrap() }; - let typed_sc_call = ScCallStep::new() - .call( - self.state - .forwarder_queue_from_addr(&fwd_addr_expr) - .add_queued_call( - call_type.clone(), - child_fwd_addr, - DEFAULT_GAS_LIMIT, - FORWARD_QUEUED_CALLS_ENDPOINT, - MultiValueEncoded::::new(), - ) - .with_egld_or_single_esdt_transfer( - EgldOrEsdtTokenPayment::new( - payment_token.clone(), - payment_nonce, - payment_amount.clone().into(), - ), - ), - ) - .from(&self.wallet_address) - .gas_limit("70,000,000"); - - steps.push(typed_sc_call); + buffer.push_tx(|tx| { + tx.from(&self.wallet_address) + .to(&fwd_addr) + .gas(70_000_000u64) + .typed(forwarder_queue_proxy::ForwarderQueueProxy) + .add_queued_call( + call_type.clone(), + child_fwd_addr, + DEFAULT_GAS_LIMIT, + FORWARD_QUEUED_CALLS_ENDPOINT, + MultiValueEncoded::::new(), + ) + .payment(EgldOrEsdtTokenPayment::new( + payment_token.clone(), + payment_nonce, + payment_amount.clone().into(), + )) + .returns(ReturnsStatus) + .returns(ReturnsResult) + }); }, CallNode::Vault(vault_rc) => { // Call Vault @@ -87,46 +73,41 @@ impl ComposabilityInteract { vault.address.clone().unwrap() }; - let typed_sc_call = ScCallStep::new() - .call( - self.state - .forwarder_queue_from_addr(&fwd_addr_expr) - .add_queued_call( - call_type.clone(), - vault_addr, - DEFAULT_GAS_LIMIT, - endpoint_name, - MultiValueEncoded::::new(), - ) - .with_egld_or_single_esdt_transfer( - EgldOrEsdtTokenPayment::new( - payment_token.clone(), - payment_nonce, - payment_amount.clone().into(), - ), - ), - ) - .from(&self.wallet_address) - .gas_limit("70,000,000"); - - steps.push(typed_sc_call); + buffer.push_tx(|tx| { + tx.from(&self.wallet_address) + .to(&fwd_addr) + .gas(70_000_000u64) + .typed(forwarder_queue_proxy::ForwarderQueueProxy) + .add_queued_call( + call_type.clone(), + vault_addr, + DEFAULT_GAS_LIMIT, + endpoint_name, + MultiValueEncoded::::new(), + ) + .payment(EgldOrEsdtTokenPayment::new( + payment_token.clone(), + payment_nonce, + payment_amount.clone().into(), + )) + .returns(ReturnsStatus) + .returns(ReturnsResult) + }); }, } } } - self.interactor - .multi_sc_exec(StepBuffer::from_sc_call_vec(&mut steps)) - .await; - for step in steps.iter() { - if !step.response().is_success() { - println!( - "perform 'add_queued_call' failed with: {}", - step.response().tx_error - ); + let results = buffer.run().await; + + for (index, (status, result)) in results.iter().enumerate() { + if !status == 0u64 { + println!("perform 'add_queued_call' failed with error code {status}"); continue; } - println!("successfully performed action 'add_queued_call'"); + println!( + "successfully performed action {index} 'add_queued_call' with result {result:?}" + ); } } @@ -135,21 +116,16 @@ impl ComposabilityInteract { let root_addr_ref = call_state.root.borrow(); root_addr_ref.address.clone().unwrap() }; - let root_addr_bech32 = bech32::encode(&root_addr); - let root_addr_expr = format!("bech32:{root_addr_bech32}"); self.interactor - .sc_call( - ScCallStep::new() - .call( - self.state - .forwarder_queue_from_addr(&root_addr_expr) - .forward_queued_calls(), - ) - .from(&self.wallet_address) - .gas_limit("70,000,000") - .expect(TxExpect::ok().additional_error_message("calling root failed with: ")), - ) + .tx() + .from(&self.wallet_address) + .gas(70_000_000u64) + .to(&root_addr) + .typed(forwarder_queue_proxy::ForwarderQueueProxy) + .forward_queued_calls() + .prepare_async() + .run() .await; println!("successfully called root"); diff --git a/contracts/feature-tests/composability/interact/src/call_tree_deploy.rs b/contracts/feature-tests/composability/interact/src/call_tree_deploy.rs index c9c2f1498c..89d4000c7f 100644 --- a/contracts/feature-tests/composability/interact/src/call_tree_deploy.rs +++ b/contracts/feature-tests/composability/interact/src/call_tree_deploy.rs @@ -1,110 +1,66 @@ -use crate::{call_tree::CallState, comp_interact_controller::ComposabilityInteract}; - -use forwarder_queue::ProxyTrait as _; -use multiversx_sc_snippets::{ - multiversx_sc::{ - codec::multi_types::OptionalValue, - types::{BoxedBytes, ManagedBuffer}, - }, - multiversx_sc_scenario::{ - api::StaticApi, - bech32, - scenario_model::{ScDeployStep, TypedScDeploy}, - }, - StepBuffer, +use crate::{ + call_tree::CallState, comp_interact_controller::ComposabilityInteract, forwarder_queue_proxy, + vault_proxy, }; -use vault::ProxyTrait as _; + +use multiversx_sc_snippets::imports::*; impl ComposabilityInteract { pub async fn deploy_call_tree_contracts(&mut self, call_state: &CallState) { - let mut typed_vault_deploys = self.typed_sc_deploy_vault(call_state).await; - let mut typed_forwarder_deploys = self.typed_sc_deploy_forwarder_queue(call_state).await; - - let mut steps = Vec::new(); - for typed_sc_deploy in &mut typed_vault_deploys { - steps.push(typed_sc_deploy.as_mut()); - } - for typed_sc_deploy in &mut typed_forwarder_deploys { - steps.push(typed_sc_deploy.as_mut()); - } - - self.interactor - .multi_sc_exec(StepBuffer::from_sc_deploy_vec(&mut steps)) - .await; + let vault_deploy_addresses = self.typed_sc_deploy_vault(call_state).await; + let forwarder_deploy_addresses = self.typed_sc_deploy_forwarder_queue(call_state).await; let mut vault_iter = call_state.vaults.iter(); - for step in typed_vault_deploys.iter() { - if let Some(new_address) = step.response().new_deployed_address.clone() { - let new_address_bech32 = bech32::encode(&new_address); - let rc_vault = vault_iter.next().unwrap(); - let mut vault = rc_vault.borrow_mut(); - println!( - "New vault {0} deployed address: {1}", - vault.name, new_address_bech32 - ); + for address in vault_deploy_addresses.iter() { + let rc_vault = vault_iter.next().unwrap(); + let mut vault = rc_vault.borrow_mut(); + println!("New vault {0} deployed address: {1}", vault.name, address); - vault.address = Some(new_address); - } else { - println!("deploy failed"); - return; - } + vault.address = Some(address.to_address()); } let mut fwd_iter = call_state.forwarders.iter(); - for step in typed_forwarder_deploys.iter() { - if let Some(new_address) = step.response().new_deployed_address.clone() { - let new_address_bech32 = bech32::encode(&new_address); - let rc_fwd = fwd_iter.next().unwrap(); - let mut fwd = rc_fwd.borrow_mut(); - println!( - "New forwarder {0} deployed address: {1}", - fwd.name, new_address_bech32 - ); + for address in forwarder_deploy_addresses.iter() { + let rc_fwd = fwd_iter.next().unwrap(); + let mut fwd = rc_fwd.borrow_mut(); + println!("New forwarder {0} deployed address: {1}", fwd.name, address); - fwd.address = Some(new_address); - } else { - println!("deploy failed"); - return; - } + fwd.address = Some(address.to_address()); } } - pub async fn typed_sc_deploy_vault( - &mut self, - call_state: &CallState, - ) -> Vec>>> { - let mut typed_vault_deploys = Vec::new(); + pub async fn typed_sc_deploy_vault(&mut self, call_state: &CallState) -> Vec { + let mut buffer = self.interactor.homogenous_call_buffer(); for _ in call_state.vaults.iter() { - let typed_sc_deploy = ScDeployStep::new() - .call( - self.state - .default_vault_address() - .init(OptionalValue::::None), - ) - .from(&self.wallet_address) - .code(&self.vault_code) - .gas_limit("70,000,000"); - - typed_vault_deploys.push(typed_sc_deploy); + buffer.push_tx(|tx| { + tx.from(&self.wallet_address) + .typed(vault_proxy::VaultProxy) + .init(OptionalValue::::None) + .code(&self.vault_code) + .gas(NumExpr("70,000,000")) + .returns(ReturnsNewBech32Address) + }); } - typed_vault_deploys + + buffer.run().await } pub async fn typed_sc_deploy_forwarder_queue( &mut self, call_state: &CallState, - ) -> Vec> { - let mut typed_forwarder_deploys = Vec::new(); - + ) -> Vec { + let mut buffer = self.interactor.homogenous_call_buffer(); for _ in call_state.forwarders.iter() { - let typed_sc_deploy = ScDeployStep::new() - .call(self.state.default_forwarder_queue_address().init()) - .from(&self.wallet_address) - .code(&self.forw_queue_code) - .gas_limit("70,000,000"); - - typed_forwarder_deploys.push(typed_sc_deploy); + buffer.push_tx(|tx| { + tx.from(&self.wallet_address) + .typed(forwarder_queue_proxy::ForwarderQueueProxy) + .init() + .code(&self.forw_queue_code) + .gas(NumExpr("70,000,000")) + .returns(ReturnsNewBech32Address) + }); } - typed_forwarder_deploys + + buffer.run().await } } diff --git a/contracts/feature-tests/composability/interact/src/comp_interact_config.rs b/contracts/feature-tests/composability/interact/src/comp_interact_config.rs index c27957a9fb..d09c2323f7 100644 --- a/contracts/feature-tests/composability/interact/src/comp_interact_config.rs +++ b/contracts/feature-tests/composability/interact/src/comp_interact_config.rs @@ -1,11 +1,10 @@ -use forwarder_queue::QueuedCallType; -use multiversx_sc_snippets::{ - multiversx_sc::types::{EgldOrEsdtTokenIdentifier, TokenIdentifier}, - multiversx_sc_scenario::{api::StaticApi, num_bigint::BigUint}, -}; +use multiversx_sc_snippets::imports::*; +use num_bigint::BigUint; use serde::Deserialize; use std::{fmt::Debug, io::Read, str::FromStr}; +use crate::forwarder_queue_proxy::QueuedCallType; + /// Config file const CONFIG_FILE: &str = "config.toml"; diff --git a/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs b/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs index f5851d6e6c..1c2457494b 100644 --- a/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs +++ b/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs @@ -1,14 +1,6 @@ use crate::{call_tree::CallState, comp_interact_config::Config, comp_interact_state::State}; -use multiversx_sc_snippets::{ - multiversx_sc::types::Address, - multiversx_sc_scenario::{ - scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext}, - scenario_model::BytesValue, - test_wallets::judy, - }, - Interactor, -}; +use multiversx_sc_snippets::imports::*; const INTERACTOR_SCENARIO_TRACE_PATH: &str = "comp_interact_trace.scen.json"; @@ -17,6 +9,7 @@ pub struct ComposabilityInteract { pub wallet_address: Address, pub forw_queue_code: BytesValue, pub vault_code: BytesValue, + #[allow(dead_code)] pub state: State, } @@ -27,7 +20,7 @@ impl ComposabilityInteract { .await .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; - let wallet_address = interactor.register_wallet(judy()); + let wallet_address = interactor.register_wallet(test_wallets::judy()); let forw_queue_code = BytesValue::interpret_from( "mxsc:../forwarder-queue/output/forwarder-queue.mxsc.json", &InterpreterContext::default(), diff --git a/contracts/feature-tests/composability/interact/src/comp_interact_main.rs b/contracts/feature-tests/composability/interact/src/comp_interact_main.rs index b6e0ba9778..1652d66b76 100644 --- a/contracts/feature-tests/composability/interact/src/comp_interact_main.rs +++ b/contracts/feature-tests/composability/interact/src/comp_interact_main.rs @@ -8,15 +8,12 @@ mod comp_interact_config; mod comp_interact_controller; mod comp_interact_state; -use clap::Parser; +mod forwarder_queue_proxy; +mod vault_proxy; +use clap::Parser; use comp_interact_controller::ComposabilityInteract; - -use multiversx_sc_snippets::{ - env_logger, - multiversx_sc_scenario::{api::StaticApi, ContractInfo}, - tokio, -}; +use multiversx_sc_snippets::imports::*; #[tokio::main] async fn main() { diff --git a/contracts/feature-tests/composability/interact/src/comp_interact_state.rs b/contracts/feature-tests/composability/interact/src/comp_interact_state.rs index f9f676636c..fc2b7be1ad 100644 --- a/contracts/feature-tests/composability/interact/src/comp_interact_state.rs +++ b/contracts/feature-tests/composability/interact/src/comp_interact_state.rs @@ -1,20 +1,12 @@ -use crate::{ContractInfo, StaticApi}; use serde::{Deserialize, Serialize}; use std::{ io::{Read, Write}, path::Path, }; -/// Default contract address -const DEFAULT_CONTRACT_ADDRESS: &str = - "0x0000000000000000000000000000000000000000000000000000000000000000"; - /// State file const STATE_FILE: &str = "state.toml"; -pub type VaultContract = ContractInfo>; -pub type ForwarderQueueContract = ContractInfo>; - /// Composability Interact state #[derive(Debug, Default, Serialize, Deserialize)] pub struct State { @@ -35,21 +27,6 @@ impl State { Self::default() } } - - /// Returns the forwarder-queue contract - pub fn forwarder_queue_from_addr(&self, address: &str) -> ForwarderQueueContract { - ForwarderQueueContract::new(address) - } - - /// Returns the vault contract with default address - pub fn default_vault_address(&self) -> VaultContract { - VaultContract::new(DEFAULT_CONTRACT_ADDRESS) - } - - /// Returns the forwarder-queue contract with default address - pub fn default_forwarder_queue_address(&self) -> ForwarderQueueContract { - ForwarderQueueContract::new(DEFAULT_CONTRACT_ADDRESS) - } } impl Drop for State { diff --git a/contracts/feature-tests/composability/interact/src/forwarder_queue_proxy.rs b/contracts/feature-tests/composability/interact/src/forwarder_queue_proxy.rs new file mode 100644 index 0000000000..da3775365f --- /dev/null +++ b/contracts/feature-tests/composability/interact/src/forwarder_queue_proxy.rs @@ -0,0 +1,251 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct ForwarderQueueProxy; + +impl TxProxyTrait for ForwarderQueueProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = ForwarderQueueProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + ForwarderQueueProxyMethods { wrapped_tx: tx } + } +} + +pub struct ForwarderQueueProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl ForwarderQueueProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl ForwarderQueueProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn queued_calls( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("queued_calls") + .original_result() + } + + pub fn add_queued_call_sync< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + to: Arg0, + endpoint_name: Arg1, + args: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("add_queued_call_sync") + .argument(&to) + .argument(&endpoint_name) + .argument(&args) + .original_result() + } + + pub fn add_queued_call_legacy_async< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + to: Arg0, + endpoint_name: Arg1, + args: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("add_queued_call_legacy_async") + .argument(&to) + .argument(&endpoint_name) + .argument(&args) + .original_result() + } + + pub fn add_queued_call_transfer_execute< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + Arg3: ProxyArg>>, + >( + self, + to: Arg0, + gas_limit: Arg1, + endpoint_name: Arg2, + args: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("add_queued_call_transfer_execute") + .argument(&to) + .argument(&gas_limit) + .argument(&endpoint_name) + .argument(&args) + .original_result() + } + + pub fn add_queued_call_transfer_esdt< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + Arg5: ProxyArg>>, + >( + self, + to: Arg0, + gas_limit: Arg1, + endpoint_name: Arg2, + token: Arg3, + amount: Arg4, + args: Arg5, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("add_queued_call_transfer_esdt") + .argument(&to) + .argument(&gas_limit) + .argument(&endpoint_name) + .argument(&token) + .argument(&amount) + .argument(&args) + .original_result() + } + + pub fn add_queued_call_promise< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + Arg3: ProxyArg>>, + >( + self, + to: Arg0, + gas_limit: Arg1, + endpoint_name: Arg2, + args: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("add_queued_call_promise") + .argument(&to) + .argument(&gas_limit) + .argument(&endpoint_name) + .argument(&args) + .original_result() + } + + pub fn add_queued_call< + Arg0: ProxyArg, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + Arg4: ProxyArg>>, + >( + self, + call_type: Arg0, + to: Arg1, + gas_limit: Arg2, + endpoint_name: Arg3, + args: Arg4, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("add_queued_call") + .argument(&call_type) + .argument(&to) + .argument(&gas_limit) + .argument(&endpoint_name) + .argument(&args) + .original_result() + } + + pub fn forward_queued_calls( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_queued_calls") + .original_result() + } + + pub fn callback_count( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("callback_count") + .original_result() + } + + pub fn callback_payments( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("callback_payments") + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, Clone)] +pub struct QueuedCall +where + Api: ManagedTypeApi, +{ + pub call_type: QueuedCallType, + pub to: ManagedAddress, + pub gas_limit: u64, + pub endpoint_name: ManagedBuffer, + pub args: ManagedArgBuffer, + pub payments: EgldOrMultiEsdtPayment, +} + +#[type_abi] +#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, Clone)] +pub enum QueuedCallType { + Sync, + LegacyAsync, + TransferExecute, + Promise, +} diff --git a/contracts/feature-tests/composability/interact/src/vault_proxy.rs b/contracts/feature-tests/composability/interact/src/vault_proxy.rs new file mode 100644 index 0000000000..24e6f12e69 --- /dev/null +++ b/contracts/feature-tests/composability/interact/src/vault_proxy.rs @@ -0,0 +1,273 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct VaultProxy; + +impl TxProxyTrait for VaultProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = VaultProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + VaultProxyMethods { wrapped_tx: tx } + } +} + +pub struct VaultProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>>, + >( + self, + opt_arg_to_echo: Arg0, + ) -> TxTypedDeploy>> { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&opt_arg_to_echo) + .original_result() + } +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade< + Arg0: ProxyArg>>, + >( + self, + opt_arg_to_echo: Arg0, + ) -> TxTypedUpgrade>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .argument(&opt_arg_to_echo) + .original_result() + } +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn echo_arguments< + Arg0: ProxyArg>>, + >( + self, + args: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_arguments") + .argument(&args) + .original_result() + } + + pub fn echo_arguments_without_storage< + Arg0: ProxyArg>>, + >( + self, + args: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_arguments_without_storage") + .argument(&args) + .original_result() + } + + pub fn echo_caller( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_caller") + .original_result() + } + + pub fn accept_funds( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds") + .original_result() + } + + pub fn accept_funds_echo_payment( + self, + ) -> TxTypedCall, MultiValueEncoded>>> { + self.wrapped_tx + .raw_call("accept_funds_echo_payment") + .original_result() + } + + pub fn accept_funds_single_esdt_transfer( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds_single_esdt_transfer") + .original_result() + } + + pub fn reject_funds( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("reject_funds") + .original_result() + } + + pub fn retrieve_funds_with_transfer_exec< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + token: Arg0, + amount: Arg1, + opt_receive_func: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("retrieve_funds_with_transfer_exec") + .argument(&token) + .argument(&amount) + .argument(&opt_receive_func) + .original_result() + } + + pub fn retrieve_funds_promises< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + back_transfers: Arg0, + back_transfer_value: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("retrieve_funds_promises") + .argument(&back_transfers) + .argument(&back_transfer_value) + .original_result() + } + + pub fn retrieve_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + token: Arg0, + nonce: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("retrieve_funds") + .argument(&token) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn retrieve_multi_funds_async< + Arg0: ProxyArg, u64, BigUint>>>, + >( + self, + token_payments: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("retrieve_multi_funds_async") + .argument(&token_payments) + .original_result() + } + + pub fn burn_and_create_retrieve_async( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("burn_and_create_retrieve_async") + .original_result() + } + + pub fn get_owner_address( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_owner_address") + .original_result() + } + + /// We already leave a trace of the calls using the event logs; + /// this additional counter has the role of showing that storage also gets saved correctly. + pub fn call_counts< + Arg0: ProxyArg>, + >( + self, + endpoint: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("call_counts") + .argument(&endpoint) + .original_result() + } + + pub fn num_called_retrieve_funds_promises( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("num_called_retrieve_funds_promises") + .original_result() + } + + pub fn num_async_calls_sent_from_child( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("num_async_calls_sent_from_child") + .original_result() + } +} diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/Cargo.toml b/contracts/feature-tests/composability/local-esdt-and-nft/Cargo.toml index 3f9638f4d2..807849bb25 100644 --- a/contracts/feature-tests/composability/local-esdt-and-nft/Cargo.toml +++ b/contracts/feature-tests/composability/local-esdt-and-nft/Cargo.toml @@ -10,9 +10,9 @@ path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/meta/Cargo.toml b/contracts/feature-tests/composability/local-esdt-and-nft/meta/Cargo.toml index 8b6d5f3929..ec95b9a5b5 100644 --- a/contracts/feature-tests/composability/local-esdt-and-nft/meta/Cargo.toml +++ b/contracts/feature-tests/composability/local-esdt-and-nft/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.local-esdt-and-nft] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/meta/src/main.rs b/contracts/feature-tests/composability/local-esdt-and-nft/meta/src/main.rs index 17c70f7f41..3e0f8441dc 100644 --- a/contracts/feature-tests/composability/local-esdt-and-nft/meta/src/main.rs +++ b/contracts/feature-tests/composability/local-esdt-and-nft/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs b/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs index 235e3cde63..55f0577795 100644 --- a/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs +++ b/contracts/feature-tests/composability/local-esdt-and-nft/src/lib.rs @@ -48,9 +48,8 @@ pub trait LocalEsdtAndEsdtNft { can_add_special_roles: true, }, ) - .async_call() .with_callback(self.callbacks().esdt_issue_callback(&caller)) - .call_and_exit() + .async_call_and_exit() } #[endpoint(localMint)] @@ -87,9 +86,8 @@ pub trait LocalEsdtAndEsdtNft { can_add_special_roles: true, }, ) - .async_call() .with_callback(self.callbacks().nft_issue_callback(&caller)) - .call_and_exit() + .async_call_and_exit() } #[endpoint(nftCreate)] @@ -138,8 +136,10 @@ pub trait LocalEsdtAndEsdtNft { nonce: u64, amount: BigUint, ) { - self.send() - .transfer_esdt_via_async_call(to, token_identifier, nonce, amount); + self.tx() + .to(to) + .esdt((token_identifier, nonce, amount)) + .async_call_and_exit(); } #[endpoint] @@ -157,15 +157,15 @@ pub trait LocalEsdtAndEsdtNft { arg_buffer.push_arg_raw(arg); } - let _ = self.send_raw().transfer_esdt_nft_execute( - &to, - &token_identifier, - nonce, - &amount, - self.blockchain().get_gas_left(), - &function, - &arg_buffer, - ); + let gas_left = self.blockchain().get_gas_left(); + + self.tx() + .to(&to) + .gas(gas_left) + .raw_call(function) + .arguments_raw(arg_buffer) + .single_esdt(&token_identifier, nonce, &amount) + .transfer_execute(); } // Semi-Fungible @@ -192,9 +192,8 @@ pub trait LocalEsdtAndEsdtNft { can_add_special_roles: true, }, ) - .async_call() .with_callback(self.callbacks().nft_issue_callback(&caller)) - .call_and_exit() + .async_call_and_exit() } // common @@ -209,9 +208,8 @@ pub trait LocalEsdtAndEsdtNft { self.send() .esdt_system_sc_proxy() .set_special_roles(&address, &token_identifier, roles.into_iter()) - .async_call() .with_callback(self.callbacks().change_roles_callback()) - .call_and_exit() + .async_call_and_exit() } #[endpoint(unsetLocalRoles)] @@ -224,9 +222,8 @@ pub trait LocalEsdtAndEsdtNft { self.send() .esdt_system_sc_proxy() .unset_special_roles(&address, &token_identifier, roles.into_iter()) - .async_call() .with_callback(self.callbacks().change_roles_callback()) - .call_and_exit() + .async_call_and_exit() } #[endpoint(controlChanges)] @@ -240,8 +237,7 @@ pub trait LocalEsdtAndEsdtNft { self.send() .esdt_system_sc_proxy() .control_changes(&token, &property_arguments) - .async_call() - .call_and_exit(); + .async_call_and_exit(); } // views @@ -287,7 +283,7 @@ pub trait LocalEsdtAndEsdtNft { ManagedAsyncCallResult::Err(message) => { // return issue cost to the caller if token_identifier.is_egld() && returned_tokens > 0 { - self.send().direct_egld(caller, &returned_tokens); + self.tx().to(caller).egld(&returned_tokens).transfer(); } self.last_error_message().set(&message.err_msg); @@ -311,7 +307,7 @@ pub trait LocalEsdtAndEsdtNft { let (token_identifier, returned_tokens) = self.call_value().egld_or_single_fungible_esdt(); if token_identifier.is_egld() && returned_tokens > 0 { - self.send().direct_egld(caller, &returned_tokens); + self.tx().to(caller).egld(&returned_tokens).transfer(); } self.last_error_message().set(&message.err_msg); diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/wasm/Cargo.lock b/contracts/feature-tests/composability/local-esdt-and-nft/wasm/Cargo.lock index acc6558d24..50003012b7 100755 --- a/contracts/feature-tests/composability/local-esdt-and-nft/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/local-esdt-and-nft/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/wasm/Cargo.toml b/contracts/feature-tests/composability/local-esdt-and-nft/wasm/Cargo.toml index 8808b6c488..581b5e7680 100644 --- a/contracts/feature-tests/composability/local-esdt-and-nft/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/local-esdt-and-nft/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.local-esdt-and-nft] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/local-esdt-and-nft/wasm/src/lib.rs b/contracts/feature-tests/composability/local-esdt-and-nft/wasm/src/lib.rs index 5bd9fa54c0..7fc777de65 100644 --- a/contracts/feature-tests/composability/local-esdt-and-nft/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/local-esdt-and-nft/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 20 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/promises-features/Cargo.toml b/contracts/feature-tests/composability/promises-features/Cargo.toml index c2ffef9059..f0685ebcf5 100644 --- a/contracts/feature-tests/composability/promises-features/Cargo.toml +++ b/contracts/feature-tests/composability/promises-features/Cargo.toml @@ -8,10 +8,7 @@ publish = false [lib] path = "src/promises_main.rs" -[dependencies.vault] -path = "../vault" - [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" diff --git a/contracts/feature-tests/composability/promises-features/meta/Cargo.toml b/contracts/feature-tests/composability/promises-features/meta/Cargo.toml index be4f70e057..9b10023a5e 100644 --- a/contracts/feature-tests/composability/promises-features/meta/Cargo.toml +++ b/contracts/feature-tests/composability/promises-features/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.promises-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/promises-features/meta/src/main.rs b/contracts/feature-tests/composability/promises-features/meta/src/main.rs index 9ea31adb68..7327395421 100644 --- a/contracts/feature-tests/composability/promises-features/meta/src/main.rs +++ b/contracts/feature-tests/composability/promises-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/promises-features/sc-config.toml b/contracts/feature-tests/composability/promises-features/sc-config.toml index 79ef7a04a8..d3be3200f4 100644 --- a/contracts/feature-tests/composability/promises-features/sc-config.toml +++ b/contracts/feature-tests/composability/promises-features/sc-config.toml @@ -5,3 +5,6 @@ main = "promises-features" name = "promises-features" add-unlabelled = true ei = "1.3" # the whole point of this config is to explicitly specify that this contract needs EI 1.3/VM 1.5 + +[[proxy]] +path = "src/promises_feature_proxy.rs" diff --git a/contracts/feature-tests/composability/promises-features/src/call_promise_direct.rs b/contracts/feature-tests/composability/promises-features/src/fwd_call_promise_direct.rs similarity index 66% rename from contracts/feature-tests/composability/promises-features/src/call_promise_direct.rs rename to contracts/feature-tests/composability/promises-features/src/fwd_call_promise_direct.rs index 8ce47a10c3..78635d26b6 100644 --- a/contracts/feature-tests/composability/promises-features/src/call_promise_direct.rs +++ b/contracts/feature-tests/composability/promises-features/src/fwd_call_promise_direct.rs @@ -3,9 +3,6 @@ multiversx_sc::imports!(); /// Test contract for investigating the new async call framework. #[multiversx_sc::module] pub trait CallPromisesDirectModule { - #[proxy] - fn vault_proxy(&self) -> vault::Proxy; - #[endpoint] #[payable("*")] fn promise_raw_single_token( @@ -17,14 +14,14 @@ pub trait CallPromisesDirectModule { args: MultiValueEncoded, ) { let payment = self.call_value().egld_or_single_esdt(); - self.send() - .contract_call::<()>(to, endpoint_name) - .with_egld_or_single_esdt_transfer(payment) - .with_raw_arguments(args.to_arg_buffer()) - .with_gas_limit(gas_limit) - .async_call_promise() - .with_extra_gas_for_callback(extra_gas_for_callback) - .with_callback(self.callbacks().the_one_callback(1001, 1002u32.into())) + self.tx() + .to(&to) + .raw_call(endpoint_name) + .payment(payment) + .arguments_raw(args.to_arg_buffer()) + .gas(gas_limit) + .callback(self.callbacks().the_one_callback(1001, 1002u32.into())) + .gas_for_callback(extra_gas_for_callback) .register_promise(); } @@ -43,13 +40,13 @@ pub trait CallPromisesDirectModule { let gas_limit = (self.blockchain().get_gas_left() - extra_gas_for_callback) * 9 / 10; - self.send() - .contract_call::<()>(to, endpoint_name) - .with_multi_token_transfer(token_payments_vec) - .with_gas_limit(gas_limit) - .async_call_promise() - .with_extra_gas_for_callback(extra_gas_for_callback) - .with_callback(self.callbacks().the_one_callback(2001, 2002u32.into())) + self.tx() + .to(&to) + .raw_call(endpoint_name) + .payment(EgldOrMultiEsdtPayment::MultiEsdt(token_payments_vec)) + .gas(gas_limit) + .callback(self.callbacks().the_one_callback(2001, 2002u32.into())) + .gas_for_callback(extra_gas_for_callback) .register_promise(); } diff --git a/contracts/feature-tests/composability/promises-features/src/call_promises.rs b/contracts/feature-tests/composability/promises-features/src/fwd_call_promises.rs similarity index 66% rename from contracts/feature-tests/composability/promises-features/src/call_promises.rs rename to contracts/feature-tests/composability/promises-features/src/fwd_call_promises.rs index 616d8c5cb0..92a2c8e0e1 100644 --- a/contracts/feature-tests/composability/promises-features/src/call_promises.rs +++ b/contracts/feature-tests/composability/promises-features/src/fwd_call_promises.rs @@ -1,24 +1,25 @@ multiversx_sc::imports!(); -use crate::common::{self, CallbackData}; +use crate::{ + common::{self, CallbackData}, + vault_proxy, +}; #[multiversx_sc::module] pub trait CallPromisesModule: common::CommonModule { - #[proxy] - fn vault_proxy(&self) -> vault::Proxy; - #[endpoint] #[payable("*")] fn forward_promise_accept_funds(&self, to: ManagedAddress) { let payment = self.call_value().egld_or_single_esdt(); let gas_limit = self.blockchain().get_gas_left() / 2; - self.vault_proxy() - .contract(to) + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) .accept_funds() - .with_egld_or_single_esdt_transfer(payment) - .with_gas_limit(gas_limit) - .async_call_promise() - .register_promise() + .gas(gas_limit) + .payment(payment) + .register_promise(); } #[endpoint] @@ -30,14 +31,15 @@ pub trait CallPromisesModule: common::CommonModule { amount: BigUint, ) { let gas_limit = self.blockchain().get_gas_left() - 20_000_000; - self.vault_proxy() - .contract(to) + + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) .retrieve_funds(token, token_nonce, amount) - .with_gas_limit(gas_limit) - .async_call_promise() - .with_callback(self.callbacks().retrieve_funds_callback()) - .with_extra_gas_for_callback(10_000_000) - .register_promise() + .gas(gas_limit) + .callback(self.callbacks().retrieve_funds_callback()) + .gas_for_callback(10_000_000) + .register_promise(); } #[promises_callback] diff --git a/contracts/feature-tests/composability/promises-features/src/call_promises_bt.rs b/contracts/feature-tests/composability/promises-features/src/fwd_call_promises_bt.rs similarity index 82% rename from contracts/feature-tests/composability/promises-features/src/call_promises_bt.rs rename to contracts/feature-tests/composability/promises-features/src/fwd_call_promises_bt.rs index e1e2188852..2634e2c5ac 100644 --- a/contracts/feature-tests/composability/promises-features/src/call_promises_bt.rs +++ b/contracts/feature-tests/composability/promises-features/src/fwd_call_promises_bt.rs @@ -1,13 +1,12 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -use crate::common::{self, CallbackData}; - +use crate::{ + common::{self, CallbackData}, + vault_proxy, +}; #[multiversx_sc::module] pub trait CallPromisesBackTransfersModule: common::CommonModule { - #[proxy] - fn vault_proxy(&self) -> vault::Proxy; - #[endpoint] fn forward_promise_retrieve_funds_back_transfers( &self, @@ -17,14 +16,14 @@ pub trait CallPromisesBackTransfersModule: common::CommonModule { amount: BigUint, ) { let gas_limit = self.blockchain().get_gas_left() - 20_000_000; - self.vault_proxy() - .contract(to) + self.tx() + .to(&to) + .typed(vault_proxy::VaultProxy) .retrieve_funds(token, token_nonce, amount) - .with_gas_limit(gas_limit) - .async_call_promise() - .with_callback(self.callbacks().retrieve_funds_back_transfers_callback()) - .with_extra_gas_for_callback(10_000_000) - .register_promise() + .gas(gas_limit) + .callback(self.callbacks().retrieve_funds_back_transfers_callback()) + .gas_for_callback(10_000_000) + .register_promise(); } #[promises_callback] diff --git a/contracts/feature-tests/composability/promises-features/src/call_sync_bt.rs b/contracts/feature-tests/composability/promises-features/src/fwd_call_sync_bt.rs similarity index 77% rename from contracts/feature-tests/composability/promises-features/src/call_sync_bt.rs rename to contracts/feature-tests/composability/promises-features/src/fwd_call_sync_bt.rs index d3cc048ccc..d31ac022dc 100644 --- a/contracts/feature-tests/composability/promises-features/src/call_sync_bt.rs +++ b/contracts/feature-tests/composability/promises-features/src/fwd_call_sync_bt.rs @@ -1,11 +1,10 @@ +use crate::vault_proxy; + multiversx_sc::imports!(); /// Not directly related to promises, but this contract already has the setup for VM 1.5. #[multiversx_sc::module] pub trait BackTransfersFeatureModule { - #[proxy] - fn vault_proxy(&self) -> vault::Proxy; - #[endpoint] fn forward_sync_retrieve_funds_bt( &self, @@ -14,11 +13,13 @@ pub trait BackTransfersFeatureModule { token_nonce: u64, amount: BigUint, ) { - let ((), back_transfers) = self - .vault_proxy() - .contract(to) + let back_transfers = self + .tx() + .to(&to) + .typed(vault_proxy::VaultProxy) .retrieve_funds(token, token_nonce, amount) - .execute_on_dest_context_with_back_transfers::<()>(); + .returns(ReturnsBackTransfers) + .sync_call(); require!( back_transfers.esdt_payments.len() == 1 || back_transfers.total_egld_amount != 0, @@ -39,11 +40,13 @@ pub trait BackTransfersFeatureModule { token_nonce: u64, amount: BigUint, ) { - let ((), back_transfers) = self - .vault_proxy() - .contract(to.clone()) + let back_transfers = self + .tx() + .to(&to) + .typed(vault_proxy::VaultProxy) .retrieve_funds(token.clone(), token_nonce, amount.clone()) - .execute_on_dest_context_with_back_transfers::<()>(); + .returns(ReturnsBackTransfers) + .sync_call(); require!( back_transfers.esdt_payments.len() == 1 || back_transfers.total_egld_amount != 0, @@ -55,11 +58,13 @@ pub trait BackTransfersFeatureModule { &back_transfers.esdt_payments.into_multi_value(), ); - let ((), back_transfers) = self - .vault_proxy() - .contract(to) + let back_transfers = self + .tx() + .to(&to) + .typed(vault_proxy::VaultProxy) .retrieve_funds(token, token_nonce, amount) - .execute_on_dest_context_with_back_transfers::<()>(); + .returns(ReturnsBackTransfers) + .sync_call(); require!( back_transfers.esdt_payments.len() == 1 || back_transfers.total_egld_amount != 0, diff --git a/contracts/feature-tests/composability/promises-features/src/promises_feature_proxy.rs b/contracts/feature-tests/composability/promises-features/src/promises_feature_proxy.rs new file mode 100644 index 0000000000..d5fb14bf19 --- /dev/null +++ b/contracts/feature-tests/composability/promises-features/src/promises_feature_proxy.rs @@ -0,0 +1,254 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct PromisesFeaturesProxy; + +impl TxProxyTrait for PromisesFeaturesProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = PromisesFeaturesProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + PromisesFeaturesProxyMethods { wrapped_tx: tx } + } +} + +pub struct PromisesFeaturesProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl PromisesFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl PromisesFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn callback_data( + self, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("callback_data") + .original_result() + } + + pub fn callback_data_at_index< + Arg0: ProxyArg, + >( + self, + index: Arg0, + ) -> TxTypedCall, EgldOrEsdtTokenIdentifier, u64, BigUint, MultiValueManagedVec>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("callback_data_at_index") + .argument(&index) + .original_result() + } + + pub fn clear_callback_data( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("clear_callback_data") + .original_result() + } + + pub fn forward_promise_accept_funds< + Arg0: ProxyArg>, + >( + self, + to: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forward_promise_accept_funds") + .argument(&to) + .original_result() + } + + pub fn forward_promise_retrieve_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + token_nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_promise_retrieve_funds") + .argument(&to) + .argument(&token) + .argument(&token_nonce) + .argument(&amount) + .original_result() + } + + pub fn promise_raw_single_token< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg, + Arg4: ProxyArg>>, + >( + self, + to: Arg0, + endpoint_name: Arg1, + gas_limit: Arg2, + extra_gas_for_callback: Arg3, + args: Arg4, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("promise_raw_single_token") + .argument(&to) + .argument(&endpoint_name) + .argument(&gas_limit) + .argument(&extra_gas_for_callback) + .argument(&args) + .original_result() + } + + pub fn promise_raw_multi_transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>>, + >( + self, + to: Arg0, + endpoint_name: Arg1, + extra_gas_for_callback: Arg2, + token_payment_args: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("promise_raw_multi_transfer") + .argument(&to) + .argument(&endpoint_name) + .argument(&extra_gas_for_callback) + .argument(&token_payment_args) + .original_result() + } + + pub fn forward_sync_retrieve_funds_bt< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + token_nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_sync_retrieve_funds_bt") + .argument(&to) + .argument(&token) + .argument(&token_nonce) + .argument(&amount) + .original_result() + } + + pub fn forward_sync_retrieve_funds_bt_twice< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + token_nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_sync_retrieve_funds_bt_twice") + .argument(&to) + .argument(&token) + .argument(&token_nonce) + .argument(&amount) + .original_result() + } + + pub fn forward_promise_retrieve_funds_back_transfers< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg, + Arg3: ProxyArg>, + >( + self, + to: Arg0, + token: Arg1, + token_nonce: Arg2, + amount: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("forward_promise_retrieve_funds_back_transfers") + .argument(&to) + .argument(&token) + .argument(&token_nonce) + .argument(&amount) + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode)] +pub struct CallbackData +where + Api: ManagedTypeApi, +{ + pub callback_name: ManagedBuffer, + pub token_identifier: EgldOrEsdtTokenIdentifier, + pub token_nonce: u64, + pub token_amount: BigUint, + pub args: ManagedVec>, +} diff --git a/contracts/feature-tests/composability/promises-features/src/promises_main.rs b/contracts/feature-tests/composability/promises-features/src/promises_main.rs index 11eb5d3935..2387879943 100644 --- a/contracts/feature-tests/composability/promises-features/src/promises_main.rs +++ b/contracts/feature-tests/composability/promises-features/src/promises_main.rs @@ -1,11 +1,13 @@ #![no_std] #![allow(clippy::type_complexity)] -mod call_promise_direct; -mod call_promises; -mod call_promises_bt; -pub mod call_sync_bt; mod common; +mod fwd_call_promise_direct; +mod fwd_call_promises; +mod fwd_call_promises_bt; +pub mod fwd_call_sync_bt; +pub mod promises_feature_proxy; +pub mod vault_proxy; multiversx_sc::imports!(); @@ -13,10 +15,10 @@ multiversx_sc::imports!(); #[multiversx_sc::contract] pub trait PromisesFeatures: common::CommonModule - + call_promises::CallPromisesModule - + call_promise_direct::CallPromisesDirectModule - + call_sync_bt::BackTransfersFeatureModule - + call_promises_bt::CallPromisesBackTransfersModule + + fwd_call_promises::CallPromisesModule + + fwd_call_promise_direct::CallPromisesDirectModule + + fwd_call_sync_bt::BackTransfersFeatureModule + + fwd_call_promises_bt::CallPromisesBackTransfersModule { #[init] fn init(&self) {} diff --git a/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs b/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs new file mode 100644 index 0000000000..24e6f12e69 --- /dev/null +++ b/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs @@ -0,0 +1,273 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct VaultProxy; + +impl TxProxyTrait for VaultProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = VaultProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + VaultProxyMethods { wrapped_tx: tx } + } +} + +pub struct VaultProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>>, + >( + self, + opt_arg_to_echo: Arg0, + ) -> TxTypedDeploy>> { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&opt_arg_to_echo) + .original_result() + } +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade< + Arg0: ProxyArg>>, + >( + self, + opt_arg_to_echo: Arg0, + ) -> TxTypedUpgrade>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .argument(&opt_arg_to_echo) + .original_result() + } +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn echo_arguments< + Arg0: ProxyArg>>, + >( + self, + args: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_arguments") + .argument(&args) + .original_result() + } + + pub fn echo_arguments_without_storage< + Arg0: ProxyArg>>, + >( + self, + args: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_arguments_without_storage") + .argument(&args) + .original_result() + } + + pub fn echo_caller( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_caller") + .original_result() + } + + pub fn accept_funds( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds") + .original_result() + } + + pub fn accept_funds_echo_payment( + self, + ) -> TxTypedCall, MultiValueEncoded>>> { + self.wrapped_tx + .raw_call("accept_funds_echo_payment") + .original_result() + } + + pub fn accept_funds_single_esdt_transfer( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds_single_esdt_transfer") + .original_result() + } + + pub fn reject_funds( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("reject_funds") + .original_result() + } + + pub fn retrieve_funds_with_transfer_exec< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + token: Arg0, + amount: Arg1, + opt_receive_func: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("retrieve_funds_with_transfer_exec") + .argument(&token) + .argument(&amount) + .argument(&opt_receive_func) + .original_result() + } + + pub fn retrieve_funds_promises< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + back_transfers: Arg0, + back_transfer_value: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("retrieve_funds_promises") + .argument(&back_transfers) + .argument(&back_transfer_value) + .original_result() + } + + pub fn retrieve_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + token: Arg0, + nonce: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("retrieve_funds") + .argument(&token) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn retrieve_multi_funds_async< + Arg0: ProxyArg, u64, BigUint>>>, + >( + self, + token_payments: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("retrieve_multi_funds_async") + .argument(&token_payments) + .original_result() + } + + pub fn burn_and_create_retrieve_async( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("burn_and_create_retrieve_async") + .original_result() + } + + pub fn get_owner_address( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_owner_address") + .original_result() + } + + /// We already leave a trace of the calls using the event logs; + /// this additional counter has the role of showing that storage also gets saved correctly. + pub fn call_counts< + Arg0: ProxyArg>, + >( + self, + endpoint: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("call_counts") + .argument(&endpoint) + .original_result() + } + + pub fn num_called_retrieve_funds_promises( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("num_called_retrieve_funds_promises") + .original_result() + } + + pub fn num_async_calls_sent_from_child( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("num_async_calls_sent_from_child") + .original_result() + } +} diff --git a/contracts/feature-tests/composability/promises-features/wasm/Cargo.lock b/contracts/feature-tests/composability/promises-features/wasm/Cargo.lock index eb6e4092ed..091176489b 100644 --- a/contracts/feature-tests/composability/promises-features/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/promises-features/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,18 +98,18 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -117,7 +119,6 @@ name = "promises-features" version = "0.0.0" dependencies = [ "multiversx-sc", - "vault", ] [[package]] @@ -130,9 +131,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -149,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -171,8 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "vault" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/promises-features/wasm/Cargo.toml b/contracts/feature-tests/composability/promises-features/wasm/Cargo.toml index ae07ea0f64..39c93eb948 100644 --- a/contracts/feature-tests/composability/promises-features/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/promises-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.promises-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/promises-features/wasm/src/lib.rs b/contracts/feature-tests/composability/promises-features/wasm/src/lib.rs index e9b079caf6..1dc649df0d 100644 --- a/contracts/feature-tests/composability/promises-features/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/promises-features/wasm/src/lib.rs @@ -11,8 +11,6 @@ // Total number of exported functions: 15 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/proxy-test-first/Cargo.toml b/contracts/feature-tests/composability/proxy-test-first/Cargo.toml index dd0e5e3190..7668df8c3a 100644 --- a/contracts/feature-tests/composability/proxy-test-first/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-first/Cargo.toml @@ -12,10 +12,10 @@ path = "src/proxy-test-first.rs" hex-literal = "0.4.1" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/proxy-test-first/meta/Cargo.toml b/contracts/feature-tests/composability/proxy-test-first/meta/Cargo.toml index 5ba64dbc91..c857d94013 100644 --- a/contracts/feature-tests/composability/proxy-test-first/meta/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-first/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.proxy-test-first] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/proxy-test-first/meta/src/main.rs b/contracts/feature-tests/composability/proxy-test-first/meta/src/main.rs index c3a70f306e..cdf00375c2 100644 --- a/contracts/feature-tests/composability/proxy-test-first/meta/src/main.rs +++ b/contracts/feature-tests/composability/proxy-test-first/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/proxy-test-first/src/message_me_proxy.rs b/contracts/feature-tests/composability/proxy-test-first/src/message_me_proxy.rs new file mode 100644 index 0000000000..fbe4ebf1a8 --- /dev/null +++ b/contracts/feature-tests/composability/proxy-test-first/src/message_me_proxy.rs @@ -0,0 +1,106 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct MessageMeProxy; + +impl TxProxyTrait for MessageMeProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = MessageMeProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + MessageMeProxyMethods { wrapped_tx: tx } + } +} + +pub struct MessageMeProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl MessageMeProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg, + >( + self, + init_arg: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .raw_deploy() + .argument(&init_arg) + .original_result() + } +} + +#[rustfmt::skip] +impl MessageMeProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade( + self, + ) -> TxTypedUpgrade { + self.wrapped_tx + .raw_upgrade() + .original_result() + } +} + +#[rustfmt::skip] +impl MessageMeProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn message_me< + Arg0: ProxyArg, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + >( + self, + arg1: Arg0, + arg2: Arg1, + arg3: Arg2, + arg4: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("messageMe") + .argument(&arg1) + .argument(&arg2) + .argument(&arg3) + .argument(&arg4) + .original_result() + } +} diff --git a/contracts/feature-tests/composability/proxy-test-first/src/pay_me_proxy.rs b/contracts/feature-tests/composability/proxy-test-first/src/pay_me_proxy.rs new file mode 100644 index 0000000000..38f620a84c --- /dev/null +++ b/contracts/feature-tests/composability/proxy-test-first/src/pay_me_proxy.rs @@ -0,0 +1,105 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct PayMeProxy; + +impl TxProxyTrait for PayMeProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = PayMeProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + PayMeProxyMethods { wrapped_tx: tx } + } +} + +pub struct PayMeProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl PayMeProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl PayMeProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade( + self, + ) -> TxTypedUpgrade { + self.wrapped_tx + .raw_upgrade() + .original_result() + } +} + +#[rustfmt::skip] +impl PayMeProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn pay_me< + Arg0: ProxyArg, + >( + self, + arg1: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("payMe") + .argument(&arg1) + .original_result() + } + + pub fn pay_me_with_result< + Arg0: ProxyArg, + >( + self, + arg1: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("payMeWithResult") + .argument(&arg1) + .original_result() + } +} diff --git a/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs b/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs index d84f36e5fa..eacc3064d0 100644 --- a/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs +++ b/contracts/feature-tests/composability/proxy-test-first/src/proxy-test-first.rs @@ -4,46 +4,14 @@ multiversx_sc::imports!(); use hex_literal::hex; +pub mod message_me_proxy; +pub mod pay_me_proxy; + static HARDCODED_ADDRESS: [u8; 32] = hex!("fefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefe"); -mod pay_me_proxy { - multiversx_sc::imports!(); - - #[multiversx_sc::proxy] - pub trait PayMe { - #[payable("EGLD")] - #[endpoint(payMe)] - fn pay_me(&self, arg1: i64); - - #[payable("EGLD")] - #[endpoint(payMeWithResult)] - fn pay_me_with_result(&self, arg1: i64); - } -} - -mod message_me_proxy { - multiversx_sc::imports!(); - - #[multiversx_sc::proxy] - pub trait MessageMe { - #[init] - #[payable("EGLD")] - fn init(&self, init_arg: i32) -> i32; - - #[endpoint(messageMe)] - fn message_me(&self, arg1: i64, arg2: &BigUint, arg3: Vec, arg4: &ManagedAddress); - } -} - #[multiversx_sc::contract] pub trait ProxyTestFirst { - #[proxy] - fn pay_me_proxy(&self) -> pay_me_proxy::Proxy; - - #[proxy] - fn message_me_proxy(&self) -> message_me_proxy::Proxy; - #[storage_get("other_contract")] fn get_other_contract(&self) -> ManagedAddress; @@ -62,11 +30,18 @@ pub trait ProxyTestFirst { #[endpoint(deploySecondContract)] fn deploy_second_contract(&self, code: ManagedBuffer) -> i32 { let payment = self.call_value().egld_value(); + let (address, init_result) = self - .message_me_proxy() + .tx() + .typed(message_me_proxy::MessageMeProxy) .init(123) - .with_egld_transfer(payment.clone_value()) - .deploy_contract::(&code, CodeMetadata::UPGRADEABLE); + .code(code) + .code_metadata(CodeMetadata::UPGRADEABLE) + .returns(ReturnsNewManagedAddress) + .returns(ReturnsResult) + .egld(payment) + .sync_call(); + self.set_other_contract(&address); init_result + 1 } @@ -77,11 +52,15 @@ pub trait ProxyTestFirst { let payment = self.call_value().egld_value(); let other_contract = self.get_other_contract(); - self.message_me_proxy() - .contract(other_contract) - .init(456) // TODO: upgrade proxy - .with_egld_transfer(payment.clone_value()) - .upgrade_contract(&code, CodeMetadata::UPGRADEABLE); + self.tx() + .to(other_contract) + .typed(pay_me_proxy::PayMeProxy) + .upgrade() + .argument(&456) + .egld(payment) + .code(code) + .code_metadata(CodeMetadata::UPGRADEABLE) + .upgrade_async_call_and_exit(); } #[payable("EGLD")] @@ -89,12 +68,12 @@ pub trait ProxyTestFirst { fn forward_to_other_contract(&self) { let payment = self.call_value().egld_value(); let other_contract = self.get_other_contract(); - self.pay_me_proxy() - .contract(other_contract) + self.tx() + .to(&other_contract) + .typed(pay_me_proxy::PayMeProxy) .pay_me(0x56) - .with_egld_transfer(payment.clone_value()) - .async_call() - .call_and_exit() + .egld(payment) + .async_call_and_exit(); } #[payable("EGLD")] @@ -102,44 +81,44 @@ pub trait ProxyTestFirst { fn forward_to_other_contract_with_callback(&self) { let payment = self.call_value().egld_value(); let other_contract = self.get_other_contract(); - self.pay_me_proxy() - .contract(other_contract) + self.tx() + .to(&other_contract) + .typed(pay_me_proxy::PayMeProxy) .pay_me_with_result(0x56) - .with_egld_transfer(payment.clone_value()) - .async_call() - .with_callback(self.callbacks().pay_callback()) - .call_and_exit() + .egld(payment) + .callback(self.callbacks().pay_callback()) + .async_call_and_exit(); } #[endpoint(messageOtherContract)] fn message_other_contract(&self) { let other_contract = self.get_other_contract(); - self.message_me_proxy() - .contract(other_contract) + self.tx() + .to(&other_contract) + .typed(message_me_proxy::MessageMeProxy) .message_me( 0x01, &BigUint::from(2u32), [3u8; 3].to_vec(), &ManagedAddress::from(&HARDCODED_ADDRESS), ) - .async_call() - .call_and_exit() + .async_call_and_exit() } #[endpoint(messageOtherContractWithCallback)] fn message_other_contract_with_callback(&self) { let other_contract = self.get_other_contract(); - self.message_me_proxy() - .contract(other_contract) + self.tx() + .to(&other_contract) + .typed(message_me_proxy::MessageMeProxy) .message_me( 0x01, &BigUint::from(2u32), [3u8; 3].to_vec(), &ManagedAddress::from(&HARDCODED_ADDRESS), ) - .async_call() - .with_callback(self.callbacks().message_callback()) - .call_and_exit() + .callback(self.callbacks().message_callback()) + .async_call_and_exit() } #[callback(payCallback)] // although uncommon, custom callback names are possible diff --git a/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.lock b/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.lock index 4aff4f7065..ccfd61e72c 100755 --- a/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,18 +98,18 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -130,9 +132,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -149,15 +151,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -169,3 +171,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.toml b/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.toml index 1c4e66daad..fe0ad4ff4b 100644 --- a/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.proxy-test-first] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/proxy-test-first/wasm/src/lib.rs b/contracts/feature-tests/composability/proxy-test-first/wasm/src/lib.rs index f9ce7c6833..9f5f0bb847 100644 --- a/contracts/feature-tests/composability/proxy-test-first/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/proxy-test-first/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 8 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/proxy-test-second/Cargo.toml b/contracts/feature-tests/composability/proxy-test-second/Cargo.toml index 6aacf4c17c..1170efad40 100644 --- a/contracts/feature-tests/composability/proxy-test-second/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-second/Cargo.toml @@ -9,10 +9,10 @@ publish = false path = "src/proxy-test-second.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/proxy-test-second/meta/Cargo.toml b/contracts/feature-tests/composability/proxy-test-second/meta/Cargo.toml index 8ad3614823..7e67512271 100644 --- a/contracts/feature-tests/composability/proxy-test-second/meta/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-second/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.proxy-test-second] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/proxy-test-second/meta/src/main.rs b/contracts/feature-tests/composability/proxy-test-second/meta/src/main.rs index 6496c9a364..7b514c9bca 100644 --- a/contracts/feature-tests/composability/proxy-test-second/meta/src/main.rs +++ b/contracts/feature-tests/composability/proxy-test-second/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.lock b/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.lock index 3420a7b3f6..02a4ae8865 100755 --- a/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,18 +98,18 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -129,9 +131,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.toml b/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.toml index 4f0ac22bbc..e5ca8d1b5e 100644 --- a/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.proxy-test-second] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/proxy-test-second/wasm/src/lib.rs b/contracts/feature-tests/composability/proxy-test-second/wasm/src/lib.rs index e10ed79624..b2e0cd610d 100644 --- a/contracts/feature-tests/composability/proxy-test-second/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/proxy-test-second/wasm/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 4 +// Upgrade: 1 +// Endpoints: 3 // Async Callback (empty): 1 // Total number of exported functions: 6 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/recursive-caller/Cargo.toml b/contracts/feature-tests/composability/recursive-caller/Cargo.toml index 3d706c42a4..08adf23128 100644 --- a/contracts/feature-tests/composability/recursive-caller/Cargo.toml +++ b/contracts/feature-tests/composability/recursive-caller/Cargo.toml @@ -12,9 +12,9 @@ path = "src/recursive_caller.rs" path = "../vault" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/recursive-caller/meta/Cargo.toml b/contracts/feature-tests/composability/recursive-caller/meta/Cargo.toml index 3439b25847..d1923f071c 100644 --- a/contracts/feature-tests/composability/recursive-caller/meta/Cargo.toml +++ b/contracts/feature-tests/composability/recursive-caller/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.recursive-caller] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/recursive-caller/meta/src/main.rs b/contracts/feature-tests/composability/recursive-caller/meta/src/main.rs index f5814c6ec7..5161513ec6 100644 --- a/contracts/feature-tests/composability/recursive-caller/meta/src/main.rs +++ b/contracts/feature-tests/composability/recursive-caller/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/recursive-caller/sc-config.toml b/contracts/feature-tests/composability/recursive-caller/sc-config.toml new file mode 100644 index 0000000000..48d2e6bb8f --- /dev/null +++ b/contracts/feature-tests/composability/recursive-caller/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "src/self_proxy.rs" diff --git a/contracts/feature-tests/composability/recursive-caller/src/recursive_caller.rs b/contracts/feature-tests/composability/recursive-caller/src/recursive_caller.rs index 617f29e901..d75b516926 100644 --- a/contracts/feature-tests/composability/recursive-caller/src/recursive_caller.rs +++ b/contracts/feature-tests/composability/recursive-caller/src/recursive_caller.rs @@ -2,15 +2,12 @@ multiversx_sc::imports!(); +pub mod self_proxy; +pub mod vault_proxy; + /// Test contract for investigating async calls. #[multiversx_sc::contract] pub trait RecursiveCaller { - #[proxy] - fn vault_proxy(&self) -> vault::Proxy; - - #[proxy] - fn self_proxy(&self) -> self::Proxy; - #[init] fn init(&self) {} @@ -24,18 +21,18 @@ pub trait RecursiveCaller { ) { self.recursive_send_funds_event(to, token_identifier, amount, counter); - self.vault_proxy() - .contract(to.clone()) + self.tx() + .to(to) + .typed(vault_proxy::VaultProxy) .accept_funds() - .with_egld_or_single_esdt_transfer((token_identifier.clone(), 0, amount.clone())) - .async_call() - .with_callback(self.callbacks().recursive_send_funds_callback( + .egld_or_single_esdt(token_identifier, 0, amount) + .callback(self.callbacks().recursive_send_funds_callback( to, token_identifier, amount, counter, )) - .call_and_exit() + .async_call_and_exit(); } #[callback] @@ -49,11 +46,12 @@ pub trait RecursiveCaller { self.recursive_send_funds_callback_event(to, token_identifier, amount, counter); if counter > 1 { - self.self_proxy() - .contract(self.blockchain().get_sc_address()) + let self_address = self.blockchain().get_sc_address(); + self.tx() + .to(&self_address) + .typed(self_proxy::RecursiveCallerProxy) .recursive_send_funds(to, token_identifier, amount, counter - 1) - .async_call() - .call_and_exit() + .async_call_and_exit() } } diff --git a/contracts/feature-tests/composability/recursive-caller/src/self_proxy.rs b/contracts/feature-tests/composability/recursive-caller/src/self_proxy.rs new file mode 100644 index 0000000000..6e55b345df --- /dev/null +++ b/contracts/feature-tests/composability/recursive-caller/src/self_proxy.rs @@ -0,0 +1,86 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct RecursiveCallerProxy; + +impl TxProxyTrait for RecursiveCallerProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = RecursiveCallerProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + RecursiveCallerProxyMethods { wrapped_tx: tx } + } +} + +pub struct RecursiveCallerProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl RecursiveCallerProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl RecursiveCallerProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn recursive_send_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg, + >( + self, + to: Arg0, + token_identifier: Arg1, + amount: Arg2, + counter: Arg3, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("recursive_send_funds") + .argument(&to) + .argument(&token_identifier) + .argument(&amount) + .argument(&counter) + .original_result() + } +} diff --git a/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs b/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs new file mode 100644 index 0000000000..24e6f12e69 --- /dev/null +++ b/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs @@ -0,0 +1,273 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct VaultProxy; + +impl TxProxyTrait for VaultProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = VaultProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + VaultProxyMethods { wrapped_tx: tx } + } +} + +pub struct VaultProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>>, + >( + self, + opt_arg_to_echo: Arg0, + ) -> TxTypedDeploy>> { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&opt_arg_to_echo) + .original_result() + } +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade< + Arg0: ProxyArg>>, + >( + self, + opt_arg_to_echo: Arg0, + ) -> TxTypedUpgrade>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .argument(&opt_arg_to_echo) + .original_result() + } +} + +#[rustfmt::skip] +impl VaultProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn echo_arguments< + Arg0: ProxyArg>>, + >( + self, + args: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_arguments") + .argument(&args) + .original_result() + } + + pub fn echo_arguments_without_storage< + Arg0: ProxyArg>>, + >( + self, + args: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_arguments_without_storage") + .argument(&args) + .original_result() + } + + pub fn echo_caller( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_caller") + .original_result() + } + + pub fn accept_funds( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds") + .original_result() + } + + pub fn accept_funds_echo_payment( + self, + ) -> TxTypedCall, MultiValueEncoded>>> { + self.wrapped_tx + .raw_call("accept_funds_echo_payment") + .original_result() + } + + pub fn accept_funds_single_esdt_transfer( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept_funds_single_esdt_transfer") + .original_result() + } + + pub fn reject_funds( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("reject_funds") + .original_result() + } + + pub fn retrieve_funds_with_transfer_exec< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + token: Arg0, + amount: Arg1, + opt_receive_func: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("retrieve_funds_with_transfer_exec") + .argument(&token) + .argument(&amount) + .argument(&opt_receive_func) + .original_result() + } + + pub fn retrieve_funds_promises< + Arg0: ProxyArg>, + Arg1: ProxyArg>>, + >( + self, + back_transfers: Arg0, + back_transfer_value: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("retrieve_funds_promises") + .argument(&back_transfers) + .argument(&back_transfer_value) + .original_result() + } + + pub fn retrieve_funds< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + token: Arg0, + nonce: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("retrieve_funds") + .argument(&token) + .argument(&nonce) + .argument(&amount) + .original_result() + } + + pub fn retrieve_multi_funds_async< + Arg0: ProxyArg, u64, BigUint>>>, + >( + self, + token_payments: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("retrieve_multi_funds_async") + .argument(&token_payments) + .original_result() + } + + pub fn burn_and_create_retrieve_async( + self, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("burn_and_create_retrieve_async") + .original_result() + } + + pub fn get_owner_address( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("get_owner_address") + .original_result() + } + + /// We already leave a trace of the calls using the event logs; + /// this additional counter has the role of showing that storage also gets saved correctly. + pub fn call_counts< + Arg0: ProxyArg>, + >( + self, + endpoint: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("call_counts") + .argument(&endpoint) + .original_result() + } + + pub fn num_called_retrieve_funds_promises( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("num_called_retrieve_funds_promises") + .original_result() + } + + pub fn num_async_calls_sent_from_child( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("num_async_calls_sent_from_child") + .original_result() + } +} diff --git a/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.lock b/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.lock index 1c86119ff1..a363608b01 100755 --- a/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -149,15 +151,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -170,6 +172,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "vault" version = "0.0.0" diff --git a/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.toml b/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.toml index 47b5eb2cf3..ca36ea3c03 100644 --- a/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.recursive-caller] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/recursive-caller/wasm/src/lib.rs b/contracts/feature-tests/composability/recursive-caller/wasm/src/lib.rs index 3e2da1f9b6..a129056010 100644 --- a/contracts/feature-tests/composability/recursive-caller/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/recursive-caller/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 3 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_contract_deploy.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_contract_deploy.scen.json index dfaf89f427..5e0097f354 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_contract_deploy.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_contract_deploy.scen.json @@ -88,7 +88,6 @@ }, "expect": { "out": [ - "str:some_argument", "sc:child-with-arg", "nested:str:some_argument" ], @@ -129,7 +128,6 @@ }, "expect": { "out": [ - "str:some_argument", "sc:child-src-with-arg" ], "status": "0", diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_init_sync_echo.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_init_sync_echo.scen.json index 2c1bc8dff7..085233e5a9 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_init_sync_echo.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_init_sync_echo.scen.json @@ -37,10 +37,7 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2" - ], + "out": [], "status": "", "logs": [ { diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_sync_echo.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_sync_echo.scen.json index ac1f58b191..a34e9497fd 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_sync_echo.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_sync_echo.scen.json @@ -37,10 +37,7 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2" - ], + "out": [], "status": "0", "logs": [ { @@ -94,12 +91,7 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2", - "1", - "2" - ], + "out": [], "status": "0", "logs": [ { diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_sync_echo_caller.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_sync_echo_caller.scen.json index 99bf0f279f..a964ec9e19 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_sync_echo_caller.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_sync_echo_caller.scen.json @@ -35,9 +35,7 @@ "gasPrice": "0" }, "expect": { - "out": [ - "sc:forwarder" - ], + "out": [], "status": "0", "logs": [ { @@ -82,10 +80,7 @@ "gasPrice": "0" }, "expect": { - "out": [ - "sc:forwarder", - "sc:forwarder" - ], + "out": [], "status": "0", "logs": [ { diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_sync_readonly.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_sync_readonly.scen.json index f1b53d61ea..0da08b7c08 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_sync_readonly.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_sync_readonly.scen.json @@ -37,10 +37,7 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2" - ], + "out": [], "status": "", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_sync_same_context.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_sync_same_context.scen.json index 08b6b3349b..ff8b81238c 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_sync_same_context.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_sync_same_context.scen.json @@ -38,10 +38,7 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2" - ], + "out": [], "status": "", "logs": [ { diff --git a/contracts/feature-tests/composability/tests/composability_scenario_rs_test.rs b/contracts/feature-tests/composability/tests/composability_scenario_rs_test.rs index fae64b1ab1..33db8b4b49 100644 --- a/contracts/feature-tests/composability/tests/composability_scenario_rs_test.rs +++ b/contracts/feature-tests/composability/tests/composability_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/composability"); blockchain.register_contract( "mxsc:builtin-func-features/output/builtin-func-features.mxsc.json", diff --git a/contracts/feature-tests/composability/forwarder/tests/forwarder_blackbox_test.rs b/contracts/feature-tests/composability/tests/forwarder_blackbox_legacy_test.rs similarity index 73% rename from contracts/feature-tests/composability/forwarder/tests/forwarder_blackbox_test.rs rename to contracts/feature-tests/composability/tests/forwarder_blackbox_legacy_test.rs index bbe8d68ecb..086dd9e11d 100644 --- a/contracts/feature-tests/composability/forwarder/tests/forwarder_blackbox_test.rs +++ b/contracts/feature-tests/composability/tests/forwarder_blackbox_legacy_test.rs @@ -1,4 +1,6 @@ -use forwarder::nft::{Color, ProxyTrait as _}; +#![allow(deprecated)] + +use forwarder_legacy::fwd_nft_legacy::{Color, ProxyTrait as _}; use multiversx_sc_scenario::{ api::StaticApi, @@ -9,32 +11,31 @@ use multiversx_sc_scenario::{ }; const USER_ADDRESS_EXPR: &str = "address:user"; -const FORWARDER_ADDRESS_EXPR: &str = "sc:forwarder"; -const FORWARDER_PATH_EXPR: &str = "mxsc:output/forwarder.mxsc.json"; +const FORWARDER_ADDRESS_EXPR: &str = "sc:forwarder_legacy"; +const FORWARDER_PATH_EXPR: &str = "mxsc:output/forwarder_legacy.mxsc.json"; const NFT_TOKEN_ID_EXPR: &str = "str:COOL-123456"; const NFT_TOKEN_ID: &[u8] = b"COOL-123456"; -type ForwarderContract = ContractInfo>; +type ForwarderContract = ContractInfo>; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/composability/forwarder"); - blockchain.register_contract(FORWARDER_PATH_EXPR, forwarder::ContractBuilder); + blockchain.register_contract(FORWARDER_PATH_EXPR, forwarder_legacy::ContractBuilder); blockchain } struct ForwarderTestState { world: ScenarioWorld, - forwarder_contract: ForwarderContract, + forwarder_legacy_contract: ForwarderContract, } impl ForwarderTestState { fn new() -> Self { let mut world = world(); - let forwarder_code = world.code_expression(FORWARDER_PATH_EXPR); + let forwarder_legacy_code = world.code_expression(FORWARDER_PATH_EXPR); let roles = vec![ "ESDTRoleNFTCreate".to_string(), "ESDTRoleNFTUpdateAttributes".to_string(), @@ -47,16 +48,16 @@ impl ForwarderTestState { FORWARDER_ADDRESS_EXPR, Account::new() .nonce(1) - .code(forwarder_code) + .code(forwarder_legacy_code) .esdt_roles(NFT_TOKEN_ID_EXPR, roles), ), ); - let forwarder_contract = ForwarderContract::new(FORWARDER_ADDRESS_EXPR); + let forwarder_legacy_contract = ForwarderContract::new(FORWARDER_ADDRESS_EXPR); Self { world, - forwarder_contract, + forwarder_legacy_contract, } } } @@ -69,9 +70,11 @@ fn test_nft_update_attributes_and_send() { state.world.sc_call( ScCallStep::new().from(USER_ADDRESS_EXPR).call( - state - .forwarder_contract - .nft_create_compact(NFT_TOKEN_ID, 1u64, original_attributes), + state.forwarder_legacy_contract.nft_create_compact( + NFT_TOKEN_ID, + 1u64, + original_attributes, + ), ), ); @@ -109,9 +112,11 @@ fn test_nft_update_attributes_and_send() { state.world.sc_call( ScCallStep::new().from(USER_ADDRESS_EXPR).call( - state - .forwarder_contract - .nft_update_attributes(NFT_TOKEN_ID, 1u64, new_attributes), + state.forwarder_legacy_contract.nft_update_attributes( + NFT_TOKEN_ID, + 1u64, + new_attributes, + ), ), ); diff --git a/contracts/feature-tests/composability/tests/forwarder_blackbox_test.rs b/contracts/feature-tests/composability/tests/forwarder_blackbox_test.rs new file mode 100644 index 0000000000..7dd5c1a81b --- /dev/null +++ b/contracts/feature-tests/composability/tests/forwarder_blackbox_test.rs @@ -0,0 +1,103 @@ +use forwarder::forwarder_proxy; + +use multiversx_sc_scenario::imports::*; + +const USER_ADDRESS: TestAddress = TestAddress::new("user"); +const FORWARDER_ADDRESS: TestSCAddress = TestSCAddress::new("forwarder"); +const FORWARDER_PATH: MxscPath = MxscPath::new("output/forwarder.mxsc.json"); + +const NFT_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("COOL-123456"); +const NFT_TOKEN: &[u8] = b"COOL-123456"; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(FORWARDER_PATH, forwarder::ContractBuilder); + blockchain +} + +struct ForwarderTestState { + world: ScenarioWorld, +} + +impl ForwarderTestState { + fn new() -> Self { + let mut world = world(); + + let roles = vec![ + "ESDTRoleNFTCreate".to_string(), + "ESDTRoleNFTUpdateAttributes".to_string(), + ]; + + world.account(USER_ADDRESS).nonce(1); + world + .account(FORWARDER_ADDRESS) + .nonce(1) + .code(FORWARDER_PATH) + .esdt_roles(NFT_TOKEN_ID, roles); + + Self { world } + } +} + +#[test] +fn test_nft_update_attributes_and_send() { + let mut state = ForwarderTestState::new(); + + let original_attributes = forwarder_proxy::Color { r: 0, g: 0, b: 0 }; + + state + .world + .tx() + .from(USER_ADDRESS) + .to(FORWARDER_ADDRESS) + .typed(forwarder_proxy::ForwarderProxy) + .nft_create_compact(NFT_TOKEN_ID, 1u64, original_attributes) + .run(); + + state.world.transfer_step( + TransferStep::new() + .from(FORWARDER_ADDRESS.eval_to_expr().as_str()) + .to(USER_ADDRESS.eval_to_expr().as_str()) + .esdt_transfer(NFT_TOKEN, 1, "1"), + ); + + state + .world + .check_account(USER_ADDRESS) + .esdt_nft_balance_and_attributes(NFT_TOKEN_ID, 1, 1, original_attributes); + + let new_attributes = forwarder_proxy::Color { + r: 255, + g: 255, + b: 255, + }; + + state.world.transfer_step( + TransferStep::new() + .from(USER_ADDRESS.eval_to_expr().as_str()) + .to(FORWARDER_ADDRESS.eval_to_expr().as_str()) + .esdt_transfer(NFT_TOKEN, 1, "1"), + ); + + state + .world + .tx() + .from(USER_ADDRESS) + .to(FORWARDER_ADDRESS) + .typed(forwarder_proxy::ForwarderProxy) + .nft_update_attributes(NFT_TOKEN_ID, 1u64, new_attributes) + .run(); + + state.world.transfer_step( + TransferStep::new() + .from(FORWARDER_ADDRESS.eval_to_expr().as_str()) + .to(USER_ADDRESS.eval_to_expr().as_str()) + .esdt_transfer(NFT_TOKEN, 1, "1"), + ); + + state + .world + .check_account(USER_ADDRESS) + .esdt_nft_balance_and_attributes(NFT_TOKEN_ID, 1, 1, new_attributes); +} diff --git a/contracts/feature-tests/composability/tests/forwarder_whitebox_legacy_test.rs b/contracts/feature-tests/composability/tests/forwarder_whitebox_legacy_test.rs new file mode 100644 index 0000000000..8766bfa174 --- /dev/null +++ b/contracts/feature-tests/composability/tests/forwarder_whitebox_legacy_test.rs @@ -0,0 +1,117 @@ +use forwarder_legacy::fwd_nft_legacy::{Color, ForwarderNftModule}; +use multiversx_sc::{contract_base::ContractBase, types::Address}; +use multiversx_sc_scenario::{ + managed_address, managed_biguint, managed_token_id, + scenario_model::{ + Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, SetStateStep, + }, + ScenarioWorld, WhiteboxContract, +}; + +const USER_ADDRESS_EXPR: &str = "address:user"; +const FORWARDER_ADDRESS_EXPR: &str = "sc:forwarder_legacy"; +const FORWARDER_PATH_EXPR: &str = "mxsc:output/forwarder_legacy.mxsc.json"; + +const NFT_TOKEN_ID_EXPR: &str = "str:COOL-123456"; +const NFT_TOKEN_ID: &[u8] = b"COOL-123456"; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(FORWARDER_PATH_EXPR, forwarder_legacy::ContractBuilder); + blockchain +} + +#[test] +fn test_nft_update_attributes_and_send() { + let mut world = world(); + + let forwarder_legacy_code = world.code_expression(FORWARDER_PATH_EXPR); + let roles = vec![ + "ESDTRoleNFTCreate".to_string(), + "ESDTRoleNFTUpdateAttributes".to_string(), + ]; + + world.set_state_step( + SetStateStep::new() + .put_account(USER_ADDRESS_EXPR, Account::new().nonce(1)) + .put_account( + FORWARDER_ADDRESS_EXPR, + Account::new() + .nonce(1) + .code(forwarder_legacy_code) + .esdt_roles(NFT_TOKEN_ID_EXPR, roles), + ), + ); + + let forwarder_legacy_whitebox = + WhiteboxContract::new(FORWARDER_ADDRESS_EXPR, forwarder_legacy::contract_obj); + + let original_attributes = Color { r: 0, g: 0, b: 0 }; + + world.whitebox_call( + &forwarder_legacy_whitebox, + ScCallStep::new().from(USER_ADDRESS_EXPR), + |sc| { + sc.nft_create_compact( + managed_token_id!(NFT_TOKEN_ID), + managed_biguint!(1), + original_attributes, + ); + + sc.send().direct_esdt( + &managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), + &managed_token_id!(NFT_TOKEN_ID), + 1, + &managed_biguint!(1), + ); + }, + ); + + world.check_state_step(CheckStateStep::new().put_account( + USER_ADDRESS_EXPR, + CheckAccount::new().esdt_nft_balance_and_attributes( + NFT_TOKEN_ID_EXPR, + 1, + "1", + Some(original_attributes), + ), + )); + + let new_attributes = Color { + r: 255, + g: 255, + b: 255, + }; + + world.whitebox_call( + &forwarder_legacy_whitebox, + ScCallStep::new() + .from(USER_ADDRESS_EXPR) + .esdt_transfer(NFT_TOKEN_ID, 1, "1"), + |sc| { + sc.nft_update_attributes(managed_token_id!(NFT_TOKEN_ID), 1, new_attributes); + + sc.send().direct_esdt( + &managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), + &managed_token_id!(NFT_TOKEN_ID), + 1, + &managed_biguint!(1), + ); + }, + ); + + world.check_state_step(CheckStateStep::new().put_account( + USER_ADDRESS_EXPR, + CheckAccount::new().esdt_nft_balance_and_attributes( + NFT_TOKEN_ID_EXPR, + 1, + "1", + Some(new_attributes), + ), + )); +} + +fn address_expr_to_address(address_expr: &str) -> Address { + AddressValue::from(address_expr).to_address() +} diff --git a/contracts/feature-tests/composability/forwarder/tests/forwarder_whitebox_test.rs b/contracts/feature-tests/composability/tests/forwarder_whitebox_test.rs similarity index 87% rename from contracts/feature-tests/composability/forwarder/tests/forwarder_whitebox_test.rs rename to contracts/feature-tests/composability/tests/forwarder_whitebox_test.rs index 4cb15d884f..1dbf3952f2 100644 --- a/contracts/feature-tests/composability/forwarder/tests/forwarder_whitebox_test.rs +++ b/contracts/feature-tests/composability/tests/forwarder_whitebox_test.rs @@ -1,12 +1,5 @@ -use forwarder::nft::{Color, ForwarderNftModule}; -use multiversx_sc::{contract_base::ContractBase, types::Address}; -use multiversx_sc_scenario::{ - managed_address, managed_biguint, managed_token_id, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, SetStateStep, - }, - ScenarioWorld, WhiteboxContract, -}; +use forwarder::fwd_nft::{Color, ForwarderNftModule}; +use multiversx_sc_scenario::imports::*; const USER_ADDRESS_EXPR: &str = "address:user"; const FORWARDER_ADDRESS_EXPR: &str = "sc:forwarder"; @@ -17,7 +10,6 @@ const NFT_TOKEN_ID: &[u8] = b"COOL-123456"; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/composability/forwarder"); blockchain.register_contract(FORWARDER_PATH_EXPR, forwarder::ContractBuilder); blockchain diff --git a/contracts/feature-tests/composability/tests/promises_feature_blackbox_test.rs b/contracts/feature-tests/composability/tests/promises_feature_blackbox_test.rs index a2ee00c631..4fd4f4d1cc 100644 --- a/contracts/feature-tests/composability/tests/promises_feature_blackbox_test.rs +++ b/contracts/feature-tests/composability/tests/promises_feature_blackbox_test.rs @@ -1,76 +1,47 @@ use multiversx_sc::types::BigUint; -use multiversx_sc_scenario::{ - api::StaticApi, - scenario_model::{Account, CheckAccount, CheckStateStep, ScCallStep, SetStateStep}, - ContractInfo, ScenarioWorld, -}; - -use promises_features::call_sync_bt::ProxyTrait; - -const USER_ADDRESS_EXPR: &str = "address:user"; -const PROMISES_FEATURE_ADDRESS_EXPR: &str = "sc:promises-feature"; -const PROMISES_FEATURES_PATH_EXPR: &str = - "mxsc:promises-features/output/promises-feature.mxsc.json"; -const VAULT_ADDRESS_EXPR: &str = "sc:vault"; -const VAULT_PATH_EXPR: &str = "mxsc:../vault/output/vault.mxsc.json"; - -const TOKEN_ID_EXPR: &str = "str:TOKEN-123456"; -const TOKEN_ID: &[u8] = b"TOKEN-123456"; +use multiversx_sc_scenario::imports::*; + +use promises_features::promises_feature_proxy; -type PromisesFeaturesContract = ContractInfo>; -type VaultContract = ContractInfo>; +const USER_ADDRESS: TestAddress = TestAddress::new("user"); +const PROMISES_FEATURE_ADDRESS: TestSCAddress = TestSCAddress::new("promises-feature"); +const PROMISES_FEATURES_PATH: MxscPath = + MxscPath::new("promises-features/output/promises-feature.mxsc.json"); +const VAULT_ADDRESS: TestSCAddress = TestSCAddress::new("vault"); +const VAULT_PATH: MxscPath = MxscPath::new("../vault/output/vault.mxsc.json"); + +const TOKEN_ID_EXPR: TestTokenIdentifier = TestTokenIdentifier::new("TOKEN-123456"); +const TOKEN_ID: &[u8] = b"TOKEN-123456"; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/composability"); - blockchain.register_contract( - PROMISES_FEATURES_PATH_EXPR, - promises_features::ContractBuilder, - ); - blockchain.register_contract(VAULT_PATH_EXPR, vault::ContractBuilder); + blockchain.register_contract(PROMISES_FEATURES_PATH, promises_features::ContractBuilder); + blockchain.register_contract(VAULT_PATH, vault::ContractBuilder); blockchain } struct PromisesFeaturesTestState { world: ScenarioWorld, - promises_features_contract: PromisesFeaturesContract, - vault_contract: VaultContract, } impl PromisesFeaturesTestState { fn new() -> Self { let mut world = world(); - let promises_feature_code = world.code_expression(PROMISES_FEATURES_PATH_EXPR); - let vault_code = world.code_expression(VAULT_PATH_EXPR); - - world.set_state_step( - SetStateStep::new() - .put_account(USER_ADDRESS_EXPR, Account::new().nonce(1)) - .put_account( - PROMISES_FEATURE_ADDRESS_EXPR, - Account::new().nonce(1).code(promises_feature_code), - ) - .put_account( - VAULT_ADDRESS_EXPR, - Account::new() - .nonce(1) - .code(vault_code) - .esdt_balance(TOKEN_ID_EXPR, "1000"), - ), - ); - - let promises_features_contract = - PromisesFeaturesContract::new(PROMISES_FEATURE_ADDRESS_EXPR); - let vault_contract = VaultContract::new(VAULT_ADDRESS_EXPR); - - Self { - world, - promises_features_contract, - vault_contract, - } + world.account(USER_ADDRESS).nonce(1); + world + .account(PROMISES_FEATURE_ADDRESS) + .nonce(1) + .code(PROMISES_FEATURES_PATH); + world + .account(VAULT_ADDRESS) + .nonce(1) + .code(VAULT_PATH) + .esdt_balance(TOKEN_ID_EXPR, 1000); + + Self { world } } } @@ -79,25 +50,19 @@ fn test_back_transfers() { let mut state = PromisesFeaturesTestState::new(); let token_amount = BigUint::from(1000u64); - state.world.sc_call( - ScCallStep::new().from(USER_ADDRESS_EXPR).call( - state - .promises_features_contract - .forward_sync_retrieve_funds_bt( - state.vault_contract, - TOKEN_ID, - 0u64, - &token_amount, - ), - ), - ); + state + .world + .tx() + .from(USER_ADDRESS) + .to(PROMISES_FEATURE_ADDRESS) + .typed(promises_feature_proxy::PromisesFeaturesProxy) + .forward_sync_retrieve_funds_bt(VAULT_ADDRESS, TOKEN_ID, 0u64, &token_amount) + .run(); state .world - .check_state_step(CheckStateStep::new().put_account( - state.promises_features_contract, - CheckAccount::new().esdt_balance(TOKEN_ID_EXPR, token_amount), - )); + .check_account(PROMISES_FEATURE_ADDRESS) + .esdt_balance(TOKEN_ID_EXPR, token_amount); } #[test] @@ -105,25 +70,18 @@ fn test_multi_call_back_transfers() { let mut state = PromisesFeaturesTestState::new(); let token_amount = BigUint::from(1000u64); let half_token_amount = token_amount.clone() / 2u64; - let vault_address = state.vault_contract.to_address(); - - state.world.sc_call( - ScCallStep::new().from(USER_ADDRESS_EXPR).call( - state - .promises_features_contract - .forward_sync_retrieve_funds_bt_twice( - vault_address.clone(), - TOKEN_ID, - 0u64, - &half_token_amount, - ), - ), - ); state .world - .check_state_step(CheckStateStep::new().put_account( - state.promises_features_contract, - CheckAccount::new().esdt_balance(TOKEN_ID_EXPR, token_amount), - )); + .tx() + .from(USER_ADDRESS) + .to(PROMISES_FEATURE_ADDRESS) + .typed(promises_feature_proxy::PromisesFeaturesProxy) + .forward_sync_retrieve_funds_bt_twice(VAULT_ADDRESS, TOKEN_ID, 0u64, &half_token_amount) + .run(); + + state + .world + .check_account(PROMISES_FEATURE_ADDRESS) + .esdt_balance(TOKEN_ID_EXPR, token_amount); } diff --git a/contracts/feature-tests/composability/transfer-role-features/Cargo.toml b/contracts/feature-tests/composability/transfer-role-features/Cargo.toml index 40085fa73e..76b5d3b38d 100644 --- a/contracts/feature-tests/composability/transfer-role-features/Cargo.toml +++ b/contracts/feature-tests/composability/transfer-role-features/Cargo.toml @@ -12,13 +12,13 @@ path = "src/lib.rs" path = "../vault" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/transfer-role-features/meta/Cargo.toml b/contracts/feature-tests/composability/transfer-role-features/meta/Cargo.toml index 203a996a76..a1bc8f5bba 100644 --- a/contracts/feature-tests/composability/transfer-role-features/meta/Cargo.toml +++ b/contracts/feature-tests/composability/transfer-role-features/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.transfer-role-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/transfer-role-features/meta/src/main.rs b/contracts/feature-tests/composability/transfer-role-features/meta/src/main.rs index a8eb09e9c1..2b1d3aa6b3 100644 --- a/contracts/feature-tests/composability/transfer-role-features/meta/src/main.rs +++ b/contracts/feature-tests/composability/transfer-role-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/transfer-role-features/sc-config.toml b/contracts/feature-tests/composability/transfer-role-features/sc-config.toml new file mode 100644 index 0000000000..5bceb5fda7 --- /dev/null +++ b/contracts/feature-tests/composability/transfer-role-features/sc-config.toml @@ -0,0 +1,2 @@ +[[proxy]] +path = "src/transfer_role_proxy.rs" \ No newline at end of file diff --git a/contracts/feature-tests/composability/transfer-role-features/src/lib.rs b/contracts/feature-tests/composability/transfer-role-features/src/lib.rs index b689b76d43..97c71a3577 100644 --- a/contracts/feature-tests/composability/transfer-role-features/src/lib.rs +++ b/contracts/feature-tests/composability/transfer-role-features/src/lib.rs @@ -2,6 +2,7 @@ #![allow(clippy::type_complexity)] multiversx_sc::imports!(); +pub mod transfer_role_proxy; #[multiversx_sc::contract] pub trait TransferRoleFeatures: @@ -30,7 +31,7 @@ pub trait TransferRoleFeatures: } if !self.blockchain().is_smart_contract(&dest) { - self.transfer_to_user(original_caller, dest, payments.clone_value(), endpoint_name); + self.transfer_to_user(original_caller, dest, &payments, endpoint_name); } else { let mut args_buffer = ManagedArgBuffer::new(); for arg in args { @@ -40,7 +41,7 @@ pub trait TransferRoleFeatures: self.transfer_to_contract_raw( original_caller, dest, - payments.clone_value(), + &payments, endpoint_name, args_buffer, None, diff --git a/contracts/feature-tests/composability/transfer-role-features/src/transfer_role_proxy.rs b/contracts/feature-tests/composability/transfer-role-features/src/transfer_role_proxy.rs new file mode 100644 index 0000000000..1447af2d70 --- /dev/null +++ b/contracts/feature-tests/composability/transfer-role-features/src/transfer_role_proxy.rs @@ -0,0 +1,86 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct TransferRoleFeaturesProxy; + +impl TxProxyTrait for TransferRoleFeaturesProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = TransferRoleFeaturesProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + TransferRoleFeaturesProxyMethods { wrapped_tx: tx } + } +} + +pub struct TransferRoleFeaturesProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl TransferRoleFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>>, + >( + self, + whitelist: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&whitelist) + .original_result() + } +} + +#[rustfmt::skip] +impl TransferRoleFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn forward_payments< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + >( + self, + dest: Arg0, + endpoint_name: Arg1, + args: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("forwardPayments") + .argument(&dest) + .argument(&endpoint_name) + .argument(&args) + .original_result() + } +} diff --git a/contracts/feature-tests/composability/transfer-role-features/tests/transfer_role_blackbox_test.rs b/contracts/feature-tests/composability/transfer-role-features/tests/transfer_role_blackbox_test.rs index acaefbfb1d..080facb377 100644 --- a/contracts/feature-tests/composability/transfer-role-features/tests/transfer_role_blackbox_test.rs +++ b/contracts/feature-tests/composability/transfer-role-features/tests/transfer_role_blackbox_test.rs @@ -1,122 +1,91 @@ -use multiversx_sc::{codec::multi_types::MultiValueVec, types::Address}; -use multiversx_sc_scenario::{ - api::StaticApi, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, ScDeployStep, - SetStateStep, TxExpect, - }, - ContractInfo, ScenarioWorld, -}; -use transfer_role_features::ProxyTrait as _; +use multiversx_sc_scenario::imports::*; +use transfer_role_features::transfer_role_proxy; const ACCEPT_FUNDS_FUNC_NAME: &[u8] = b"accept_funds"; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; const REJECT_FUNDS_FUNC_NAME: &[u8] = b"reject_funds"; -const TRANSFER_ROLE_FEATURES_ADDRESS_EXPR: &str = "sc:transfer-role-features"; -const TRANSFER_ROLE_FEATURES_PATH_EXPR: &str = "mxsc:output/transfer-role-features.mxsc.json"; -const TRANSFER_TOKEN_ID: &[u8] = b"TRANSFER-123456"; -const TRANSFER_TOKEN_ID_EXPR: &str = "str:TRANSFER-123456"; -const USER_ADDRESS_EXPR: &str = "address:user"; -const VAULT_ADDRESS_EXPR: &str = "sc:vault"; -const VAULT_PATH_EXPR: &str = "mxsc:../vault/output/vault.mxsc.json"; - -type TransferRoleFeaturesContract = ContractInfo>; +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const TRANSFER_ROLE_FEATURES_ADDRESS: TestSCAddress = TestSCAddress::new("transfer-role-features"); +const TRANSFER_ROLE_FEATURES_PATH: MxscPath = + MxscPath::new("output/transfer-role-features.mxsc.json"); +const TRANSFER_TOKEN: TestTokenIdentifier = TestTokenIdentifier::new("TRANSFER-123456"); +const USER_ADDRESS: TestAddress = TestAddress::new("user"); +const VAULT_ADDRESS: TestSCAddress = TestSCAddress::new("vault"); +const VAULT_PATH: MxscPath = MxscPath::new("../vault/output/vault.mxsc.json"); fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace( - "contracts/feature-tests/composability/transfer-role-features", - ); blockchain.register_contract( - TRANSFER_ROLE_FEATURES_PATH_EXPR, + TRANSFER_ROLE_FEATURES_PATH, transfer_role_features::ContractBuilder, ); - blockchain.register_contract(VAULT_PATH_EXPR, vault::ContractBuilder); + blockchain.register_contract(VAULT_PATH, vault::ContractBuilder); blockchain } struct TransferRoleTestState { world: ScenarioWorld, - owner_address: Address, - vault_address: Address, - transfer_role_features_contract: TransferRoleFeaturesContract, } impl TransferRoleTestState { fn new() -> Self { let mut world = world(); - let vault_code = world.code_expression(VAULT_PATH_EXPR); - - world.set_state_step( - SetStateStep::new() - .put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .new_address(OWNER_ADDRESS_EXPR, 1, TRANSFER_ROLE_FEATURES_ADDRESS_EXPR) - .put_account(VAULT_ADDRESS_EXPR, Account::new().nonce(1).code(vault_code)) - .put_account( - USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(TRANSFER_TOKEN_ID_EXPR, 1_000u64), - ), + + world.account(OWNER_ADDRESS).nonce(1).new_address( + OWNER_ADDRESS, + 1, + TRANSFER_ROLE_FEATURES_ADDRESS, ); - let owner_address = AddressValue::from(OWNER_ADDRESS_EXPR).to_address(); - let vault_address = AddressValue::from(VAULT_ADDRESS_EXPR).to_address(); - let transfer_role_features_contract = - TransferRoleFeaturesContract::new(TRANSFER_ROLE_FEATURES_ADDRESS_EXPR); - - Self { - world, - owner_address, - vault_address, - transfer_role_features_contract, - } + world.account(VAULT_ADDRESS).nonce(1).code(VAULT_PATH); + world + .account(USER_ADDRESS) + .nonce(1) + .esdt_balance(TRANSFER_TOKEN, 1000); + + Self { world } } fn deploy(&mut self) -> &mut Self { - let transfer_role_features_code = - self.world.code_expression(TRANSFER_ROLE_FEATURES_PATH_EXPR); - let whitelist = MultiValueVec::from(vec![ - AddressValue::from(OWNER_ADDRESS_EXPR).to_address(), - AddressValue::from(VAULT_ADDRESS_EXPR).to_address(), + AddressValue::from(OWNER_ADDRESS).to_address(), + AddressValue::from(VAULT_ADDRESS).to_address(), ]); - self.world.sc_deploy( - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(transfer_role_features_code) - .call(self.transfer_role_features_contract.init(whitelist)), - ); + self.world + .tx() + .from(OWNER_ADDRESS) + .typed(transfer_role_proxy::TransferRoleFeaturesProxy) + .init(whitelist) + .code(TRANSFER_ROLE_FEATURES_PATH) + .new_address(TRANSFER_ROLE_FEATURES_ADDRESS) + .run(); self } fn forward_payments(&mut self, dest: Address, endpoint_name: &[u8]) { - self.world.sc_call( - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .esdt_transfer(TRANSFER_TOKEN_ID, 0, 100u64) - .call(self.transfer_role_features_contract.forward_payments( - dest, - endpoint_name, - MultiValueVec::>::new(), - )), - ); + self.world + .tx() + .from(USER_ADDRESS) + .to(TRANSFER_ROLE_FEATURES_ADDRESS) + .typed(transfer_role_proxy::TransferRoleFeaturesProxy) + .forward_payments(dest, endpoint_name, MultiValueVec::>::new()) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(TRANSFER_TOKEN), + 0u64, + &multiversx_sc::proxy_imports::BigUint::from(100u64), + ) + .run(); } fn check_user_and_vault_balance(&mut self) { self.world - .check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "800"), - )); + .check_account(USER_ADDRESS) + .esdt_balance(TRANSFER_TOKEN, 800); self.world - .check_state_step(CheckStateStep::new().put_account( - VAULT_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "100"), - )); + .check_account(VAULT_ADDRESS) + .esdt_balance(TRANSFER_TOKEN, 100); } } @@ -126,40 +95,38 @@ fn test_transfer_role() { state.deploy(); // transfer to user - ok - state.forward_payments(state.owner_address.clone(), b""); + state.forward_payments(Address::from(OWNER_ADDRESS.eval_to_array()), b""); state .world - .check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "900"), - )); + .check_account(USER_ADDRESS) + .esdt_balance(TRANSFER_TOKEN, 900); + state .world - .check_state_step(CheckStateStep::new().put_account( - OWNER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "100"), - )); + .check_account(OWNER_ADDRESS) + .esdt_balance(TRANSFER_TOKEN, 100); // transfer to user - err, not whitelisted - state.world.sc_call( - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .esdt_transfer(TRANSFER_TOKEN_ID, 0, 100u64) - .call(state.transfer_role_features_contract.forward_payments( - Address::zero(), - "", - MultiValueVec::>::new(), - )) - .expect(TxExpect::user_error( - "str:Destination address not whitelisted", - )), - ); + state + .world + .tx() + .from(USER_ADDRESS) + .to(TRANSFER_ROLE_FEATURES_ADDRESS) + .typed(transfer_role_proxy::TransferRoleFeaturesProxy) + .forward_payments(Address::zero(), "", MultiValueVec::>::new()) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(TRANSFER_TOKEN), + 0u64, + &multiversx_sc::proxy_imports::BigUint::from(100u64), + ) + .with_result(ExpectMessage("Destination address not whitelisted")) + .run(); // transfer to sc - ok - state.forward_payments(state.vault_address.clone(), ACCEPT_FUNDS_FUNC_NAME); + state.forward_payments(VAULT_ADDRESS.to_address(), ACCEPT_FUNDS_FUNC_NAME); state.check_user_and_vault_balance(); // transfer to sc - reject - state.forward_payments(state.vault_address.clone(), REJECT_FUNDS_FUNC_NAME); + state.forward_payments(VAULT_ADDRESS.to_address(), REJECT_FUNDS_FUNC_NAME); state.check_user_and_vault_balance(); } diff --git a/contracts/feature-tests/composability/transfer-role-features/tests/transfer_role_whitebox_test.rs b/contracts/feature-tests/composability/transfer-role-features/tests/transfer_role_whitebox_test.rs index 155f82ce9d..adf9582982 100644 --- a/contracts/feature-tests/composability/transfer-role-features/tests/transfer_role_whitebox_test.rs +++ b/contracts/feature-tests/composability/transfer-role-features/tests/transfer_role_whitebox_test.rs @@ -1,14 +1,5 @@ -use multiversx_sc::types::{ - Address, EsdtTokenPayment, ManagedArgBuffer, ManagedVec, MultiValueEncoded, -}; use multiversx_sc_modules::transfer_role_proxy::TransferRoleProxyModule; -use multiversx_sc_scenario::{ - managed_address, managed_biguint, managed_buffer, managed_token_id, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, ScDeployStep, SetStateStep, - }, - ScenarioWorld, WhiteboxContract, -}; +use multiversx_sc_scenario::imports::*; use transfer_role_features::TransferRoleFeatures; const OWNER_ADDRESS_EXPR: &str = "address:owner"; @@ -25,10 +16,6 @@ const REJECT_FUNDS_FUNC_NAME: &[u8] = b"reject_funds"; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace( - "contracts/composability/feature-tests/transfer-role-features", - ); - blockchain.register_contract( TRANSFER_ROLE_FEATURES_PATH_EXPR, transfer_role_features::ContractBuilder, @@ -104,7 +91,7 @@ fn test_transfer_role() { sc.transfer_to_user( managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), managed_address!(&address_expr_to_address(OWNER_ADDRESS_EXPR)), - payments, + &payments, managed_buffer!(b"enjoy"), ); }, @@ -135,7 +122,7 @@ fn test_transfer_role() { sc.transfer_to_user( managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), managed_address!(&Address::zero()), - payments, + &payments, managed_buffer!(b"enjoy"), ); }, @@ -159,7 +146,7 @@ fn test_transfer_role() { sc.transfer_to_contract_raw( managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), managed_address!(&address_expr_to_address(VAULT_ADDRESS_EXPR)), - payments, + &payments, managed_buffer!(ACCEPT_FUNDS_FUNC_NAME), ManagedArgBuffer::new(), None, @@ -191,7 +178,7 @@ fn test_transfer_role() { sc.transfer_to_contract_raw( managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), managed_address!(&address_expr_to_address(VAULT_ADDRESS_EXPR)), - payments, + &payments, managed_buffer!(REJECT_FUNDS_FUNC_NAME), ManagedArgBuffer::new(), None, diff --git a/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.lock b/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.lock index bb7ae8f108..8999fc8883 100644 --- a/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,14 +82,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,27 +105,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -140,15 +142,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.toml b/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.toml index ff699a705e..b29ca05253 100644 --- a/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.transfer-role-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/transfer-role-features/wasm/src/lib.rs b/contracts/feature-tests/composability/transfer-role-features/wasm/src/lib.rs index 317595fcea..9f507871cd 100644 --- a/contracts/feature-tests/composability/transfer-role-features/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/transfer-role-features/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 3 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/vault/Cargo.toml b/contracts/feature-tests/composability/vault/Cargo.toml index 6d81c26350..f014b6234a 100644 --- a/contracts/feature-tests/composability/vault/Cargo.toml +++ b/contracts/feature-tests/composability/vault/Cargo.toml @@ -10,9 +10,9 @@ path = "src/vault.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/vault/meta/Cargo.toml b/contracts/feature-tests/composability/vault/meta/Cargo.toml index 2fc51374aa..8110c00500 100644 --- a/contracts/feature-tests/composability/vault/meta/Cargo.toml +++ b/contracts/feature-tests/composability/vault/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.vault] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/composability/vault/meta/src/main.rs b/contracts/feature-tests/composability/vault/meta/src/main.rs index 355942918a..a95e69d1a3 100644 --- a/contracts/feature-tests/composability/vault/meta/src/main.rs +++ b/contracts/feature-tests/composability/vault/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/composability/vault/sc-config.toml b/contracts/feature-tests/composability/vault/sc-config.toml index f0d4da2f02..5a76bc3096 100644 --- a/contracts/feature-tests/composability/vault/sc-config.toml +++ b/contracts/feature-tests/composability/vault/sc-config.toml @@ -15,3 +15,15 @@ add-labels = ["promises-endpoint"] name = "vault-upgrade" add-unlabelled = false add-labels = ["upgrade"] + +[[proxy]] +path = "../forwarder/src/vault_proxy.rs" + +[[proxy]] +path = "../promises-features/src/vault_proxy.rs" + +[[proxy]] +path = "../recursive-caller/src/vault_proxy.rs" + +[[proxy]] +path = "../interact/src/vault_proxy.rs" diff --git a/contracts/feature-tests/composability/vault/src/vault.rs b/contracts/feature-tests/composability/vault/src/vault.rs index 9dfaa11a07..1fb32cccdd 100644 --- a/contracts/feature-tests/composability/vault/src/vault.rs +++ b/contracts/feature-tests/composability/vault/src/vault.rs @@ -107,16 +107,12 @@ pub trait Vault { let caller = self.blockchain().get_caller(); let func_name = opt_receive_func.into_option().unwrap_or_default(); - self.send_raw() - .transfer_esdt_execute( - &caller, - &token, - &amount, - 50_000_000, - &func_name, - &ManagedArgBuffer::new(), - ) - .unwrap_or_else(|_| sc_panic!("ESDT transfer failed")); + self.tx() + .to(&caller) + .gas(50_000_000u64) + .raw_call(func_name) + .single_esdt(&token, 0u64, &amount) + .transfer_execute(); } #[allow_multiple_var_args] @@ -150,10 +146,11 @@ pub trait Vault { for _ in 0..nr_callbacks { self.num_async_calls_sent_from_child().update(|c| *c += 1); - self.send() - .contract_call::<()>(caller.clone(), endpoint_name.clone()) - .with_egld_or_single_esdt_transfer(return_payment.clone()) - .with_gas_limit(self.blockchain().get_gas_left() / 2) + self.tx() + .to(&caller) + .raw_call(endpoint_name.clone()) + .payment(&return_payment) + .gas(self.blockchain().get_gas_left() / 2) .transfer_execute() } } @@ -164,10 +161,12 @@ pub trait Vault { let caller = self.blockchain().get_caller(); if let Some(esdt_token_id) = token.into_esdt_option() { - self.send() - .direct_esdt(&caller, &esdt_token_id, nonce, &amount); + self.tx() + .to(caller) + .esdt((esdt_token_id, nonce, amount)) + .transfer(); } else { - self.send().direct_egld(&caller, &amount); + self.tx().to(caller).egld(amount).transfer(); } } @@ -185,12 +184,12 @@ pub trait Vault { all_payments.push(EsdtTokenPayment::new(token_id, nonce, amount)); } - self.send().direct_multi(&caller, &all_payments); + self.tx().to(caller).payment(all_payments).transfer(); } #[payable("*")] #[endpoint] - fn burn_and_create_retrive_async(&self) { + fn burn_and_create_retrieve_async(&self) { let payments = self.call_value().all_esdt_transfers(); let mut uris = ManagedVec::new(); uris.push(ManagedBuffer::new()); @@ -223,8 +222,7 @@ pub trait Vault { )); } - self.send() - .direct_multi(&self.blockchain().get_caller(), &new_tokens); + self.tx().to(ToCaller).payment(new_tokens).transfer(); } #[event("accept_funds")] diff --git a/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.lock b/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.lock index ee08553757..57ea0b6085 100644 --- a/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.lock +++ b/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -133,15 +135,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -154,6 +156,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "vault" version = "0.0.0" diff --git a/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.toml b/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.toml index 63df7d0d02..bb85ed8ea8 100644 --- a/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.toml +++ b/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.vault] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/vault/wasm-vault-promises/src/lib.rs b/contracts/feature-tests/composability/vault/wasm-vault-promises/src/lib.rs index f1a599dafe..014291f680 100644 --- a/contracts/feature-tests/composability/vault/wasm-vault-promises/src/lib.rs +++ b/contracts/feature-tests/composability/vault/wasm-vault-promises/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 18 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -30,7 +28,7 @@ multiversx_sc_wasm_adapter::endpoints! { retrieve_funds_with_transfer_exec => retrieve_funds_with_transfer_exec retrieve_funds => retrieve_funds retrieve_multi_funds_async => retrieve_multi_funds_async - burn_and_create_retrive_async => burn_and_create_retrive_async + burn_and_create_retrieve_async => burn_and_create_retrieve_async get_owner_address => get_owner_address call_counts => call_counts num_called_retrieve_funds_promises => num_called_retrieve_funds_promises diff --git a/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.lock b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.lock index 5130bd4f11..33ce46111e 100644 --- a/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.lock +++ b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -133,15 +135,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -154,6 +156,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "vault" version = "0.0.0" diff --git a/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.toml b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.toml index 33c14f4fd5..f82dbd235a 100644 --- a/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.toml +++ b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.vault] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/vault/wasm-vault-upgrade/src/lib.rs b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/src/lib.rs index 904a343933..15f7408f1f 100644 --- a/contracts/feature-tests/composability/vault/wasm-vault-upgrade/src/lib.rs +++ b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/src/lib.rs @@ -4,14 +4,12 @@ ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// -// Init: 1 -// Endpoints: 1 +// Upgrade: 1 +// Endpoints: 0 // Async Callback (empty): 1 -// Total number of exported functions: 3 +// Total number of exported functions: 2 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/vault/wasm/Cargo.lock b/contracts/feature-tests/composability/vault/wasm/Cargo.lock index 7c62c838a8..f4b152850b 100755 --- a/contracts/feature-tests/composability/vault/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/vault/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -133,15 +135,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -154,6 +156,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "vault" version = "0.0.0" diff --git a/contracts/feature-tests/composability/vault/wasm/Cargo.toml b/contracts/feature-tests/composability/vault/wasm/Cargo.toml index 31122e31f2..2b5f929dee 100644 --- a/contracts/feature-tests/composability/vault/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/vault/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.vault] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/composability/vault/wasm/src/lib.rs b/contracts/feature-tests/composability/vault/wasm/src/lib.rs index 3ef976396a..9849ddf8ae 100644 --- a/contracts/feature-tests/composability/vault/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/vault/wasm/src/lib.rs @@ -5,13 +5,12 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 16 +// Upgrade: 1 +// Endpoints: 15 // Async Callback (empty): 1 // Total number of exported functions: 18 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -20,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { vault ( init => init + upgrade => upgrade echo_arguments => echo_arguments echo_arguments_without_storage => echo_arguments_without_storage echo_caller => echo_caller @@ -30,12 +30,11 @@ multiversx_sc_wasm_adapter::endpoints! { retrieve_funds_with_transfer_exec => retrieve_funds_with_transfer_exec retrieve_funds => retrieve_funds retrieve_multi_funds_async => retrieve_multi_funds_async - burn_and_create_retrive_async => burn_and_create_retrive_async + burn_and_create_retrieve_async => burn_and_create_retrieve_async get_owner_address => get_owner_address call_counts => call_counts num_called_retrieve_funds_promises => num_called_retrieve_funds_promises num_async_calls_sent_from_child => num_async_calls_sent_from_child - upgrade => upgrade ) } diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/Cargo.toml b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/Cargo.toml index af4e57038a..95a77618de 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/Cargo.toml @@ -12,10 +12,10 @@ path = "src/crowdfunding_erc20.rs" path = "../erc20" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/meta/Cargo.toml b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/meta/Cargo.toml index ce6234c630..d5c4572abe 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.crowdfunding-erc20] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/meta/src/main.rs b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/meta/src/main.rs index 090be7d23b..ca48e63847 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/meta/src/main.rs +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/src/crowdfunding_erc20.rs b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/src/crowdfunding_erc20.rs index fe509eba5b..019ec560a5 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/src/crowdfunding_erc20.rs +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/src/crowdfunding_erc20.rs @@ -3,6 +3,8 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); +pub mod erc20_proxy; + #[derive(TopEncode, TopDecode, PartialEq, Eq, TypeAbi, Clone, Copy)] pub enum Status { FundingPeriod, @@ -30,14 +32,15 @@ pub trait Crowdfunding { let erc20_address = self.erc20_contract_address().get(); let cf_contract_address = self.blockchain().get_sc_address(); - self.erc20_proxy(erc20_address) + self.tx() + .to(&erc20_address) + .typed(erc20_proxy::SimpleErc20TokenProxy) .transfer_from(caller.clone(), cf_contract_address, token_amount.clone()) - .async_call() - .with_callback( + .callback( self.callbacks() .transfer_from_callback(caller, token_amount), ) - .call_and_exit() + .async_call_and_exit(); } #[view] @@ -70,10 +73,11 @@ pub trait Crowdfunding { let erc20_address = self.erc20_contract_address().get(); - self.erc20_proxy(erc20_address) + self.tx() + .to(&erc20_address) + .typed(erc20_proxy::SimpleErc20TokenProxy) .transfer(caller, balance) - .async_call() - .call_and_exit() + .async_call_and_exit(); }, Status::Failed => { let caller = self.blockchain().get_caller(); @@ -84,10 +88,11 @@ pub trait Crowdfunding { let erc20_address = self.erc20_contract_address().get(); - self.erc20_proxy(erc20_address) + self.tx() + .to(&erc20_address) + .typed(erc20_proxy::SimpleErc20TokenProxy) .transfer(caller, deposit) - .async_call() - .call_and_exit() + .async_call_and_exit(); } }, } @@ -106,10 +111,11 @@ pub trait Crowdfunding { if self.blockchain().get_block_nonce() > self.deadline().get() { let erc20_address = self.erc20_contract_address().get(); - self.erc20_proxy(erc20_address) + self.tx() + .to(&erc20_address) + .typed(erc20_proxy::SimpleErc20TokenProxy) .transfer(cb_sender, cb_amount) - .async_call() - .call_and_exit(); + .async_call_and_exit(); } self.deposit(&cb_sender) @@ -120,11 +126,6 @@ pub trait Crowdfunding { } } - // proxy - - #[proxy] - fn erc20_proxy(&self, to: ManagedAddress) -> erc20::Proxy; - // storage #[view(get_target)] diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/src/erc20_proxy.rs b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/src/erc20_proxy.rs new file mode 100644 index 0000000000..cda5046b56 --- /dev/null +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/src/erc20_proxy.rs @@ -0,0 +1,195 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct SimpleErc20TokenProxy; + +impl TxProxyTrait for SimpleErc20TokenProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = SimpleErc20TokenProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + SimpleErc20TokenProxyMethods { wrapped_tx: tx } + } +} + +pub struct SimpleErc20TokenProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl SimpleErc20TokenProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + /// Constructor, is called immediately after the contract is created + /// Will set the fixed global token supply and give all the supply to the creator. + pub fn init< + Arg0: ProxyArg>, + >( + self, + total_supply: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&total_supply) + .original_result() + } +} + +#[rustfmt::skip] +impl SimpleErc20TokenProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + /// Total number of tokens in existence. + pub fn total_supply( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("totalSupply") + .original_result() + } + + /// Gets the balance of the specified address. + /// + /// Arguments: + /// + /// * `address` The address to query the the balance of + /// + pub fn token_balance< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("balanceOf") + .argument(&address) + .original_result() + } + + /// The amount of tokens that an owner allowed to a spender. + /// + /// Arguments: + /// + /// * `owner` The address that owns the funds. + /// * `spender` The address that will spend the funds. + /// + pub fn allowance< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + owner: Arg0, + spender: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("allowance") + .argument(&owner) + .argument(&spender) + .original_result() + } + + /// Transfer token to a specified address from sender. + /// + /// Arguments: + /// + /// * `to` The address to transfer to. + /// + pub fn transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer") + .argument(&to) + .argument(&amount) + .original_result() + } + + /// Use allowance to transfer funds between two accounts. + /// + /// Arguments: + /// + /// * `sender` The address to transfer from. + /// * `recipient` The address to transfer to. + /// * `amount` the amount of tokens to be transferred. + /// + pub fn transfer_from< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + sender: Arg0, + recipient: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transferFrom") + .argument(&sender) + .argument(&recipient) + .argument(&amount) + .original_result() + } + + /// Approve the given address to spend the specified amount of tokens on behalf of the sender. + /// It overwrites any previously existing allowance from sender to beneficiary. + /// + /// Arguments: + /// + /// * `spender` The address that will spend the funds. + /// * `amount` The amount of tokens to be spent. + /// + pub fn approve< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + spender: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("approve") + .argument(&spender) + .argument(&amount) + .original_result() + } +} diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/tests/crowdfunding_erc20_scenario_rs_test.rs b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/tests/crowdfunding_erc20_scenario_rs_test.rs index e14767b48f..a75f0a6dd3 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/tests/crowdfunding_erc20_scenario_rs_test.rs +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/tests/crowdfunding_erc20_scenario_rs_test.rs @@ -2,20 +2,14 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace( - "contracts/feature-tests/erc-style-contracts/crowdfunding-erc20", - ); - blockchain.register_contract( "mxsc:output/crowdfunding-erc20.mxsc.json", crowdfunding_erc20::ContractBuilder, ); - blockchain.register_contract( "mxsc:../erc20/output/erc20.mxsc.json", erc20::ContractBuilder, ); - blockchain } diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/Cargo.lock b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/Cargo.lock index c1f6bbab6c..37ea735e09 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "crowdfunding-erc20" @@ -63,26 +63,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -92,7 +94,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -103,7 +105,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/Cargo.toml b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/Cargo.toml index a73660bac8..0a8e753e0e 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.crowdfunding-erc20] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/src/lib.rs b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/src/lib.rs index d71ab01834..2493301277 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/src/lib.rs +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/Cargo.toml index 83577513c1..f27a097e68 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/Cargo.toml @@ -13,10 +13,10 @@ path = "src/lib.rs" path = "../erc1155" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/meta/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/meta/Cargo.toml index b2c318dd13..0702e6a50c 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.erc1155-marketplace] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/meta/src/main.rs b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/meta/src/main.rs index f36c298d55..20153e760c 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/meta/src/main.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/src/erc1155_proxy.rs b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/src/erc1155_proxy.rs new file mode 100644 index 0000000000..f3fdd90854 --- /dev/null +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/src/erc1155_proxy.rs @@ -0,0 +1,283 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct Erc1155Proxy; + +impl TxProxyTrait for Erc1155Proxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = Erc1155ProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + Erc1155ProxyMethods { wrapped_tx: tx } + } +} + +pub struct Erc1155ProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl Erc1155ProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl Erc1155ProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + /// `value` is amount for fungible, nft_id for non-fungible + pub fn safe_transfer_from< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + >( + self, + from: Arg0, + to: Arg1, + type_id: Arg2, + value: Arg3, + data: Arg4, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("safeTransferFrom") + .argument(&from) + .argument(&to) + .argument(&type_id) + .argument(&value) + .argument(&data) + .original_result() + } + + /// `value` is amount for fungible, nft_id for non-fungible + pub fn safe_batch_transfer_from< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg]>>, + Arg3: ProxyArg]>>, + Arg4: ProxyArg>, + >( + self, + from: Arg0, + to: Arg1, + type_ids: Arg2, + values: Arg3, + data: Arg4, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("safeBatchTransferFrom") + .argument(&from) + .argument(&to) + .argument(&type_ids) + .argument(&values) + .argument(&data) + .original_result() + } + + pub fn set_approved_for_all< + Arg0: ProxyArg>, + Arg1: ProxyArg, + >( + self, + operator: Arg0, + approved: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("setApprovalForAll") + .argument(&operator) + .argument(&approved) + .original_result() + } + + pub fn create_token< + Arg0: ProxyArg, + Arg1: ProxyArg>, + Arg2: ProxyArg, + >( + self, + uri: Arg0, + initial_supply: Arg1, + is_fungible: Arg2, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("createToken") + .argument(&uri) + .argument(&initial_supply) + .argument(&is_fungible) + .original_result() + } + + pub fn mint< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + type_id: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("mint") + .argument(&type_id) + .argument(&amount) + .original_result() + } + + pub fn burn< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + type_id: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("burn") + .argument(&type_id) + .argument(&amount) + .original_result() + } + + pub fn balance_of< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + owner: Arg0, + type_id: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("balanceOf") + .argument(&owner) + .argument(&type_id) + .original_result() + } + + pub fn balance_of_batch< + Arg0: ProxyArg, BigUint>>>, + >( + self, + owner_type_id_pairs: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("balanceOfBatch") + .argument(&owner_type_id_pairs) + .original_result() + } + + pub fn token_owner< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + type_id: Arg0, + nft_id: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getTokenOwner") + .argument(&type_id) + .argument(&nft_id) + .original_result() + } + + pub fn token_type_creator< + Arg0: ProxyArg>, + >( + self, + type_id: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getTokenTypeCreator") + .argument(&type_id) + .original_result() + } + + pub fn token_type_uri< + Arg0: ProxyArg>, + >( + self, + type_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getTokenTypeUri") + .argument(&type_id) + .original_result() + } + + pub fn is_fungible< + Arg0: ProxyArg>, + >( + self, + type_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isFungible") + .argument(&type_id) + .original_result() + } + + pub fn is_approved< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + operator: Arg0, + owner: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("isApprovedForAll") + .argument(&operator) + .argument(&owner) + .original_result() + } +} diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/src/lib.rs b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/src/lib.rs index 676b2b5b1d..7aa633d71c 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/src/lib.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/src/lib.rs @@ -3,6 +3,8 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); +pub mod erc1155_proxy; + const PERCENTAGE_TOTAL: u8 = 100; #[derive(TopEncode, TopDecode, TypeAbi)] @@ -106,7 +108,10 @@ pub trait Erc1155Marketplace { let claimable_funds_mapper = self.get_claimable_funds_mapper(); for (token_identifier, amount) in claimable_funds_mapper.iter() { - self.send().direct(&caller, &token_identifier, 0, &amount); + self.tx() + .to(&caller) + .egld_or_single_esdt(&token_identifier, 0, &amount) + .transfer(); self.clear_claimable_funds(&token_identifier); } } @@ -176,12 +181,10 @@ pub trait Erc1155Marketplace { // refund losing bid if !auction.current_winner.is_zero() { - self.send().direct( - &auction.current_winner, - &auction.token_identifier, - 0, - &auction.current_bid, - ); + self.tx() + .to(&auction.current_winner) + .egld_or_single_esdt(&auction.token_identifier, 0, &auction.current_bid) + .transfer(); } // update auction bid and winner @@ -215,12 +218,10 @@ pub trait Erc1155Marketplace { self.add_claimable_funds(&auction.token_identifier, &cut_amount); // send part of the bid to the original owner - self.send().direct( - &auction.original_owner, - &auction.token_identifier, - 0, - &amount_to_send, - ); + self.tx() + .to(&auction.original_owner) + .egld_or_single_esdt(&auction.token_identifier, 0, &amount_to_send) + .transfer(); // send token to winner self.async_transfer_token(type_id, nft_id, auction.current_winner); @@ -310,10 +311,11 @@ pub trait Erc1155Marketplace { let sc_own_address = self.blockchain().get_sc_address(); let token_ownership_contract_address = self.token_ownership_contract_address().get(); - self.erc1155_proxy(token_ownership_contract_address) + self.tx() + .to(&token_ownership_contract_address) + .typed(erc1155_proxy::Erc1155Proxy) .safe_transfer_from(sc_own_address, to, type_id, nft_id, &[]) - .async_call() - .call_and_exit() + .async_call_and_exit(); } fn calculate_cut_amount(&self, total_amount: &BigUint, cut_percentage: u8) -> BigUint { @@ -332,11 +334,6 @@ pub trait Erc1155Marketplace { mapper.insert(token_identifier.clone(), BigUint::zero()); } - // proxy - - #[proxy] - fn erc1155_proxy(&self, to: ManagedAddress) -> erc1155::Proxy; - // storage // token ownership contract, i.e. the erc1155 SC diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/Cargo.lock b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/Cargo.lock index e1d897e85b..b20203f2dd 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -63,26 +63,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -92,7 +94,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -103,7 +105,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/Cargo.toml index bd55b29f36..f2b91359bc 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.erc1155-marketplace] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/src/lib.rs b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/src/lib.rs index 442a245237..4cb87cbdfd 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/src/lib.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 14 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/Cargo.toml index e538bc4de9..314a2f79dc 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/Cargo.toml @@ -9,10 +9,10 @@ publish = false path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/meta/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/meta/Cargo.toml index 5608c548a3..e8345c1a8e 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.erc1155-user-mock] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/meta/src/main.rs b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/meta/src/main.rs index f9c3fdd3e9..6a3462a756 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/meta/src/main.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/Cargo.lock b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/Cargo.lock index 89b2e55240..238df48aea 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/Cargo.toml index fcb4237512..b1b50c674d 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.erc1155-user-mock] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/src/lib.rs b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/src/lib.rs index f3281811d5..a0c2470012 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/src/lib.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155-user-mock/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc1155/Cargo.toml index c39f7d5f16..59c8698391 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155/Cargo.toml @@ -9,12 +9,12 @@ publish = false path = "src/erc1155.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" [dev-dependencies.erc1155-user-mock] diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/meta/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc1155/meta/Cargo.toml index 1815a7f706..f92997ff1b 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.erc1155] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/meta/src/main.rs b/contracts/feature-tests/erc-style-contracts/erc1155/meta/src/main.rs index 9a4730217a..4aef7a714c 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/meta/src/main.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/sc-config.toml b/contracts/feature-tests/erc-style-contracts/erc1155/sc-config.toml index 9d5da94a85..41ca1e2eee 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/sc-config.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155/sc-config.toml @@ -1,6 +1,9 @@ [settings] main = "erc1155" +[[proxy]] +path = "../erc1155-marketplace/src/erc1155_proxy.rs" + # the only purpose of this config is to specify the allocator [contracts.erc1155] add-unlabelled = true diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155.rs b/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155.rs index 9fb1fb5216..725cff90de 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155.rs @@ -350,16 +350,17 @@ pub trait Erc1155 { ) { let caller = self.blockchain().get_caller(); - self.erc1155_user_proxy(to.clone()) + self.tx() + .to(to.clone()) + .typed(erc1155_user_proxy::Erc1155UserProxy) .on_erc1155_received(caller, from.clone(), type_id.clone(), value.clone(), data) - .async_call() - .with_callback(self.callbacks().transfer_callback( + .callback(self.callbacks().transfer_callback( from, to, [type_id].to_vec(), [value].to_vec(), )) - .call_and_exit() + .async_call_and_exit(); } fn peform_async_call_batch_transfer( @@ -372,7 +373,9 @@ pub trait Erc1155 { ) { let caller = self.blockchain().get_caller(); - self.erc1155_user_proxy(to.clone()) + self.tx() + .to(to.clone()) + .typed(erc1155_user_proxy::Erc1155UserProxy) .on_erc1155_batch_received( caller, from.clone(), @@ -380,14 +383,13 @@ pub trait Erc1155 { values.to_vec(), data, ) - .async_call() - .with_callback(self.callbacks().transfer_callback( + .callback(self.callbacks().transfer_callback( from, to, type_ids.to_vec(), values.to_vec(), )) - .call_and_exit() + .async_call_and_exit(); } // callbacks @@ -418,14 +420,6 @@ pub trait Erc1155 { } } - // proxy - - #[proxy] - fn erc1155_user_proxy( - &self, - sc_address: ManagedAddress, - ) -> erc1155_user_proxy::Proxy; - // storage // map for address -> type_id -> amount diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155_user_proxy.rs b/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155_user_proxy.rs index 5c645bf4be..13c0fce3b6 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155_user_proxy.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155_user_proxy.rs @@ -1,24 +1,87 @@ -multiversx_sc::imports!(); +#![allow(clippy::all)] -#[multiversx_sc::proxy] -pub trait Erc1155UserProxy { - #[endpoint(onERC1155Received)] - fn on_erc1155_received( - &self, - operator: ManagedAddress, - from: ManagedAddress, - type_id: BigUint, - value: BigUint, - data: ManagedBuffer, - ); +use multiversx_sc::proxy_imports::*; - #[endpoint(onERC1155BatchReceived)] - fn on_erc1155_batch_received( - &self, - operator: ManagedAddress, - from: ManagedAddress, - type_ids: Vec, - values: Vec, - data: ManagedBuffer, - ); +pub struct Erc1155UserProxy; + +impl TxProxyTrait for Erc1155UserProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = Erc1155UserProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + Erc1155UserProxyMethods { wrapped_tx: tx } + } +} + +pub struct Erc1155UserProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl Erc1155UserProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn on_erc1155_received< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + >( + self, + operator: Arg0, + from: Arg1, + type_id: Arg2, + value: Arg3, + data: Arg4, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("onERC1155Received") + .argument(&operator) + .argument(&from) + .argument(&type_id) + .argument(&value) + .argument(&data) + .original_result() + } + + pub fn on_erc1155_batch_received< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>>, + Arg3: ProxyArg>>, + Arg4: ProxyArg>, + >( + self, + operator: Arg0, + from: Arg1, + type_ids: Arg2, + values: Arg3, + data: Arg4, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("onERC1155BatchReceived") + .argument(&operator) + .argument(&from) + .argument(&type_ids) + .argument(&values) + .argument(&data) + .original_result() + } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.lock b/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.lock index edcb0e4176..fb6988c95a 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.toml index e964700ec5..e2e1a7b1d9 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.erc1155] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/wasm/src/lib.rs b/contracts/feature-tests/erc-style-contracts/erc1155/wasm/src/lib.rs index 051c2d54fa..f3fcf7cd71 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/wasm/src/lib.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 15 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/erc-style-contracts/erc20/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc20/Cargo.toml index 20671838db..c41b75b3e8 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc20/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/erc20.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/erc-style-contracts/erc20/meta/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc20/meta/Cargo.toml index db4e5ff3df..4ad2d78743 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc20/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.erc20] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/erc-style-contracts/erc20/meta/src/main.rs b/contracts/feature-tests/erc-style-contracts/erc20/meta/src/main.rs index b4ccd80712..ffb251ea2f 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/meta/src/main.rs +++ b/contracts/feature-tests/erc-style-contracts/erc20/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/sc-config.toml b/contracts/feature-tests/erc-style-contracts/erc20/sc-config.toml new file mode 100644 index 0000000000..68aff47cba --- /dev/null +++ b/contracts/feature-tests/erc-style-contracts/erc20/sc-config.toml @@ -0,0 +1,7 @@ +[settings] + +[[proxy]] +path = "../crowdfunding-erc20/src/erc20_proxy.rs" + +[[proxy]] +path = "../lottery-erc20/src/erc20_proxy.rs" diff --git a/contracts/feature-tests/erc-style-contracts/erc20/tests/erc20_scenario_rs_test.rs b/contracts/feature-tests/erc-style-contracts/erc20/tests/erc20_scenario_rs_test.rs index eb68d00d2e..bf8da38747 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/tests/erc20_scenario_rs_test.rs +++ b/contracts/feature-tests/erc-style-contracts/erc20/tests/erc20_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/erc-style-contracts/erc20"); blockchain.register_contract("mxsc:output/erc20.mxsc.json", erc20::ContractBuilder); blockchain diff --git a/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.lock b/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.lock index 4833835c10..93df2a8f3b 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.toml index 59d6c7a7b8..de00855ee5 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.erc20] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/erc-style-contracts/erc20/wasm/src/lib.rs b/contracts/feature-tests/erc-style-contracts/erc20/wasm/src/lib.rs index 22fe14729a..0a3607ddc0 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/wasm/src/lib.rs +++ b/contracts/feature-tests/erc-style-contracts/erc20/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 8 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/erc-style-contracts/erc721/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc721/Cargo.toml index 8372f0354a..62e8bf18f1 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc721/Cargo.toml @@ -10,9 +10,9 @@ path = "src/erc721.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/erc-style-contracts/erc721/meta/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc721/meta/Cargo.toml index 96afb07b44..9b0c62afd2 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc721/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.erc721] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/erc-style-contracts/erc721/meta/src/main.rs b/contracts/feature-tests/erc-style-contracts/erc721/meta/src/main.rs index c505661fd6..f1df8f2beb 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/meta/src/main.rs +++ b/contracts/feature-tests/erc-style-contracts/erc721/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.lock b/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.lock index 7b5004e949..42158fbfd7 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.toml b/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.toml index a80419dcab..4ee3302598 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.erc721] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/erc-style-contracts/erc721/wasm/src/lib.rs b/contracts/feature-tests/erc-style-contracts/erc721/wasm/src/lib.rs index 1f97c9968b..4adcd25ca0 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/wasm/src/lib.rs +++ b/contracts/feature-tests/erc-style-contracts/erc721/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 10 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/Cargo.toml b/contracts/feature-tests/erc-style-contracts/lottery-erc20/Cargo.toml index 46ffb3c5ea..eb84590bb5 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/Cargo.toml @@ -12,10 +12,10 @@ path = "src/lottery.rs" path = "../erc20" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/meta/Cargo.toml b/contracts/feature-tests/erc-style-contracts/lottery-erc20/meta/Cargo.toml index ce2495310a..7a481725a7 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.lottery-erc20] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/meta/src/main.rs b/contracts/feature-tests/erc-style-contracts/lottery-erc20/meta/src/main.rs index 1fc258fb1f..601d8539ba 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/meta/src/main.rs +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/src/erc20_proxy.rs b/contracts/feature-tests/erc-style-contracts/lottery-erc20/src/erc20_proxy.rs new file mode 100644 index 0000000000..cda5046b56 --- /dev/null +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/src/erc20_proxy.rs @@ -0,0 +1,195 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct SimpleErc20TokenProxy; + +impl TxProxyTrait for SimpleErc20TokenProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = SimpleErc20TokenProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + SimpleErc20TokenProxyMethods { wrapped_tx: tx } + } +} + +pub struct SimpleErc20TokenProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl SimpleErc20TokenProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + /// Constructor, is called immediately after the contract is created + /// Will set the fixed global token supply and give all the supply to the creator. + pub fn init< + Arg0: ProxyArg>, + >( + self, + total_supply: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&total_supply) + .original_result() + } +} + +#[rustfmt::skip] +impl SimpleErc20TokenProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + /// Total number of tokens in existence. + pub fn total_supply( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("totalSupply") + .original_result() + } + + /// Gets the balance of the specified address. + /// + /// Arguments: + /// + /// * `address` The address to query the the balance of + /// + pub fn token_balance< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("balanceOf") + .argument(&address) + .original_result() + } + + /// The amount of tokens that an owner allowed to a spender. + /// + /// Arguments: + /// + /// * `owner` The address that owns the funds. + /// * `spender` The address that will spend the funds. + /// + pub fn allowance< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + owner: Arg0, + spender: Arg1, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("allowance") + .argument(&owner) + .argument(&spender) + .original_result() + } + + /// Transfer token to a specified address from sender. + /// + /// Arguments: + /// + /// * `to` The address to transfer to. + /// + pub fn transfer< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + to: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transfer") + .argument(&to) + .argument(&amount) + .original_result() + } + + /// Use allowance to transfer funds between two accounts. + /// + /// Arguments: + /// + /// * `sender` The address to transfer from. + /// * `recipient` The address to transfer to. + /// * `amount` the amount of tokens to be transferred. + /// + pub fn transfer_from< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + sender: Arg0, + recipient: Arg1, + amount: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transferFrom") + .argument(&sender) + .argument(&recipient) + .argument(&amount) + .original_result() + } + + /// Approve the given address to spend the specified amount of tokens on behalf of the sender. + /// It overwrites any previously existing allowance from sender to beneficiary. + /// + /// Arguments: + /// + /// * `spender` The address that will spend the funds. + /// * `amount` The amount of tokens to be spent. + /// + pub fn approve< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + spender: Arg0, + amount: Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("approve") + .argument(&spender) + .argument(&amount) + .original_result() + } +} diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/src/lottery.rs b/contracts/feature-tests/erc-style-contracts/lottery-erc20/src/lottery.rs index 318563e703..1bbd1f7370 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/src/lottery.rs +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/src/lottery.rs @@ -2,6 +2,7 @@ multiversx_sc::imports!(); +mod erc20_proxy; mod lottery_info; mod random; mod status; @@ -15,9 +16,6 @@ const THIRTY_DAYS_IN_SECONDS: u64 = 60 * 60 * 24 * 30; #[multiversx_sc::contract] pub trait Lottery { - #[proxy] - fn erc20_proxy(&self, to: ManagedAddress) -> erc20::Proxy; - #[init] fn init(&self, erc20_contract_address: ManagedAddress) { self.set_erc20_contract_address(&erc20_contract_address); @@ -212,14 +210,15 @@ pub trait Lottery { let erc20_address = self.get_erc20_contract_address(); let lottery_contract_address = self.blockchain().get_sc_address(); - self.erc20_proxy(erc20_address) + self.tx() + .to(&erc20_address) + .typed(erc20_proxy::SimpleErc20TokenProxy) .transfer_from(caller.clone(), lottery_contract_address, token_amount) - .async_call() - .with_callback( + .callback( self.callbacks() .transfer_from_callback(lottery_name, &caller), ) - .call_and_exit() + .async_call_and_exit(); } fn reserve_ticket(&self, lottery_name: &BoxedBytes) { @@ -282,11 +281,12 @@ pub trait Lottery { let erc20_address = self.get_erc20_contract_address(); - self.erc20_proxy(erc20_address) + self.tx() + .to(&erc20_address) + .typed(erc20_proxy::SimpleErc20TokenProxy) .transfer(winner_address, prize) - .async_call() - .with_callback(self.callbacks().distribute_prizes_callback(lottery_name)) - .call_and_exit() + .callback(self.callbacks().distribute_prizes_callback(lottery_name)) + .async_call_and_exit(); } fn get_random_winning_ticket_id(&self, prev_winners: &[u32], total_tickets: u32) -> u32 { diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/tests/lottery_erc20_scenario_rs_test.rs b/contracts/feature-tests/erc-style-contracts/lottery-erc20/tests/lottery_erc20_scenario_rs_test.rs index ed82fb71bb..fa03693cce 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/tests/lottery_erc20_scenario_rs_test.rs +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/tests/lottery_erc20_scenario_rs_test.rs @@ -2,10 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace( - "contracts/feature-tests/erc-style-contracts/lottery-erc20", - ); - blockchain.register_contract( "mxsc:output/lottery-erc20.mxsc.json", lottery_erc20::ContractBuilder, diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/Cargo.lock b/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/Cargo.lock index 2d821b9e29..93af02f7fe 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -63,26 +63,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -92,7 +94,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -103,7 +105,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -119,27 +121,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -156,15 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -176,3 +178,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/Cargo.toml b/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/Cargo.toml index 9338d5fd10..3e7112f299 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.lottery-erc20] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/src/lib.rs b/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/src/lib.rs index ff416cf4b9..b247fc3493 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/src/lib.rs +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 9 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/esdt-system-sc-mock/Cargo.toml b/contracts/feature-tests/esdt-system-sc-mock/Cargo.toml index 134d30ce63..ca7c0ab46f 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/Cargo.toml +++ b/contracts/feature-tests/esdt-system-sc-mock/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/esdt_system_sc_mock.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/feature-tests/esdt-system-sc-mock/meta/Cargo.toml b/contracts/feature-tests/esdt-system-sc-mock/meta/Cargo.toml index e316dac5ad..3b87777102 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/meta/Cargo.toml +++ b/contracts/feature-tests/esdt-system-sc-mock/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.esdt-system-sc-mock] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/esdt-system-sc-mock/meta/src/main.rs b/contracts/feature-tests/esdt-system-sc-mock/meta/src/main.rs index b0eb252a66..d2101a5771 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/meta/src/main.rs +++ b/contracts/feature-tests/esdt-system-sc-mock/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/esdt-system-sc-mock/tests/esdt_system_sc_mock_scenario_rs_test.rs b/contracts/feature-tests/esdt-system-sc-mock/tests/esdt_system_sc_mock_scenario_rs_test.rs index c0809e7b40..eca4daa6cb 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/tests/esdt_system_sc_mock_scenario_rs_test.rs +++ b/contracts/feature-tests/esdt-system-sc-mock/tests/esdt_system_sc_mock_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/esdt-system-sc-mock"); blockchain.register_contract( "mxsc:output/esdt-system-sc-mock.mxsc.json", diff --git a/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.lock b/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.lock index d789558af3..c5ffbccbff 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.lock +++ b/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.toml b/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.toml index 656e98c8d1..8a315ab804 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.toml +++ b/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.esdt-system-sc-mock] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/esdt-system-sc-mock/wasm/src/lib.rs b/contracts/feature-tests/esdt-system-sc-mock/wasm/src/lib.rs index 24e6d08cd1..8301d8cf9c 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/wasm/src/lib.rs +++ b/contracts/feature-tests/esdt-system-sc-mock/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 8 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/exchange-features/Cargo.toml b/contracts/feature-tests/exchange-features/Cargo.toml new file mode 100644 index 0000000000..0bf9de1dfd --- /dev/null +++ b/contracts/feature-tests/exchange-features/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "exchange-features" +version = "0.0.0" +authors = ["Alin-Marius Cruceat "] +edition = "2021" +publish = false + +[lib] +path = "src/exchange_features.rs" + +[dependencies.multiversx-sc] +version = "0.50.3" +path = "../../../framework/base" + +[dev-dependencies.multiversx-sc-scenario] +version = "0.50.3" +path = "../../../framework/scenario" diff --git a/contracts/feature-tests/exchange-features/meta/Cargo.toml b/contracts/feature-tests/exchange-features/meta/Cargo.toml new file mode 100644 index 0000000000..5030eb66dd --- /dev/null +++ b/contracts/feature-tests/exchange-features/meta/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "exchange-features-meta" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies.exchange-features] +path = ".." + +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" +default-features = false diff --git a/contracts/feature-tests/exchange-features/meta/src/main.rs b/contracts/feature-tests/exchange-features/meta/src/main.rs new file mode 100644 index 0000000000..219a7e34af --- /dev/null +++ b/contracts/feature-tests/exchange-features/meta/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + multiversx_sc_meta_lib::cli_main::(); +} diff --git a/contracts/feature-tests/exchange-features/multiversx.json b/contracts/feature-tests/exchange-features/multiversx.json new file mode 100644 index 0000000000..7365539625 --- /dev/null +++ b/contracts/feature-tests/exchange-features/multiversx.json @@ -0,0 +1,3 @@ +{ + "language": "rust" +} \ No newline at end of file diff --git a/contracts/feature-tests/exchange-features/src/exchange_features.rs b/contracts/feature-tests/exchange-features/src/exchange_features.rs new file mode 100644 index 0000000000..fd048e72c8 --- /dev/null +++ b/contracts/feature-tests/exchange-features/src/exchange_features.rs @@ -0,0 +1,72 @@ +#![no_std] + +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +#[derive( + ManagedVecItem, + TopEncode, + TopDecode, + NestedEncode, + NestedDecode, + TypeAbi, + Clone, + PartialEq, + Debug, +)] +pub struct TokenAttributes { + pub amount: BigUint, +} + +impl FixedSupplyToken for TokenAttributes { + fn get_total_supply(&self) -> BigUint { + self.amount.clone() + } + + fn into_part(self, payment_amount: &BigUint) -> Self { + let new_amount = self.rule_of_three_non_zero_result(payment_amount, &self.amount); + TokenAttributes { amount: new_amount } + } +} +impl Mergeable for TokenAttributes { + #[inline] + fn can_merge_with(&self, _other: &Self) -> bool { + true + } + + fn merge_with(&mut self, other: Self) { + self.error_if_not_mergeable(&other); + + self.amount += other.amount + } +} + +#[multiversx_sc::contract] +pub trait ExchangeFeatures { + #[storage_mapper("supply")] + fn supply(&self) -> SingleValueMapper>; + + #[init] + fn init(&self, initial_value: BigUint) { + self.supply().set(TokenAttributes { + amount: initial_value, + }); + } + + #[upgrade] + fn upgrade(&self, value: BigUint) { + let token = self.supply().get(); + self.supply().set(token.into_part(&value)); + } + + #[endpoint] + fn merge(&self, value: BigUint) { + self.supply() + .update(|token| token.merge_with(TokenAttributes { amount: value })); + } + + #[endpoint] + fn get_supply(&self) -> BigUint { + self.supply().get().get_total_supply() + } +} diff --git a/contracts/feature-tests/exchange-features/tests/exchange_features_blackbox_test.rs b/contracts/feature-tests/exchange-features/tests/exchange_features_blackbox_test.rs new file mode 100644 index 0000000000..ebf5b99b63 --- /dev/null +++ b/contracts/feature-tests/exchange-features/tests/exchange_features_blackbox_test.rs @@ -0,0 +1,82 @@ +use multiversx_sc_scenario::imports::*; + +const EXCHANGE_FEATURES_PATH_EXPR: &str = "mxsc:output/exchange-features.mxsc.json"; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + EXCHANGE_FEATURES_PATH_EXPR, + exchange_features::ContractBuilder, + ); + blockchain +} + +#[test] +fn exchange_features_blackbox_raw() { + let mut world = world(); + let exchange_features_code = world.code_expression(EXCHANGE_FEATURES_PATH_EXPR); + + world + .set_state_step( + SetStateStep::new() + .put_account("address:owner", Account::new().nonce(1)) + .new_address("address:owner", 1, "sc:exchange-features"), + ) + .sc_deploy( + ScDeployStep::new() + .from("address:owner") + .code(&exchange_features_code) + .argument("5") + .expect(TxExpect::ok().no_result()), + ) + .sc_call( + ScCallStep::new() + .from("address:owner") + .to("sc:exchange-features") + .function("get_supply") + .expect(TxExpect::ok().result("5")), + ) + .sc_call( + ScCallStep::new() + .from("address:owner") + .to("sc:exchange-features") + .function("merge") + .argument("3") + .expect(TxExpect::ok().no_result()), + ) + .sc_call( + ScCallStep::new() + .from("address:owner") + .to("sc:exchange-features") + .function("get_supply") + .expect(TxExpect::ok().result("8")), + ) + .sc_call( + ScCallStep::new() + .from("address:owner") + .to("sc:exchange-features") + .function("upgradeContract") + .argument(&exchange_features_code) + .argument("0x0502") // codeMetadata + .argument("0") // contract argument + .expect(TxExpect::user_error("str:Zero amount")), + ) + .sc_call( + ScCallStep::new() + .from("address:owner") + .to("sc:exchange-features") + .function("upgradeContract") + .argument(exchange_features_code) + .argument("0x0502") // codeMetadata + .argument("3") // contract argument + .expect(TxExpect::ok().no_result()), + ) + .sc_call( + ScCallStep::new() + .from("address:owner") + .to("sc:exchange-features") + .function("get_supply") + .expect(TxExpect::ok().result("3")), + ); +} diff --git a/contracts/feature-tests/exchange-features/wasm/Cargo.lock b/contracts/feature-tests/exchange-features/wasm/Cargo.lock new file mode 100644 index 0000000000..6e84158ba7 --- /dev/null +++ b/contracts/feature-tests/exchange-features/wasm/Cargo.lock @@ -0,0 +1,178 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "exchange-features" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "exchange-features-wasm" +version = "0.0.0" +dependencies = [ + "exchange-features", + "multiversx-sc-wasm-adapter", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "multiversx-sc" +version = "0.50.3" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.19.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.19.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.50.3" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.50.3" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/exchange-features/wasm/Cargo.toml b/contracts/feature-tests/exchange-features/wasm/Cargo.toml new file mode 100644 index 0000000000..7b49749410 --- /dev/null +++ b/contracts/feature-tests/exchange-features/wasm/Cargo.toml @@ -0,0 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "exchange-features-wasm" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" + +[dependencies.exchange-features] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.50.3" +path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/feature-tests/exchange-features/wasm/src/lib.rs b/contracts/feature-tests/exchange-features/wasm/src/lib.rs new file mode 100644 index 0000000000..b420653525 --- /dev/null +++ b/contracts/feature-tests/exchange-features/wasm/src/lib.rs @@ -0,0 +1,28 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Upgrade: 1 +// Endpoints: 2 +// Async Callback (empty): 1 +// Total number of exported functions: 5 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + exchange_features + ( + init => init + upgrade => upgrade + merge => merge + get_supply => get_supply + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/contracts/feature-tests/formatted-message-features/Cargo.toml b/contracts/feature-tests/formatted-message-features/Cargo.toml index 49dcba60aa..0f8546be61 100644 --- a/contracts/feature-tests/formatted-message-features/Cargo.toml +++ b/contracts/feature-tests/formatted-message-features/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/formatted_message_features.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/feature-tests/formatted-message-features/meta/Cargo.toml b/contracts/feature-tests/formatted-message-features/meta/Cargo.toml index b440c8cf8d..2b0ad62a0a 100644 --- a/contracts/feature-tests/formatted-message-features/meta/Cargo.toml +++ b/contracts/feature-tests/formatted-message-features/meta/Cargo.toml @@ -3,14 +3,14 @@ name = "formatted-message-features-meta" version = "0.0.0" edition = "2021" publish = false -authors = [ "you",] +authors = ["you"] [dev-dependencies] [dependencies.formatted-message-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/formatted-message-features/meta/src/main.rs b/contracts/feature-tests/formatted-message-features/meta/src/main.rs index 57df6a016b..6d1a57c9a5 100644 --- a/contracts/feature-tests/formatted-message-features/meta/src/main.rs +++ b/contracts/feature-tests/formatted-message-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/formatted-message-features/tests/msg_scenario_rs_test.rs b/contracts/feature-tests/formatted-message-features/tests/msg_scenario_rs_test.rs index 929ddd5c7c..0844d716d7 100644 --- a/contracts/feature-tests/formatted-message-features/tests/msg_scenario_rs_test.rs +++ b/contracts/feature-tests/formatted-message-features/tests/msg_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/formatted-message-features"); blockchain.register_contract( "mxsc:output/formatted-message-features.mxsc.json", diff --git a/contracts/feature-tests/formatted-message-features/wasm/Cargo.lock b/contracts/feature-tests/formatted-message-features/wasm/Cargo.lock index b19830db13..4f02ecead6 100644 --- a/contracts/feature-tests/formatted-message-features/wasm/Cargo.lock +++ b/contracts/feature-tests/formatted-message-features/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/formatted-message-features/wasm/Cargo.toml b/contracts/feature-tests/formatted-message-features/wasm/Cargo.toml index 912900e134..b79ce4c245 100644 --- a/contracts/feature-tests/formatted-message-features/wasm/Cargo.toml +++ b/contracts/feature-tests/formatted-message-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.formatted-message-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/formatted-message-features/wasm/src/lib.rs b/contracts/feature-tests/formatted-message-features/wasm/src/lib.rs index 7a07a6ec82..34c6f81e59 100644 --- a/contracts/feature-tests/formatted-message-features/wasm/src/lib.rs +++ b/contracts/feature-tests/formatted-message-features/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 18 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/managed-map-features/Cargo.toml b/contracts/feature-tests/managed-map-features/Cargo.toml index 4e44c248df..f2fe3a1764 100644 --- a/contracts/feature-tests/managed-map-features/Cargo.toml +++ b/contracts/feature-tests/managed-map-features/Cargo.toml @@ -9,11 +9,11 @@ publish = false path = "src/mmap_features.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dev-dependencies.esdt-system-sc-mock] diff --git a/contracts/feature-tests/managed-map-features/meta/Cargo.toml b/contracts/feature-tests/managed-map-features/meta/Cargo.toml index fdb2ea7cc8..1588553538 100644 --- a/contracts/feature-tests/managed-map-features/meta/Cargo.toml +++ b/contracts/feature-tests/managed-map-features/meta/Cargo.toml @@ -4,10 +4,11 @@ version = "0.0.0" authors = ["Andrei Marinica "] edition = "2021" publish = false + [dependencies.managed-map-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/managed-map-features/meta/src/main.rs b/contracts/feature-tests/managed-map-features/meta/src/main.rs index 834c30e0d3..74b4c4ad85 100644 --- a/contracts/feature-tests/managed-map-features/meta/src/main.rs +++ b/contracts/feature-tests/managed-map-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/managed-map-features/tests/managed_map_scenario_rs_test.rs b/contracts/feature-tests/managed-map-features/tests/managed_map_scenario_rs_test.rs index 78defc0fcf..9981c49f93 100644 --- a/contracts/feature-tests/managed-map-features/tests/managed_map_scenario_rs_test.rs +++ b/contracts/feature-tests/managed-map-features/tests/managed_map_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/managed-map-features"); blockchain.register_contract( "mxsc:output/managed-map-features.mxsc.json", managed_map_features::ContractBuilder, diff --git a/contracts/feature-tests/managed-map-features/wasm/Cargo.lock b/contracts/feature-tests/managed-map-features/wasm/Cargo.lock index e8fa9edd3d..f7f3456541 100644 --- a/contracts/feature-tests/managed-map-features/wasm/Cargo.lock +++ b/contracts/feature-tests/managed-map-features/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/managed-map-features/wasm/Cargo.toml b/contracts/feature-tests/managed-map-features/wasm/Cargo.toml index c688388a91..1af7c7cfad 100644 --- a/contracts/feature-tests/managed-map-features/wasm/Cargo.toml +++ b/contracts/feature-tests/managed-map-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.managed-map-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/managed-map-features/wasm/src/lib.rs b/contracts/feature-tests/managed-map-features/wasm/src/lib.rs index 2f32f8bf49..943fc9cb9a 100644 --- a/contracts/feature-tests/managed-map-features/wasm/src/lib.rs +++ b/contracts/feature-tests/managed-map-features/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 5 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/multi-contract-features/Cargo.toml b/contracts/feature-tests/multi-contract-features/Cargo.toml index d4b5121141..0e4d48e950 100644 --- a/contracts/feature-tests/multi-contract-features/Cargo.toml +++ b/contracts/feature-tests/multi-contract-features/Cargo.toml @@ -12,9 +12,9 @@ path = "src/multi_contract_features.rs" example_feature = [] [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/feature-tests/multi-contract-features/meta/Cargo.toml b/contracts/feature-tests/multi-contract-features/meta/Cargo.toml index 053f902584..f07fcbd5ab 100644 --- a/contracts/feature-tests/multi-contract-features/meta/Cargo.toml +++ b/contracts/feature-tests/multi-contract-features/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.multi-contract-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/multi-contract-features/meta/src/main.rs b/contracts/feature-tests/multi-contract-features/meta/src/main.rs index 9099598c92..bab60b6eac 100644 --- a/contracts/feature-tests/multi-contract-features/meta/src/main.rs +++ b/contracts/feature-tests/multi-contract-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/multi-contract-features/multicontract.toml b/contracts/feature-tests/multi-contract-features/multicontract.toml index b6c3c8efb1..dd9eaa5add 100644 --- a/contracts/feature-tests/multi-contract-features/multicontract.toml +++ b/contracts/feature-tests/multi-contract-features/multicontract.toml @@ -17,7 +17,7 @@ features = [] [contracts.multi-contract-main.profile] # these are just the defaults, checking that parsing works fine -codegen-units = 1 +codegen-units = 1 opt-level = "z" lto = true debug = false @@ -31,9 +31,18 @@ add-unlabelled = false add-labels = ["mcs-external-view"] [contracts.multi-contract-example-feature] -add-unlabelled = true # optional here, since the default is true +add-unlabelled = true # optional here, since the default is true features = ["example_feature"] [contracts.multi-contract-alt-impl] add-unlabelled = false add-labels = ["alt-impl"] + +[[proxy]] +variant = "multi_contract_example_feature" +path = "src/multi_contract_example_feature_proxy.rs" + + +[[proxy]] +variant = "multi_contract_alt_impl" +path = "src/multi_contract_alt_impl_proxy.rs" diff --git a/contracts/feature-tests/multi-contract-features/src/multi_contract_alt_impl_proxy.rs b/contracts/feature-tests/multi-contract-features/src/multi_contract_alt_impl_proxy.rs new file mode 100644 index 0000000000..8a7b345766 --- /dev/null +++ b/contracts/feature-tests/multi-contract-features/src/multi_contract_alt_impl_proxy.rs @@ -0,0 +1,73 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct MultiContractFeaturesProxy; + +impl TxProxyTrait for MultiContractFeaturesProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = MultiContractFeaturesProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + MultiContractFeaturesProxyMethods { wrapped_tx: tx } + } +} + +pub struct MultiContractFeaturesProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl MultiContractFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn alternative_init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl MultiContractFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn alternative_sample_value( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("sample_value") + .original_result() + } +} diff --git a/contracts/feature-tests/multi-contract-features/src/multi_contract_example_feature_proxy.rs b/contracts/feature-tests/multi-contract-features/src/multi_contract_example_feature_proxy.rs new file mode 100644 index 0000000000..0f1dbdd125 --- /dev/null +++ b/contracts/feature-tests/multi-contract-features/src/multi_contract_example_feature_proxy.rs @@ -0,0 +1,86 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct MultiContractFeaturesProxy; + +impl TxProxyTrait for MultiContractFeaturesProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = MultiContractFeaturesProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + MultiContractFeaturesProxyMethods { wrapped_tx: tx } + } +} + +pub struct MultiContractFeaturesProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl MultiContractFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn default_init< + Arg0: ProxyArg>, + >( + self, + sample_value: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&sample_value) + .original_result() + } +} + +#[rustfmt::skip] +impl MultiContractFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn sample_value( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("sample_value") + .original_result() + } + + pub fn example_feature_message( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("example_feature_message") + .original_result() + } +} diff --git a/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_rs_test.rs b/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_rs_test.rs index 5c56c275d5..4c6b64db26 100644 --- a/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_rs_test.rs +++ b/contracts/feature-tests/multi-contract-features/tests/multi_contract_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/multi-contract-features"); blockchain.register_partial_contract::( "mxsc:output/multi-contract-features.mxsc.json", diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/Cargo.lock b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/Cargo.lock index 1361ebb7c7..677ad0bc84 100644 --- a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/Cargo.lock +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/Cargo.toml b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/Cargo.toml index d524d039f3..9903659f00 100644 --- a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/Cargo.toml +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.multi-contract-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/src/lib.rs b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/src/lib.rs index ba8838b6e4..3a496abdbe 100644 --- a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/src/lib.rs +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-alt-impl/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 3 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.lock b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.lock index 3928df2b36..b9b3b9e611 100644 --- a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.lock +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.toml b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.toml index 20839cea31..e49c0fedb8 100644 --- a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.toml +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/Cargo.toml @@ -21,12 +21,15 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.multi-contract-features] path = ".." features = ["example_feature"] [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/src/lib.rs b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/src/lib.rs index 655e83240c..9602c289bf 100644 --- a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/src/lib.rs +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-example-feature/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/Cargo.lock b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/Cargo.lock index db8878b7ad..ed037e3548 100644 --- a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/Cargo.lock +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/Cargo.toml b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/Cargo.toml index beca5b4d75..44eba572c2 100644 --- a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/Cargo.toml +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.multi-contract-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/src/lib.rs b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/src/lib.rs index 871bfb5bca..85b69baf08 100644 --- a/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/src/lib.rs +++ b/contracts/feature-tests/multi-contract-features/wasm-multi-contract-features-view/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 5 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/multi-contract-features/wasm/Cargo.lock b/contracts/feature-tests/multi-contract-features/wasm/Cargo.lock index a8b5526b05..f16535f78e 100755 --- a/contracts/feature-tests/multi-contract-features/wasm/Cargo.lock +++ b/contracts/feature-tests/multi-contract-features/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -55,26 +55,28 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -84,7 +86,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -95,7 +97,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -111,27 +113,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/multi-contract-features/wasm/Cargo.toml b/contracts/feature-tests/multi-contract-features/wasm/Cargo.toml index 190c9b1fb5..707671421d 100644 --- a/contracts/feature-tests/multi-contract-features/wasm/Cargo.toml +++ b/contracts/feature-tests/multi-contract-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.multi-contract-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs b/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs index 655e83240c..9602c289bf 100644 --- a/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs +++ b/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/panic-message-features/Cargo.toml b/contracts/feature-tests/panic-message-features/Cargo.toml index d76417a223..57a56fc096 100644 --- a/contracts/feature-tests/panic-message-features/Cargo.toml +++ b/contracts/feature-tests/panic-message-features/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/panic_features.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/feature-tests/panic-message-features/meta/Cargo.toml b/contracts/feature-tests/panic-message-features/meta/Cargo.toml index 921c4f2671..078df57fdd 100644 --- a/contracts/feature-tests/panic-message-features/meta/Cargo.toml +++ b/contracts/feature-tests/panic-message-features/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.panic-message-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/panic-message-features/meta/src/main.rs b/contracts/feature-tests/panic-message-features/meta/src/main.rs index d33e82f537..d2c236c216 100644 --- a/contracts/feature-tests/panic-message-features/meta/src/main.rs +++ b/contracts/feature-tests/panic-message-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/panic-message-features/sc-config.toml b/contracts/feature-tests/panic-message-features/sc-config.toml index fc05c90bba..a5d6671115 100644 --- a/contracts/feature-tests/panic-message-features/sc-config.toml +++ b/contracts/feature-tests/panic-message-features/sc-config.toml @@ -4,3 +4,6 @@ main = "main" [contracts.main] name = "panic-message-features" panic-message = true + +[[proxy]] +path = "tests/pmf_proxy.rs" diff --git a/contracts/feature-tests/panic-message-features/scenarios/error-message-after-log.txt b/contracts/feature-tests/panic-message-features/scenarios/error-message-after-log.txt new file mode 100644 index 0000000000..0902894d05 --- /dev/null +++ b/contracts/feature-tests/panic-message-features/scenarios/error-message-after-log.txt @@ -0,0 +1,2 @@ +panic occurred: panicked at panic_features.rs:22:9: +panic after log \ No newline at end of file diff --git a/contracts/feature-tests/panic-message-features/scenarios/error-message.txt b/contracts/feature-tests/panic-message-features/scenarios/error-message.txt new file mode 100644 index 0000000000..b161bad102 --- /dev/null +++ b/contracts/feature-tests/panic-message-features/scenarios/error-message.txt @@ -0,0 +1,2 @@ +panic occurred: panicked at panic_features.rs:15:9: +example panic message 123 \ No newline at end of file diff --git a/contracts/feature-tests/panic-message-features/scenarios/panic-after-log.scen.json b/contracts/feature-tests/panic-message-features/scenarios/panic-after-log.scen.json index c652454513..91e0efe2f9 100644 --- a/contracts/feature-tests/panic-message-features/scenarios/panic-after-log.scen.json +++ b/contracts/feature-tests/panic-message-features/scenarios/panic-after-log.scen.json @@ -30,7 +30,7 @@ "expect": { "out": [], "status": "0x04", - "message": "str:panic occurred: panic after log", + "message": "file:error-message-after-log.txt", "logs": [ { "address": "address:an_account", diff --git a/contracts/feature-tests/panic-message-features/scenarios/panic-message.scen.json b/contracts/feature-tests/panic-message-features/scenarios/panic-message.scen.json index 7852b73228..bc8ad34548 100644 --- a/contracts/feature-tests/panic-message-features/scenarios/panic-message.scen.json +++ b/contracts/feature-tests/panic-message-features/scenarios/panic-message.scen.json @@ -32,7 +32,7 @@ "expect": { "out": [], "status": "0x04", - "message": "str:panic occurred: example panic message 123", + "message": "file:error-message.txt", "logs": "*", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/panic-message-features/src/panic_features.rs b/contracts/feature-tests/panic-message-features/src/panic_features.rs index 4b4ed32258..a2726d2fea 100644 --- a/contracts/feature-tests/panic-message-features/src/panic_features.rs +++ b/contracts/feature-tests/panic-message-features/src/panic_features.rs @@ -24,4 +24,9 @@ pub trait PanicMessageFeatures { #[event("before-panic")] fn before_panic(&self); + + #[view] + fn sc_panic(&self) { + sc_panic!("sc_panic! test"); + } } diff --git a/contracts/feature-tests/panic-message-features/tests/pmf_blackbox_test.rs b/contracts/feature-tests/panic-message-features/tests/pmf_blackbox_test.rs new file mode 100644 index 0000000000..d0588455ba --- /dev/null +++ b/contracts/feature-tests/panic-message-features/tests/pmf_blackbox_test.rs @@ -0,0 +1,94 @@ +mod pmf_proxy; + +use multiversx_sc_scenario::imports::*; + +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const SC_PMF: TestSCAddress = TestSCAddress::new("pmf"); +const CODE_EXPR: &str = "mxsc:output/panic-message-features.mxsc.json"; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(CODE_EXPR, panic_message_features::ContractBuilder); + blockchain +} + +fn setup() -> ScenarioWorld { + let mut world = world(); + let code = world.code_expression(CODE_EXPR); + + world.set_state_step( + SetStateStep::new() + .put_account(OWNER_ADDRESS, Account::new().nonce(1)) + .put_account(SC_PMF, Account::new().code(code)), + ); + + world +} + +// TODO: move to basic-features a testing framework tester +#[test] +fn tx_returns_error_test() { + let mut world = setup(); + + let (status, message) = world + .tx() + .from(OWNER_ADDRESS) + .to(SC_PMF) + .typed(pmf_proxy::PanicMessageFeaturesProxy) + .sc_panic() + .returns(ReturnsStatus) + .returns(ReturnsMessage) + .run(); + + assert_eq!(status, 4); + assert_eq!(message, "sc_panic! test"); +} + +#[test] +fn query_returns_error_test() { + let mut world = setup(); + + let (status, message) = world + .query() + .to(SC_PMF) + .typed(pmf_proxy::PanicMessageFeaturesProxy) + .sc_panic() + .returns(ReturnsStatus) + .returns(ReturnsMessage) + .run(); + + assert_eq!(status, 4); + assert_eq!(message, "sc_panic! test"); +} + +#[test] +fn tx_expect_error_test() { + let mut world = setup(); + + world + .tx() + .from(OWNER_ADDRESS) + .to(SC_PMF) + .typed(pmf_proxy::PanicMessageFeaturesProxy) + .sc_panic() + .with_result(ExpectMessage("sc_panic! test")) + .with_result(ExpectError(4, "sc_panic! test")) + .with_result(ExpectStatus(4)) + .run(); +} + +#[test] +fn query_expect_error_test() { + let mut world = setup(); + + world + .query() + .to(SC_PMF) + .typed(pmf_proxy::PanicMessageFeaturesProxy) + .sc_panic() + .with_result(ExpectStatus(4)) + .with_result(ExpectMessage("sc_panic! test")) + .with_result(ExpectError(4, "sc_panic! test")) + .run(); +} diff --git a/contracts/feature-tests/panic-message-features/tests/pmf_proxy.rs b/contracts/feature-tests/panic-message-features/tests/pmf_proxy.rs new file mode 100644 index 0000000000..c8864f2d4b --- /dev/null +++ b/contracts/feature-tests/panic-message-features/tests/pmf_proxy.rs @@ -0,0 +1,96 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct PanicMessageFeaturesProxy; + +impl TxProxyTrait for PanicMessageFeaturesProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = PanicMessageFeaturesProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + PanicMessageFeaturesProxyMethods { wrapped_tx: tx } + } +} + +pub struct PanicMessageFeaturesProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl PanicMessageFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl PanicMessageFeaturesProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn panic_with_message< + Arg0: ProxyArg, + >( + self, + some_value: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("panicWithMessage") + .argument(&some_value) + .original_result() + } + + /// Logs do not get recorded in case of panic. + pub fn panic_after_log( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("panicAfterLog") + .original_result() + } + + pub fn sc_panic( + self, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("sc_panic") + .original_result() + } +} diff --git a/contracts/feature-tests/panic-message-features/tests/pmf_scenario_rs_test.rs b/contracts/feature-tests/panic-message-features/tests/pmf_scenario_rs_test.rs index 2f9355f0d1..3921b15f91 100644 --- a/contracts/feature-tests/panic-message-features/tests/pmf_scenario_rs_test.rs +++ b/contracts/feature-tests/panic-message-features/tests/pmf_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/panic-message-features"); blockchain.register_partial_contract::( "mxsc:output/panic-message-features.mxsc.json", @@ -19,6 +18,7 @@ fn panic_after_log_rs() { world().run("scenarios/panic-after-log.scen.json"); } +#[ignore = "PanicInfo currently not available, TODO: use std::panic::set_hook"] #[test] fn panic_message_rs() { world().run("scenarios/panic-message.scen.json"); diff --git a/contracts/feature-tests/panic-message-features/wasm/Cargo.lock b/contracts/feature-tests/panic-message-features/wasm/Cargo.lock index daee57efc3..6175f04a80 100755 --- a/contracts/feature-tests/panic-message-features/wasm/Cargo.lock +++ b/contracts/feature-tests/panic-message-features/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,9 +98,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -120,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/panic-message-features/wasm/Cargo.toml b/contracts/feature-tests/panic-message-features/wasm/Cargo.toml index b55981873c..c0637702a2 100644 --- a/contracts/feature-tests/panic-message-features/wasm/Cargo.toml +++ b/contracts/feature-tests/panic-message-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.panic-message-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/panic-message-features/wasm/src/lib.rs b/contracts/feature-tests/panic-message-features/wasm/src/lib.rs index 2a024b15d2..b42857cfc0 100644 --- a/contracts/feature-tests/panic-message-features/wasm/src/lib.rs +++ b/contracts/feature-tests/panic-message-features/wasm/src/lib.rs @@ -5,13 +5,11 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 2 +// Endpoints: 3 // Async Callback (empty): 1 -// Total number of exported functions: 4 +// Total number of exported functions: 5 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler_with_message!(); @@ -22,6 +20,7 @@ multiversx_sc_wasm_adapter::endpoints! { init => init panicWithMessage => panic_with_message panicAfterLog => panic_after_log + sc_panic => sc_panic ) } diff --git a/contracts/feature-tests/payable-features/Cargo.toml b/contracts/feature-tests/payable-features/Cargo.toml index acf93f21d7..4ff90d96c7 100644 --- a/contracts/feature-tests/payable-features/Cargo.toml +++ b/contracts/feature-tests/payable-features/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/payable_features.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/feature-tests/payable-features/meta/Cargo.toml b/contracts/feature-tests/payable-features/meta/Cargo.toml index 4fb0cc3a23..f217ac70ca 100644 --- a/contracts/feature-tests/payable-features/meta/Cargo.toml +++ b/contracts/feature-tests/payable-features/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.payable-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/payable-features/meta/src/main.rs b/contracts/feature-tests/payable-features/meta/src/main.rs index 8578cb4649..90d2949d9c 100644 --- a/contracts/feature-tests/payable-features/meta/src/main.rs +++ b/contracts/feature-tests/payable-features/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs b/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs index 6d86ebe77f..6096bbe339 100644 --- a/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_blackbox_test.rs @@ -1,10 +1,9 @@ -use multiversx_sc_scenario::{scenario_model::*, *}; +use multiversx_sc_scenario::imports::*; const PF_PATH_EXPR: &str = "mxsc:output/payable-features.mxsc.json"; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/payable-features"); blockchain.register_contract(PF_PATH_EXPR, payable_features::ContractBuilder); blockchain diff --git a/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs b/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs index 4e88c1cd75..bd2f75753b 100644 --- a/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs +++ b/contracts/feature-tests/payable-features/tests/payable_scenario_rs_test.rs @@ -2,7 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/payable-features"); blockchain.register_contract( "mxsc:output/payable-features.mxsc.json", payable_features::ContractBuilder, diff --git a/contracts/feature-tests/payable-features/wasm/Cargo.lock b/contracts/feature-tests/payable-features/wasm/Cargo.lock index 56c5e9e863..2d9af2cf8b 100755 --- a/contracts/feature-tests/payable-features/wasm/Cargo.lock +++ b/contracts/feature-tests/payable-features/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,9 +98,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -120,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/payable-features/wasm/Cargo.toml b/contracts/feature-tests/payable-features/wasm/Cargo.toml index 9e9d3c0cd2..4a0ab8c226 100644 --- a/contracts/feature-tests/payable-features/wasm/Cargo.toml +++ b/contracts/feature-tests/payable-features/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.payable-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/payable-features/wasm/src/lib.rs b/contracts/feature-tests/payable-features/wasm/src/lib.rs index 9614f000c0..41f085e638 100644 --- a/contracts/feature-tests/payable-features/wasm/src/lib.rs +++ b/contracts/feature-tests/payable-features/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 17 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/rust-snippets-generator-test/Cargo.toml b/contracts/feature-tests/rust-snippets-generator-test/Cargo.toml index 3fdc4d3e5b..ab4a00e191 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/Cargo.toml +++ b/contracts/feature-tests/rust-snippets-generator-test/Cargo.toml @@ -9,9 +9,9 @@ publish = false path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" diff --git a/contracts/feature-tests/rust-snippets-generator-test/interact-rs/Cargo.toml b/contracts/feature-tests/rust-snippets-generator-test/interact-rs/Cargo.toml index a942895412..342e1f9cf9 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/interact-rs/Cargo.toml +++ b/contracts/feature-tests/rust-snippets-generator-test/interact-rs/Cargo.toml @@ -13,7 +13,7 @@ path = "src/interactor_main.rs" path = ".." [dependencies.multiversx-sc-snippets] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/snippets" # [workspace] diff --git a/contracts/feature-tests/rust-snippets-generator-test/interact-rs/src/interactor_main.rs b/contracts/feature-tests/rust-snippets-generator-test/interact-rs/src/interactor_main.rs index e0999b7644..389c717f2c 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/interact-rs/src/interactor_main.rs +++ b/contracts/feature-tests/rust-snippets-generator-test/interact-rs/src/interactor_main.rs @@ -2,25 +2,12 @@ use rust_snippets_generator_test::{ProxyTrait as _, *}; -use multiversx_sc_snippets::{ - env_logger, - erdrs::wallet::Wallet, - multiversx_sc::{codec::multi_types::*, types::*}, - multiversx_sc_scenario::{ - api::StaticApi, - bech32, - scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext}, - scenario_model::*, - ContractInfo, - }, - sdk, tokio, Interactor, -}; +use multiversx_sc_snippets::imports::*; const GATEWAY: &str = sdk::blockchain::DEVNET_GATEWAY; const PEM: &str = "alice.pem"; const SC_ADDRESS: &str = ""; -const SYSTEM_SC_BECH32: &str = "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"; const DEFAULT_ADDRESS_EXPR: &str = "0x0000000000000000000000000000000000000000000000000000000000000000"; const TOKEN_ISSUE_COST: u64 = 50_000_000_000_000_000; diff --git a/contracts/feature-tests/rust-snippets-generator-test/meta/Cargo.toml b/contracts/feature-tests/rust-snippets-generator-test/meta/Cargo.toml index 851caad934..75924880e2 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/meta/Cargo.toml +++ b/contracts/feature-tests/rust-snippets-generator-test/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.rust-snippets-generator-test] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/rust-snippets-generator-test/meta/src/main.rs b/contracts/feature-tests/rust-snippets-generator-test/meta/src/main.rs index b88a881acd..72d75ec315 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/meta/src/main.rs +++ b/contracts/feature-tests/rust-snippets-generator-test/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/rust-snippets-generator-test/src/lib.rs b/contracts/feature-tests/rust-snippets-generator-test/src/lib.rs index 711deb667e..bc52826ecd 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/src/lib.rs +++ b/contracts/feature-tests/rust-snippets-generator-test/src/lib.rs @@ -13,7 +13,7 @@ multiversx_sc::derive_imports!(); // Additionally, we also have to update the interact-rs snippets manually to add relative paths: // [dependencies.multiversx-sc-snippets] -// version = "0.47.5" +// version = "0.50.3" // path = "../../../../framework/snippets" #[derive( diff --git a/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.lock b/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.lock index 1f0efa51a3..98d93dea6f 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.lock +++ b/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.toml b/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.toml index 23f7a37d4d..20df548937 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.toml +++ b/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.rust-snippets-generator-test] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/rust-snippets-generator-test/wasm/src/lib.rs b/contracts/feature-tests/rust-snippets-generator-test/wasm/src/lib.rs index d4405d49e8..c0432d8a8f 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/wasm/src/lib.rs +++ b/contracts/feature-tests/rust-snippets-generator-test/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 18 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/rust-testing-framework-tester/Cargo.toml b/contracts/feature-tests/rust-testing-framework-tester/Cargo.toml index 2a5bd51b12..c5ccf87a73 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/Cargo.toml +++ b/contracts/feature-tests/rust-testing-framework-tester/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" publish = false [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" features = [ "alloc" ] @@ -17,7 +17,7 @@ path = "../../examples/adder" path = "../../feature-tests/basic-features" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" [dev-dependencies] diff --git a/contracts/feature-tests/rust-testing-framework-tester/meta/Cargo.toml b/contracts/feature-tests/rust-testing-framework-tester/meta/Cargo.toml index a378195cc9..dde0f6c158 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/meta/Cargo.toml +++ b/contracts/feature-tests/rust-testing-framework-tester/meta/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies.rust-testing-framework-tester] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/rust-testing-framework-tester/meta/src/main.rs b/contracts/feature-tests/rust-testing-framework-tester/meta/src/main.rs index b8ac69bf18..57ced27087 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/meta/src/main.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs index 010f002e6a..4133f3f039 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs @@ -62,14 +62,8 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[payable("EGLD")] #[endpoint] fn recieve_egld_half(&self) { - let caller = self.blockchain().get_caller(); let payment_amount = &*self.call_value().egld_value() / 2u32; - self.send().direct( - &caller, - &EgldOrEsdtTokenIdentifier::egld(), - 0, - &payment_amount, - ); + self.tx().to(ToCaller).egld(payment_amount).transfer(); } #[payable("*")] @@ -88,12 +82,13 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[payable("*")] #[endpoint] fn receive_esdt_half(&self) { - let caller = self.blockchain().get_caller(); let payment = self.call_value().single_esdt(); let amount = payment.amount / 2u32; - self.send() - .direct_esdt(&caller, &payment.token_identifier, 0, &amount); + self.tx() + .to(ToCaller) + .single_esdt(&payment.token_identifier, 0, &amount) + .transfer(); } #[payable("*")] @@ -111,7 +106,10 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { nft_nonce: u64, amount: BigUint, ) { - self.send().direct_esdt(&to, &token_id, nft_nonce, &amount); + self.tx() + .to(&to) + .single_esdt(&token_id, nft_nonce, &amount) + .transfer(); } #[endpoint] @@ -172,13 +170,14 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[endpoint] fn call_other_contract_execute_on_dest(&self, other_sc_address: ManagedAddress) -> BigUint { - let call_result = self.send_raw().execute_on_dest_context_raw( - self.blockchain().get_gas_left(), - &other_sc_address, - &BigUint::zero(), - &ManagedBuffer::new_from_bytes(b"getTotalValue"), - &ManagedArgBuffer::new(), - ); + let gas_left = self.blockchain().get_gas_left(); + let call_result = self + .tx() + .to(&other_sc_address) + .gas(gas_left) + .raw_call("getTotalValue") + .returns(ReturnsRawResult) + .sync_call(); if let Some(raw_value) = call_result.try_get(0) { BigUint::from_bytes_be_buffer(&raw_value) } else { @@ -188,15 +187,11 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[endpoint] fn call_other_contract_add_async_call(&self, other_sc_address: ManagedAddress, value: BigUint) { - let mut args = ManagedArgBuffer::new(); - args.push_arg(&value); - - self.send_raw().async_call_raw( - &other_sc_address, - &BigUint::zero(), - &ManagedBuffer::new_from_bytes(b"add"), - &args, - ); + self.tx() + .to(&other_sc_address) + .raw_call("add") + .argument(&value) + .async_call_and_exit(); } #[callback_raw] @@ -211,16 +206,13 @@ pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[endpoint] fn execute_on_dest_add_value(&self, other_sc_address: ManagedAddress, value: BigUint) { - let mut args = ManagedArgBuffer::new(); - args.push_arg(value); - - let _ = self.send_raw().execute_on_dest_context_raw( - self.blockchain().get_gas_left(), - &other_sc_address, - &BigUint::zero(), - &ManagedBuffer::new_from_bytes(b"addValue"), - &args, - ); + let gas_left = self.blockchain().get_gas_left(); + self.tx() + .to(&other_sc_address) + .gas(gas_left) + .raw_call("addValue") + .argument(&value) + .sync_call(); } #[endpoint(addValue)] diff --git a/contracts/feature-tests/rust-testing-framework-tester/tests/rust_testing_framework_tester_scenario_rs_test.rs b/contracts/feature-tests/rust-testing-framework-tester/tests/rust_testing_framework_tester_scenario_rs_test.rs index 18aac012c7..40aaa7f4fe 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/tests/rust_testing_framework_tester_scenario_rs_test.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/tests/rust_testing_framework_tester_scenario_rs_test.rs @@ -2,9 +2,6 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain - .set_current_dir_from_workspace("contracts/feature-tests/rust-testing-framework-tester"); - blockchain.register_contract( "file:output/rust-testing-framework-tester.wasm", rust_testing_framework_tester::ContractBuilder, diff --git a/contracts/feature-tests/rust-testing-framework-tester/tests/tester_blackbox_test.rs b/contracts/feature-tests/rust-testing-framework-tester/tests/tester_blackbox_test.rs index d544af3a04..afdabb5199 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/tests/tester_blackbox_test.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/tests/tester_blackbox_test.rs @@ -1,13 +1,10 @@ -use multiversx_sc_scenario::{api::StaticApi, scenario_model::*, *}; -use rust_testing_framework_tester::*; // TODO: clean up imports +use multiversx_sc_scenario::imports::*; +use rust_testing_framework_tester::*; const WASM_PATH_EXPR: &str = "mxsc:output/rust-testing-framework-tester.mxsc.json"; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain - .set_current_dir_from_workspace("contracts/feature_tests/rust-testing-framework-tester"); - blockchain.register_contract( WASM_PATH_EXPR, rust_testing_framework_tester::ContractBuilder, @@ -16,6 +13,7 @@ fn world() -> ScenarioWorld { } #[test] +#[allow(deprecated)] fn tester_deploy_test() { let mut world = world(); let code = world.code_expression(WASM_PATH_EXPR); @@ -45,6 +43,7 @@ fn tester_deploy_test() { } #[test] +#[allow(deprecated)] fn tester_deploy_test_spawned_thread() { let handler = std::thread::spawn(|| { let mut world = world(); diff --git a/contracts/feature-tests/rust-testing-framework-tester/tests/tester_whitebox_legacy_test.rs b/contracts/feature-tests/rust-testing-framework-tester/tests/tester_whitebox_legacy_test.rs index 1f56f5bb21..3ca8162259 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/tests/tester_whitebox_legacy_test.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/tests/tester_whitebox_legacy_test.rs @@ -1,20 +1,9 @@ -#![allow(deprecated)] // TODO: migrate tests - -use adder::*; -use forwarder::call_sync::*; +use multiversx_sc_scenario::imports::*; use num_traits::ToPrimitive; +use adder::*; use basic_features::BasicFeatures; -use multiversx_sc::{ - codec::Empty, - contract_base::ContractBase, - err_msg, - types::{Address, BigUint, EsdtLocalRole, EsdtTokenPayment, ManagedVec, TokenIdentifier}, -}; -use multiversx_sc_scenario::{ - api::DebugApi, assert_values_eq, managed_address, managed_biguint, managed_buffer, - managed_token_id, rust_biguint, testing_framework::*, -}; +use forwarder::fwd_call_sync::*; use rust_testing_framework_tester::{dummy_module::DummyModule, *}; const TEST_OUTPUT_PATH: &str = "test.scen.json"; diff --git a/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.lock b/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.lock index 83116fbd50..a03542b6d8 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.lock +++ b/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,7 +82,7 @@ dependencies = [ [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -96,27 +98,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -148,15 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -168,3 +170,9 @@ name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.toml b/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.toml index c50643a4db..0c4593999f 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.toml +++ b/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.rust-testing-framework-tester] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/rust-testing-framework-tester/wasm/src/lib.rs b/contracts/feature-tests/rust-testing-framework-tester/wasm/src/lib.rs index e8aaa36184..3943837d34 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/wasm/src/lib.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 28 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/scenario-tester/.gitignore b/contracts/feature-tests/scenario-tester/.gitignore new file mode 100644 index 0000000000..dd49a95243 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/.gitignore @@ -0,0 +1,10 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +*/target/ + +# The mxpy output +/output*/ + +# Mandos test trace +trace*.scen.json diff --git a/contracts/feature-tests/scenario-tester/Cargo.toml b/contracts/feature-tests/scenario-tester/Cargo.toml new file mode 100644 index 0000000000..90be88892c --- /dev/null +++ b/contracts/feature-tests/scenario-tester/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "scenario-tester" +version = "0.0.0" +authors = ["Andrei Marinica "] +edition = "2021" +publish = false + +[lib] +path = "src/lib.rs" + +[dependencies.multiversx-sc] +version = "0.50.3" +path = "../../../framework/base" + +[dev-dependencies.multiversx-sc-scenario] +version = "0.50.3" +path = "../../../framework/scenario" diff --git a/contracts/feature-tests/scenario-tester/README.md b/contracts/feature-tests/scenario-tester/README.md new file mode 100644 index 0000000000..4538caeca9 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/README.md @@ -0,0 +1,3 @@ +# Adder + +`Adder` is a simple Smart Contract. diff --git a/contracts/feature-tests/scenario-tester/meta/Cargo.toml b/contracts/feature-tests/scenario-tester/meta/Cargo.toml new file mode 100644 index 0000000000..6063c061b6 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/meta/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "scenario-tester-meta" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies.scenario-tester] +path = ".." + +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" +default-features = false diff --git a/contracts/feature-tests/scenario-tester/meta/src/main.rs b/contracts/feature-tests/scenario-tester/meta/src/main.rs new file mode 100644 index 0000000000..17b67ed1c1 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/meta/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + multiversx_sc_meta_lib::cli_main::(); +} diff --git a/contracts/feature-tests/scenario-tester/multiversx.json b/contracts/feature-tests/scenario-tester/multiversx.json new file mode 100644 index 0000000000..7365539625 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/multiversx.json @@ -0,0 +1,3 @@ +{ + "language": "rust" +} \ No newline at end of file diff --git a/contracts/feature-tests/scenario-tester/sc-config.toml b/contracts/feature-tests/scenario-tester/sc-config.toml new file mode 100644 index 0000000000..4b16ba7311 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/sc-config.toml @@ -0,0 +1,4 @@ +[settings] + +[[proxy]] +path = "src/scenario_tester_proxy.rs" diff --git a/contracts/feature-tests/scenario-tester/scenarios/interactor_trace.scen.json b/contracts/feature-tests/scenario-tester/scenarios/interactor_trace.scen.json new file mode 100644 index 0000000000..07fd7f68ca --- /dev/null +++ b/contracts/feature-tests/scenario-tester/scenarios/interactor_trace.scen.json @@ -0,0 +1,76 @@ +{ + "steps": [ + { + "step": "setState", + "accounts": { + "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60": { + "nonce": "481", + "balance": "106274669842530000003", + "esdt": { + "str:CAN-14dc0a": "1000", + "str:CAN-2abf4b": "1000", + "str:CAN-6d39e6": "1000", + "str:CAN-ac1592": "1000" + } + } + } + }, + { + "step": "setState", + "newAddresses": [ + { + "creatorAddress": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", + "creatorNonce": "481", + "newAddress": "0x0000000000000000050028600ceb73ac22ec0b6f257aff7bed74dffa3ebfed60" + } + ] + }, + { + "step": "scDeploy", + "tx": { + "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", + "contractCode": "mxsc:../output/scenario-tester.mxsc.json", + "arguments": [ + "0x00" + ], + "gasLimit": "70,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "tx": { + "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", + "to": "0x0000000000000000050028600ceb73ac22ec0b6f257aff7bed74dffa3ebfed60", + "function": "add", + "arguments": [ + "0x07" + ], + "gasLimit": "70,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "tx": { + "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", + "to": "0x0000000000000000050028600ceb73ac22ec0b6f257aff7bed74dffa3ebfed60", + "function": "add", + "arguments": [ + "0x05" + ], + "gasLimit": "70,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + } + ] +} diff --git a/contracts/feature-tests/scenario-tester/scenarios/st-adder.scen.json b/contracts/feature-tests/scenario-tester/scenarios/st-adder.scen.json new file mode 100644 index 0000000000..94ba305ed2 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/scenarios/st-adder.scen.json @@ -0,0 +1,99 @@ +{ + "name": "adder", + "comment": "add then check", + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "address:owner": { + "nonce": "1", + "balance": "0" + } + }, + "newAddresses": [ + { + "creatorAddress": "address:owner", + "creatorNonce": "1", + "newAddress": "sc:adder" + } + ] + }, + { + "step": "scDeploy", + "id": "1", + "tx": { + "from": "address:owner", + "contractCode": "mxsc:../output/scenario-tester.mxsc.json", + "arguments": [ + "5" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scQuery", + "id": "2", + "tx": { + "to": "sc:adder", + "function": "getSum", + "arguments": [] + }, + "expect": { + "out": [ + "5" + ], + "status": "", + "logs": [] + } + }, + { + "step": "scCall", + "id": "3", + "tx": { + "from": "address:owner", + "to": "sc:adder", + "function": "add", + "arguments": [ + "3" + ], + "gasLimit": "5,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:owner": { + "nonce": "*", + "balance": "0", + "storage": {}, + "code": "" + }, + "sc:adder": { + "nonce": "0", + "balance": "0", + "storage": { + "str:sum": "8" + }, + "code": "mxsc:../output/scenario-tester.mxsc.json" + } + } + } + ] +} diff --git a/contracts/feature-tests/scenario-tester/src/lib.rs b/contracts/feature-tests/scenario-tester/src/lib.rs new file mode 100644 index 0000000000..97c352adeb --- /dev/null +++ b/contracts/feature-tests/scenario-tester/src/lib.rs @@ -0,0 +1,41 @@ +#![no_std] + +use multiversx_sc::imports::*; + +pub mod scenario_tester_proxy; + +/// One of the simplest smart contracts possible, +/// it holds a single variable in storage, which anyone can increment. +#[multiversx_sc::contract] +pub trait ScenarioTester { + #[view(getSum)] + #[storage_mapper("sum")] + fn sum(&self) -> SingleValueMapper; + + #[init] + fn init(&self, initial_value: BigUint) { + self.sum().set(initial_value); + } + + #[upgrade] + fn upgrade(&self, initial_value: BigUint) { + self.init(initial_value); + } + + /// Add desired amount to the storage variable. + #[endpoint] + fn add(&self, value: BigUint) { + self.sum().update(|sum| *sum += value); + } + + /// Tests "from" conversion for MultiValueN parameters + #[endpoint] + fn multi_param(&self, _value: MultiValue2) {} + + /// Tests "from" conversion for MultiValueN return function + #[endpoint] + fn multi_return(&self, value: BigUint) -> MultiValue2 { + let value_plus_one = &value + 1u32; + (value, value_plus_one).into() + } +} diff --git a/contracts/feature-tests/scenario-tester/src/scenario_tester_proxy.rs b/contracts/feature-tests/scenario-tester/src/scenario_tester_proxy.rs new file mode 100644 index 0000000000..66976893c2 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/src/scenario_tester_proxy.rs @@ -0,0 +1,142 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct ScenarioTesterProxy; + +impl TxProxyTrait for ScenarioTesterProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = ScenarioTesterProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + ScenarioTesterProxyMethods { wrapped_tx: tx } + } +} + +pub struct ScenarioTesterProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl ScenarioTesterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init< + Arg0: ProxyArg>, + >( + self, + initial_value: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&initial_value) + .original_result() + } +} + +#[rustfmt::skip] +impl ScenarioTesterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn upgrade< + Arg0: ProxyArg>, + >( + self, + initial_value: Arg0, + ) -> TxTypedUpgrade { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .argument(&initial_value) + .original_result() + } +} + +#[rustfmt::skip] +impl ScenarioTesterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn sum( + self, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getSum") + .original_result() + } + + /// Add desired amount to the storage variable. + pub fn add< + Arg0: ProxyArg>, + >( + self, + value: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("add") + .argument(&value) + .original_result() + } + + /// Tests "from" conversion for MultiValueN parameters + pub fn multi_param< + Arg0: ProxyArg, BigUint>>, + >( + self, + _value: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("multi_param") + .argument(&_value) + .original_result() + } + + /// Tests "from" conversion for MultiValueN return function + pub fn multi_return< + Arg0: ProxyArg>, + >( + self, + value: Arg0, + ) -> TxTypedCall, BigUint>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("multi_return") + .argument(&value) + .original_result() + } +} diff --git a/contracts/feature-tests/scenario-tester/tests/st_blackbox_chained_test.rs b/contracts/feature-tests/scenario-tester/tests/st_blackbox_chained_test.rs new file mode 100644 index 0000000000..755647bb7b --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_blackbox_chained_test.rs @@ -0,0 +1,63 @@ +use multiversx_sc_scenario::imports::*; +use num_bigint::BigUint; + +use scenario_tester::*; + +const ADDER_PATH_EXPR: &str = "mxsc:output/scenario-tester.mxsc.json"; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(ADDER_PATH_EXPR, scenario_tester::ContractBuilder); + blockchain +} + +#[test] +fn st_blackbox_chained() { + let mut world = world(); + let owner_address = "address:owner"; + let st_contract = ContractInfo::>::new("sc:adder"); + + world + .start_trace() + .set_state_step( + SetStateStep::new() + .put_account(owner_address, Account::new().nonce(1)) + .new_address(owner_address, 1, "sc:adder"), + ) + .chain_deploy(|tx| { + tx.from(TestAddress::new("owner")) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .init(5u32) + .code(MxscPath::new("output/scenario-tester.mxsc.json")) + .with_result(WithNewAddress::new(|new_address| { + assert_eq!(new_address.to_address(), st_contract.to_address()); + })) + }) + .chain_query(|tx| { + tx.to(TestSCAddress::new("adder")) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .sum() + .with_result(WithResultAs::new(|value: BigUint| { + assert_eq!(value, BigUint::from(5u32)); + })) + }) + .chain_call(|tx| { + tx.from(TestAddress::new("owner")) + .to(TestSCAddress::new("adder")) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .add(3u32) + .with_result(WithRawTxResponse(|response| { + assert!(response.tx_error.is_success()); + })) + }) + .check_state_step( + CheckStateStep::new() + .put_account(owner_address, CheckAccount::new()) + .put_account( + &st_contract, + CheckAccount::new().check_storage("str:sum", "8"), + ), + ) + .write_scenario_trace("trace2.scen.json"); +} diff --git a/contracts/feature-tests/scenario-tester/tests/st_blackbox_legacy_proxy_test.rs b/contracts/feature-tests/scenario-tester/tests/st_blackbox_legacy_proxy_test.rs new file mode 100644 index 0000000000..cdc7f071ff --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_blackbox_legacy_proxy_test.rs @@ -0,0 +1,78 @@ +#![allow(deprecated)] + +use multiversx_sc_scenario::imports::*; +use num_bigint::BigUint; + +use scenario_tester::*; + +const ADDER_PATH_EXPR: &str = "mxsc:output/adder.mxsc.json"; + +const OWNER: TestAddress = TestAddress::new("owner"); +const CODE_EXPR: MxscPath = MxscPath::new("output/adder.mxsc.json"); + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(ADDER_PATH_EXPR, scenario_tester::ContractBuilder); + blockchain +} + +#[test] +fn st_blackbox_legacy_proxy() { + let mut world = world(); + let owner_address = "address:owner"; + let mut st_contract = ContractInfo::>::new("sc:adder"); + + world.start_trace(); + + world.set_state_step( + SetStateStep::new() + .put_account(owner_address, Account::new().nonce(1)) + .new_address(owner_address, 1, "sc:adder"), + ); + + world + .tx() + .from(OWNER) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .init(5u32) + .code(CODE_EXPR) + .with_result(WithNewAddress::new(|new_address| { + assert_eq!(new_address.to_address(), st_contract.to_address()); + })) + .run(); + + world.sc_query( + ScQueryStep::new() + .to(&st_contract) + .call(st_contract.sum()) + .expect_value(SingleValue::from(BigUint::from(5u32))), + ); + + let value = world + .query() + .legacy_proxy_call(st_contract.sum()) + .returns(ReturnsResultAs::>::new()) + .run(); + assert_eq!(value.into(), BigUint::from(5u32)); + + world + .tx() + .from(OWNER) + .legacy_proxy_call(st_contract.add(3u32)) + .with_result(WithRawTxResponse(|response| { + assert!(response.tx_error.is_success()); + })) + .run(); + + world.check_state_step( + CheckStateStep::new() + .put_account(owner_address, CheckAccount::new()) + .put_account( + &st_contract, + CheckAccount::new().check_storage("str:sum", "8"), + ), + ); + + world.write_scenario_trace("trace1.scen.json"); +} diff --git a/contracts/feature-tests/scenario-tester/tests/st_blackbox_raw_steps_test.rs b/contracts/feature-tests/scenario-tester/tests/st_blackbox_raw_steps_test.rs new file mode 100644 index 0000000000..68ac9b8d39 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_blackbox_raw_steps_test.rs @@ -0,0 +1,52 @@ +use multiversx_sc_scenario::imports::*; + +const SCENARIO_TESTER_PATH_EXPR: &str = "mxsc:output/scenario-tester.mxsc.json"; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(SCENARIO_TESTER_PATH_EXPR, scenario_tester::ContractBuilder); + blockchain +} + +#[test] +fn scenario_tester_blackbox_raw() { + let mut world = world(); + let scenario_tester_code = world.code_expression(SCENARIO_TESTER_PATH_EXPR); + + world + .set_state_step( + SetStateStep::new() + .put_account("address:owner", Account::new().nonce(1)) + .new_address("address:owner", 1, "sc:scenario-tester"), + ) + .sc_deploy( + ScDeployStep::new() + .from("address:owner") + .code(scenario_tester_code) + .argument("5") + .expect(TxExpect::ok().no_result()), + ) + .sc_query( + ScQueryStep::new() + .to("sc:scenario-tester") + .function("getSum") + .expect(TxExpect::ok().result("5")), + ) + .sc_call( + ScCallStep::new() + .from("address:owner") + .to("sc:scenario-tester") + .function("add") + .argument("3") + .expect(TxExpect::ok().no_result()), + ) + .check_state_step( + CheckStateStep::new() + .put_account("address:owner", CheckAccount::new()) + .put_account( + "sc:scenario-tester", + CheckAccount::new().check_storage("str:sum", "8"), + ), + ); +} diff --git a/contracts/feature-tests/scenario-tester/tests/st_blackbox_test.rs b/contracts/feature-tests/scenario-tester/tests/st_blackbox_test.rs new file mode 100644 index 0000000000..cdcf610b25 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_blackbox_test.rs @@ -0,0 +1,246 @@ +use multiversx_sc_scenario::imports::*; + +use scenario_tester::*; + +const SC_SCENARIO_TESTER_PATH_EXPR: &str = "mxsc:output/scenario-tester.mxsc.json"; +const FOURTH_ATTRIBUTES: &[u8] = b"FourthhAttributes"; +const FOURTH_URIS: &[&[u8]] = &[b"FirstUri", b"SecondUri"]; + +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const OTHER_ADDRESS: TestAddress = TestAddress::new("other"); +const ST_ADDRESS: TestSCAddress = TestSCAddress::new("scenario-tester"); +const CODE_PATH: MxscPath = MxscPath::new("output/scenario-tester.mxsc.json"); +const TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("TOKEN-123456"); +const NFT_ID: TestTokenIdentifier = TestTokenIdentifier::new("NFT-123456"); + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + SC_SCENARIO_TESTER_PATH_EXPR, + scenario_tester::ContractBuilder, + ); + blockchain +} + +#[test] +fn st_blackbox() { + let mut world = world(); + + world.start_trace(); + + world + .account(OWNER_ADDRESS) + .nonce(1) + .balance(100) + .account(OTHER_ADDRESS) + .nonce(2) + .balance(300) + .esdt_balance(TOKEN_ID, 500) + .commit(); + + world + .check_account(OWNER_ADDRESS) + .nonce(1) + .balance(100) + .check_account(OTHER_ADDRESS) + .nonce(2) + .balance(300) + .esdt_balance(TOKEN_ID, 500) + .commit(); + + world.new_address(OWNER_ADDRESS, 1, ST_ADDRESS); + + let new_address = world + .tx() + .from(OWNER_ADDRESS) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .init(5u32) + .code(CODE_PATH) + .returns(ReturnsNewAddress) + .run(); + assert_eq!(new_address, ST_ADDRESS.to_address()); + + let value = world + .query() + .to(ST_ADDRESS) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .sum() + .returns(ReturnsResultUnmanaged) + .run(); + assert_eq!(value, RustBigUint::from(5u32)); + + world + .tx() + .from(OWNER_ADDRESS) + .to(ST_ADDRESS) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .add(1u32) + .run(); + + world + .check_account(OWNER_ADDRESS) + .nonce(3) + .balance(100) + .check_account(ST_ADDRESS) + .check_storage("str:sum", "6") + .commit(); + + world + .tx() + .from(OTHER_ADDRESS) + .to(ST_ADDRESS) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .add(1u32) + .run(); + + world + .tx() + .from(OTHER_ADDRESS) + .to(ST_ADDRESS) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .multi_param(MultiValue2((1u32, 1u16))) + .run(); + + world + .tx() + .from(OTHER_ADDRESS) + .to(ST_ADDRESS) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .multi_return(1u32) + .returns(ExpectValue(MultiValue2((1u32, 2u32)))) + .run(); + + let value = world + .tx() + .from(OTHER_ADDRESS) + .to(ST_ADDRESS) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .multi_return(1u32) + .returns(ReturnsResultUnmanaged) + .run(); + assert_eq!( + value, + MultiValue2((RustBigUint::from(1u32), RustBigUint::from(2u32))) + ); + + world.write_scenario_trace("trace1.scen.json"); +} + +#[test] +fn set_state_test() { + let mut world = world(); + let first = TestAddress::new("first"); + let second = TestAddress::new("second"); + let third = TestAddress::new("third"); + let fourth = TestAddress::new("fourth"); + let fifth = TestAddress::new("fifth"); + let sixth = TestAddress::new("sixth"); + let seventh = TestAddress::new("seventh"); + let eighth = TestAddress::new("eighth"); + + world.start_trace(); + + world + .account(first) + .nonce(1) + .balance(100) + .account(second) + .nonce(2) + .balance(300) + .esdt_balance(TOKEN_ID, 500) + .commit(); + + world + .check_account(first) + .nonce(1) + .balance(100) + .check_account(second) + .nonce(2) + .balance(300) + .esdt_balance(TOKEN_ID, 500) + .commit(); + + world + .account(third) + .nonce(3) + .balance(50) + .esdt_nft_balance(NFT_ID, 2, 1, ()) + .commit(); + + world + .check_account(third) + .nonce(3) + .balance(50) + .esdt_nft_balance_and_attributes(NFT_ID, 2, 1, "") + .commit(); + + let fourth_uris = FOURTH_URIS + .iter() + .map(|first_uri| managed_buffer!(first_uri)) + .collect(); + world + .account(fourth) + .nonce(3) + .balance(50) + .esdt_nft_all_properties( + NFT_ID, + 2, + 1, + managed_buffer!(FOURTH_ATTRIBUTES), + 1000, + None::
, + (), + fourth_uris, + ) + .commit(); + + world + .check_account(fourth) + .nonce(3) + .balance(50) + .esdt_nft_balance_and_attributes(NFT_ID, 2, 1, FOURTH_ATTRIBUTES) + .commit(); + + world + .account(fifth) + .nonce(2) + .balance(30) + .esdt_nft_last_nonce(NFT_ID, 5); + world + .check_account(fifth) + .nonce(2) + .balance(30) + .esdt_nft_balance_and_attributes(NFT_ID, 5, 0, ""); + + // using no commit should drop the value naturally + world + .account(sixth) + .nonce(4) + .balance(400) + .account(seventh) + .nonce(5) + .balance(250) + .esdt_balance(TOKEN_ID, 2); + + world + .check_account(sixth) + .nonce(4) + .balance(400) + .check_account(seventh) + .nonce(5) + .balance(250) + .esdt_balance(TOKEN_ID, 2); + + world + .account(eighth) + .nonce(6) + .balance(600) + .esdt_balance(TOKEN_ID, 60); + + world + .check_account(eighth) + .nonce(6) + .balance(600) + .esdt_balance(TOKEN_ID, 60); +} diff --git a/contracts/examples/adder/tests/adder_blackbox_upgrade_test.rs b/contracts/feature-tests/scenario-tester/tests/st_blackbox_upgrade_test.rs similarity index 72% rename from contracts/examples/adder/tests/adder_blackbox_upgrade_test.rs rename to contracts/feature-tests/scenario-tester/tests/st_blackbox_upgrade_test.rs index 4cb12cad54..3242739239 100644 --- a/contracts/examples/adder/tests/adder_blackbox_upgrade_test.rs +++ b/contracts/feature-tests/scenario-tester/tests/st_blackbox_upgrade_test.rs @@ -1,19 +1,21 @@ -use multiversx_sc_scenario::{scenario_model::*, *}; +use multiversx_sc_scenario::imports::*; -const ADDER_PATH_EXPR: &str = "mxsc:output/adder.mxsc.json"; +const ADDER_PATH_EXPR: &str = "mxsc:output/scenario-tester.mxsc.json"; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/adder"); - blockchain.register_contract("mxsc:output/adder.mxsc.json", adder::ContractBuilder); + blockchain.register_contract( + "mxsc:output/scenario-tester.mxsc.json", + scenario_tester::ContractBuilder, + ); blockchain } #[test] -fn adder_blackbox_upgrade() { +fn st_blackbox_upgrade() { let mut world = world(); - let adder_code = world.code_expression(ADDER_PATH_EXPR); + let st_code = world.code_expression(ADDER_PATH_EXPR); world .set_state_step( @@ -24,7 +26,7 @@ fn adder_blackbox_upgrade() { .sc_deploy( ScDeployStep::new() .from("address:owner") - .code(&adder_code) + .code(&st_code) .argument("5") .gas_limit("5,000,000") .expect(TxExpect::ok().no_result()), @@ -34,7 +36,7 @@ fn adder_blackbox_upgrade() { .from("address:owner") .to("sc:adder") .function("upgradeContract") - .argument(&adder_code) + .argument(&st_code) .argument("0x0502") // codeMetadata .argument("8") // contract argument .expect(TxExpect::ok().no_result()), diff --git a/contracts/feature-tests/scenario-tester/tests/st_scenario_go_test.rs b/contracts/feature-tests/scenario-tester/tests/st_scenario_go_test.rs new file mode 100644 index 0000000000..a62c9ea10f --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_scenario_go_test.rs @@ -0,0 +1,15 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} + +#[test] +fn interactor_trace_go() { + world().run("scenarios/interactor_trace.scen.json"); +} + +#[test] +fn st_adder_go() { + world().run("scenarios/st-adder.scen.json"); +} diff --git a/contracts/feature-tests/scenario-tester/tests/st_scenario_rs_test.rs b/contracts/feature-tests/scenario-tester/tests/st_scenario_rs_test.rs new file mode 100644 index 0000000000..6695bcb89c --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_scenario_rs_test.rs @@ -0,0 +1,21 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + "mxsc:output/scenario-tester.mxsc.json", + scenario_tester::ContractBuilder, + ); + blockchain +} + +#[test] +fn interactor_trace_rs() { + world().run("scenarios/interactor_trace.scen.json"); +} + +#[test] +fn st_adder_rs() { + world().run("scenarios/st-adder.scen.json"); +} diff --git a/contracts/feature-tests/scenario-tester/tests/st_unit_test.rs b/contracts/feature-tests/scenario-tester/tests/st_unit_test.rs new file mode 100644 index 0000000000..e9b418dfad --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_unit_test.rs @@ -0,0 +1,17 @@ +use multiversx_sc::types::BigUint; +use multiversx_sc_scenario::api::SingleTxApi; +use scenario_tester::*; + +#[test] +fn st_unit_test() { + let contract = scenario_tester::contract_obj::(); + + contract.init(BigUint::from(5u32)); + assert_eq!(BigUint::from(5u32), contract.sum().get()); + + contract.add(BigUint::from(7u32)); + assert_eq!(BigUint::from(12u32), contract.sum().get()); + + contract.add(BigUint::from(1u32)); + assert_eq!(BigUint::from(13u32), contract.sum().get()); +} diff --git a/contracts/feature-tests/scenario-tester/tests/st_whitebox_test.rs b/contracts/feature-tests/scenario-tester/tests/st_whitebox_test.rs new file mode 100644 index 0000000000..a6318b1f7f --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_whitebox_test.rs @@ -0,0 +1,52 @@ +use multiversx_sc_scenario::imports::*; +use scenario_tester::*; + +const ADDER_PATH_EXPR: &str = "mxsc:output/scenario-tester.mxsc.json"; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + "mxsc:output/scenario-tester.mxsc.json", + scenario_tester::ContractBuilder, + ); + blockchain +} + +#[test] +fn st_whitebox() { + let mut world = world(); + let st_whitebox = WhiteboxContract::new("sc:adder", scenario_tester::contract_obj); + let st_code = world.code_expression(ADDER_PATH_EXPR); + + world + .set_state_step( + SetStateStep::new() + .put_account("address:owner", Account::new().nonce(1)) + .new_address("address:owner", 1, "sc:adder"), + ) + .whitebox_deploy( + &st_whitebox, + ScDeployStep::new().from("address:owner").code(st_code), + |sc| { + sc.init(5u32.into()); + }, + ) + .whitebox_query(&st_whitebox, |sc| { + let sum_value = sc.sum(); + assert_eq!(sum_value.get(), 5u32); + }) + .whitebox_call( + &st_whitebox, + ScCallStep::new().from("address:owner"), + |sc| sc.add(3u32.into()), + ) + .check_state_step( + CheckStateStep::new() + .put_account("address:owner", CheckAccount::new()) + .put_account( + "sc:adder", + CheckAccount::new().check_storage("str:sum", "8"), + ), + ); +} diff --git a/contracts/feature-tests/scenario-tester/wasm/Cargo.lock b/contracts/feature-tests/scenario-tester/wasm/Cargo.lock new file mode 100755 index 0000000000..7369ef2a5d --- /dev/null +++ b/contracts/feature-tests/scenario-tester/wasm/Cargo.lock @@ -0,0 +1,178 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "multiversx-sc" +version = "0.50.3" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.19.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.19.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.50.3" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.50.3" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "scenario-tester" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "scenario-tester-wasm" +version = "0.0.0" +dependencies = [ + "multiversx-sc-wasm-adapter", + "scenario-tester", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/scenario-tester/wasm/Cargo.toml b/contracts/feature-tests/scenario-tester/wasm/Cargo.toml new file mode 100644 index 0000000000..3076ca5055 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/wasm/Cargo.toml @@ -0,0 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "scenario-tester-wasm" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" + +[dependencies.scenario-tester] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.50.3" +path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/feature-tests/scenario-tester/wasm/src/lib.rs b/contracts/feature-tests/scenario-tester/wasm/src/lib.rs new file mode 100644 index 0000000000..7976698233 --- /dev/null +++ b/contracts/feature-tests/scenario-tester/wasm/src/lib.rs @@ -0,0 +1,30 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Upgrade: 1 +// Endpoints: 4 +// Async Callback (empty): 1 +// Total number of exported functions: 7 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + scenario_tester + ( + init => init + upgrade => upgrade + getSum => sum + add => add + multi_param => multi_param + multi_return => multi_return + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/contracts/feature-tests/use-module/Cargo.toml b/contracts/feature-tests/use-module/Cargo.toml index 281bd20397..31be1bacf8 100644 --- a/contracts/feature-tests/use-module/Cargo.toml +++ b/contracts/feature-tests/use-module/Cargo.toml @@ -9,17 +9,17 @@ publish = false path = "src/use_module.rs" [dependencies.multiversx-sc-modules] -version = "0.47.5" +version = "0.50.3" path = "../../../contracts/modules" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.47.5" +version = "0.50.3" path = "../../../framework/scenario" -[dev-dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../framework/meta" +[dev-dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../framework/meta-lib" diff --git a/contracts/feature-tests/use-module/meta/Cargo.toml b/contracts/feature-tests/use-module/meta/Cargo.toml index 8246cc5fce..ce37ad8bdf 100644 --- a/contracts/feature-tests/use-module/meta/Cargo.toml +++ b/contracts/feature-tests/use-module/meta/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies.use-module] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.50.3" +path = "../../../../framework/meta-lib" default-features = false diff --git a/contracts/feature-tests/use-module/meta/abi/Cargo.toml b/contracts/feature-tests/use-module/meta/abi/Cargo.toml deleted file mode 100644 index 7a0eecd776..0000000000 --- a/contracts/feature-tests/use-module/meta/abi/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "use-module-meta" -version = "0.0.0" -authors = ["Andrei Marinica "] -edition = "2021" -publish = false - -[dependencies.use-module] -path = ".." - -[dependencies.multiversx-sc] -version = "0.47.5" -path = "../../../../framework/base" - -[dependencies.multiversx-sc-meta] -version = "0.47.5" -path = "../../../../framework/meta" -default-features = false diff --git a/contracts/feature-tests/use-module/meta/abi/src/main.rs b/contracts/feature-tests/use-module/meta/abi/src/main.rs deleted file mode 100644 index afafea6eda..0000000000 --- a/contracts/feature-tests/use-module/meta/abi/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - multiversx_sc_meta::cli_main::(); -} diff --git a/contracts/feature-tests/use-module/meta/src/main.rs b/contracts/feature-tests/use-module/meta/src/main.rs index afafea6eda..fd7c09a442 100644 --- a/contracts/feature-tests/use-module/meta/src/main.rs +++ b/contracts/feature-tests/use-module/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { - multiversx_sc_meta::cli_main::(); + multiversx_sc_meta_lib::cli_main::(); } diff --git a/contracts/feature-tests/use-module/scenarios/use_module_ongoing_operation_example.scen.json b/contracts/feature-tests/use-module/scenarios/use_module_ongoing_operation_example.scen.json index 45a659c44e..a8a16623b2 100644 --- a/contracts/feature-tests/use-module/scenarios/use_module_ongoing_operation_example.scen.json +++ b/contracts/feature-tests/use-module/scenarios/use_module_ongoing_operation_example.scen.json @@ -52,7 +52,7 @@ "to": "sc:use_module", "function": "countTo100", "arguments": [], - "gasLimit": "5,350,000", + "gasLimit": "4,700,000", "gasPrice": "0" }, "expect": { diff --git a/contracts/feature-tests/use-module/tests/gov_module_whitebox_test.rs b/contracts/feature-tests/use-module/tests/gov_module_whitebox_test.rs index fe90f658e4..72b15aac66 100644 --- a/contracts/feature-tests/use-module/tests/gov_module_whitebox_test.rs +++ b/contracts/feature-tests/use-module/tests/gov_module_whitebox_test.rs @@ -1,15 +1,8 @@ -use multiversx_sc::types::{Address, ManagedVec, MultiValueEncoded}; use multiversx_sc_modules::governance::{ governance_configurable::GovernanceConfigurablePropertiesModule, governance_proposal::VoteType, GovernanceModule, }; -use multiversx_sc_scenario::{ - managed_address, managed_biguint, managed_buffer, managed_token_id, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, ScDeployStep, SetStateStep, - }, - ScenarioWorld, WhiteboxContract, -}; +use multiversx_sc_scenario::imports::*; const GOV_TOKEN_ID_EXPR: &str = "str:GOV-123456"; const GOV_TOKEN_ID: &[u8] = b"GOV-123456"; @@ -38,7 +31,6 @@ pub struct Payment { fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/features-tests/use-module"); blockchain.register_contract(USE_MODULE_PATH_EXPR, use_module::ContractBuilder); blockchain diff --git a/contracts/feature-tests/use-module/tests/staking_module_whitebox_test.rs b/contracts/feature-tests/use-module/tests/staking_module_whitebox_test.rs index 91a96db16a..612fa725df 100644 --- a/contracts/feature-tests/use-module/tests/staking_module_whitebox_test.rs +++ b/contracts/feature-tests/use-module/tests/staking_module_whitebox_test.rs @@ -1,12 +1,5 @@ -use multiversx_sc::types::{Address, EgldOrEsdtTokenIdentifier, ManagedVec}; use multiversx_sc_modules::staking::StakingModule; -use multiversx_sc_scenario::{ - managed_address, managed_biguint, managed_token_id, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, ScDeployStep, SetStateStep, - }, - ScenarioWorld, WhiteboxContract, -}; +use multiversx_sc_scenario::imports::*; const STAKING_TOKEN_ID_EXPR: &str = "str:STAKE-123456"; const STAKING_TOKEN_ID: &[u8] = b"STAKE-123456"; @@ -28,7 +21,6 @@ const USE_MODULE_PATH_EXPR: &str = "mxsc:output/use-module.mxsc.json"; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/features-tests/use-module"); blockchain.register_contract(USE_MODULE_PATH_EXPR, use_module::ContractBuilder); blockchain diff --git a/contracts/feature-tests/use-module/tests/token_merge_module_whitebox_test.rs b/contracts/feature-tests/use-module/tests/token_merge_module_whitebox_test.rs index a970685918..803992d49b 100644 --- a/contracts/feature-tests/use-module/tests/token_merge_module_whitebox_test.rs +++ b/contracts/feature-tests/use-module/tests/token_merge_module_whitebox_test.rs @@ -1,20 +1,8 @@ -use multiversx_sc::{ - arrayvec::ArrayVec, - codec::{test_util::top_encode_to_vec_u8_or_panic, Empty}, - contract_base::ContractBase, - storage::mappers::StorageTokenWrapper, - types::{Address, EsdtTokenPayment, ManagedVec}, -}; +use multiversx_sc_scenario::imports::*; + use multiversx_sc_modules::token_merge::{ merged_token_instances::MergedTokenInstances, merged_token_setup::MergedTokenSetupModule, }; -use multiversx_sc_scenario::{ - managed_address, managed_biguint, managed_token_id, - scenario_model::{ - Account, AddressValue, CheckAccount, CheckStateStep, ScCallStep, SetStateStep, TxESDT, - }, - ScenarioWorld, WhiteboxContract, -}; use use_module::token_merge_mod_impl::{CustomAttributes, TokenMergeModImpl}; const OWNER_ADDRESS_EXPR: &str = "address:owner"; @@ -45,8 +33,6 @@ const SECOND_URIS: &[&[u8]] = &[b"cool.com/safe_file.exe"]; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/features-tests/use-module"); - blockchain.register_contract(USE_MODULE_PATH_EXPR, use_module::ContractBuilder); blockchain } @@ -78,7 +64,7 @@ fn test_token_merge() { NFT_AMOUNT, Some(FIRST_ATTRIBUTES), FIRST_ROYALTIES, - None, + None::, None, Vec::from(FIRST_URIS), ) @@ -88,7 +74,7 @@ fn test_token_merge() { NFT_AMOUNT, Some(SECOND_ATTRIBUTES), SECOND_ROYALTIES, - None, + None::, None, Vec::from(SECOND_URIS), ), @@ -466,7 +452,7 @@ fn test_partial_split() { NFT_AMOUNT, Some(FIRST_ATTRIBUTES), FIRST_ROYALTIES, - None, + None::, None, Vec::from(FIRST_URIS), ) @@ -476,7 +462,7 @@ fn test_partial_split() { NFT_AMOUNT, Some(SECOND_ATTRIBUTES), SECOND_ROYALTIES, - None, + None::, None, Vec::from(SECOND_URIS), ), @@ -684,7 +670,7 @@ fn test_custom_attributes() { NFT_AMOUNT, Some(FIRST_ATTRIBUTES), FIRST_ROYALTIES, - None, + None::, None, Vec::from(FIRST_URIS), ) @@ -694,7 +680,7 @@ fn test_custom_attributes() { NFT_AMOUNT, Some(SECOND_ATTRIBUTES), SECOND_ROYALTIES, - None, + None::, None, Vec::from(SECOND_URIS), ), diff --git a/contracts/feature-tests/use-module/tests/use_module_abi_test.rs b/contracts/feature-tests/use-module/tests/use_module_abi_test.rs index 1091e76aa4..9600b19bcb 100644 --- a/contracts/feature-tests/use-module/tests/use_module_abi_test.rs +++ b/contracts/feature-tests/use-module/tests/use_module_abi_test.rs @@ -1,17 +1,16 @@ -use multiversx_sc_meta::abi_json; +use multiversx_sc_meta_lib::abi_json; use multiversx_sc_scenario::*; use std::{fs, fs::File, io::Write}; #[test] fn use_module_abi_generated_ok() { - let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/use-module"); + let blockchain = ScenarioWorld::new(); // generate ABI - let multi_contract_config = multiversx_sc_meta::multi_contract_config::( - blockchain.current_dir().as_path(), - ); + let multi_contract_config = multiversx_sc_meta_lib::multi_contract_config::< + use_module::AbiProvider, + >(blockchain.current_dir().as_path()); let main_contract = multi_contract_config.find_contract("use-module"); assert!(!main_contract.settings.external_view); diff --git a/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs b/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs index 2ecb798d24..a7360462a4 100644 --- a/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs +++ b/contracts/feature-tests/use-module/tests/use_module_scenario_rs_test.rs @@ -1,30 +1,18 @@ -mod user_builtin { - multiversx_sc::imports!(); - - #[multiversx_sc::proxy] - pub trait UserBuiltin { - #[endpoint(SetUserName)] - fn set_user_name(&self, name: &BoxedBytes) -> BigUint; - } -} - mod dns_mock { multiversx_sc::imports!(); #[multiversx_sc::contract] pub trait DnsMock { - #[proxy] - fn user_builtin_proxy(&self, to: ManagedAddress) -> super::user_builtin::Proxy; - #[payable("EGLD")] #[endpoint] fn register(&self, name: BoxedBytes) { let _payment = self.call_value().egld_value(); let address = self.blockchain().get_caller(); - self.user_builtin_proxy(address) + self.tx() + .to(&address) + .typed(system_proxy::UserBuiltinProxy) .set_user_name(&name) - .async_call() - .call_and_exit() + .async_call_and_exit(); } } } diff --git a/contracts/feature-tests/use-module/use_module_expected_main.abi.json b/contracts/feature-tests/use-module/use_module_expected_main.abi.json index 56d64db6c4..24dba15f2a 100644 --- a/contracts/feature-tests/use-module/use_module_expected_main.abi.json +++ b/contracts/feature-tests/use-module/use_module_expected_main.abi.json @@ -14,7 +14,7 @@ }, "framework": { "name": "multiversx-sc", - "version": "0.47.5" + "version": "0.50.3" } }, "docs": [ diff --git a/contracts/feature-tests/use-module/use_module_expected_view.abi.json b/contracts/feature-tests/use-module/use_module_expected_view.abi.json index 8fef61ec76..e2da01d9a4 100644 --- a/contracts/feature-tests/use-module/use_module_expected_view.abi.json +++ b/contracts/feature-tests/use-module/use_module_expected_view.abi.json @@ -14,7 +14,7 @@ }, "framework": { "name": "multiversx-sc", - "version": "0.47.5" + "version": "0.50.3" } }, "docs": [ diff --git a/contracts/feature-tests/use-module/wasm-use-module-view/Cargo.lock b/contracts/feature-tests/use-module/wasm-use-module-view/Cargo.lock index 6de9cf30eb..f89966ed3a 100644 --- a/contracts/feature-tests/use-module/wasm-use-module-view/Cargo.lock +++ b/contracts/feature-tests/use-module/wasm-use-module-view/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,14 +82,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,27 +105,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -140,15 +142,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -161,6 +163,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "use-module" version = "0.0.0" diff --git a/contracts/feature-tests/use-module/wasm-use-module-view/Cargo.toml b/contracts/feature-tests/use-module/wasm-use-module-view/Cargo.toml index bf3768167c..92190bcc04 100644 --- a/contracts/feature-tests/use-module/wasm-use-module-view/Cargo.toml +++ b/contracts/feature-tests/use-module/wasm-use-module-view/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.use-module] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/use-module/wasm-use-module-view/src/lib.rs b/contracts/feature-tests/use-module/wasm-use-module-view/src/lib.rs index b1ea58a65a..4a5b43d1de 100644 --- a/contracts/feature-tests/use-module/wasm-use-module-view/src/lib.rs +++ b/contracts/feature-tests/use-module/wasm-use-module-view/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 4 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/use-module/wasm/Cargo.lock b/contracts/feature-tests/use-module/wasm/Cargo.lock index 9d8b2504a3..d2ea103db8 100644 --- a/contracts/feature-tests/use-module/wasm/Cargo.lock +++ b/contracts/feature-tests/use-module/wasm/Cargo.lock @@ -10,15 +10,15 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "endian-type" @@ -40,26 +40,28 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" dependencies = [ "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" dependencies = [ "hex", "proc-macro2", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" dependencies = [ "hex", "proc-macro2", @@ -80,14 +82,14 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" dependencies = [ "multiversx-sc", ] @@ -103,27 +105,27 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -140,15 +142,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -161,6 +163,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "use-module" version = "0.0.0" diff --git a/contracts/feature-tests/use-module/wasm/Cargo.toml b/contracts/feature-tests/use-module/wasm/Cargo.toml index 129b71c83e..576a6fe2e9 100644 --- a/contracts/feature-tests/use-module/wasm/Cargo.toml +++ b/contracts/feature-tests/use-module/wasm/Cargo.toml @@ -21,11 +21,14 @@ debug = false panic = "abort" overflow-checks = false +[profile.dev] +panic = "abort" + [dependencies.use-module] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.47.5" +version = "0.50.3" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/feature-tests/use-module/wasm/src/lib.rs b/contracts/feature-tests/use-module/wasm/src/lib.rs index 88422e3c83..7171b56ecd 100644 --- a/contracts/feature-tests/use-module/wasm/src/lib.rs +++ b/contracts/feature-tests/use-module/wasm/src/lib.rs @@ -10,8 +10,6 @@ // Total number of exported functions: 65 #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/modules/Cargo.toml b/contracts/modules/Cargo.toml index dcdc0d02e5..4eea34320e 100644 --- a/contracts/modules/Cargo.toml +++ b/contracts/modules/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-modules" -version = "0.47.5" +version = "0.50.3" edition = "2021" authors = ["MultiversX "] @@ -17,5 +17,5 @@ categories = ["no-std", "wasm", "cryptography::cryptocurrencies"] alloc = ["multiversx-sc/alloc"] [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../framework/base" diff --git a/contracts/modules/src/bonding_curve/utils/owner_endpoints.rs b/contracts/modules/src/bonding_curve/utils/owner_endpoints.rs index 51f5eaaa35..382e1fbc28 100644 --- a/contracts/modules/src/bonding_curve/utils/owner_endpoints.rs +++ b/contracts/modules/src/bonding_curve/utils/owner_endpoints.rs @@ -25,8 +25,7 @@ pub trait OwnerEndpointsModule: storage::StorageModule + events::EventsModule { self.send() .esdt_system_sc_proxy() .set_special_roles(&address, &token_identifier, roles.into_iter()) - .async_call() - .call_and_exit() + .async_call_and_exit() } #[endpoint(unsetLocalRoles)] @@ -39,8 +38,7 @@ pub trait OwnerEndpointsModule: storage::StorageModule + events::EventsModule { self.send() .esdt_system_sc_proxy() .unset_special_roles(&address, &token_identifier, roles.into_iter()) - .async_call() - .call_and_exit() + .async_call_and_exit() } fn set_bonding_curve( @@ -179,9 +177,9 @@ pub trait OwnerEndpointsModule: storage::StorageModule + events::EventsModule { self.bonding_curve(&token).clear(); } self.owned_tokens(&caller).clear(); - self.send().direct_multi(&caller, &tokens_to_claim); + self.tx().to(&caller).multi_esdt(tokens_to_claim).transfer(); if egld_to_claim > BigUint::zero() { - self.send().direct_egld(&caller, &egld_to_claim); + self.tx().to(&caller).egld(&egld_to_claim).transfer(); } } diff --git a/contracts/modules/src/bonding_curve/utils/user_endpoints.rs b/contracts/modules/src/bonding_curve/utils/user_endpoints.rs index 321a0bd439..f627d26256 100644 --- a/contracts/modules/src/bonding_curve/utils/user_endpoints.rs +++ b/contracts/modules/src/bonding_curve/utils/user_endpoints.rs @@ -48,8 +48,11 @@ pub trait UserEndpointsModule: storage::StorageModule + events::EventsModule { self.nonce_amount(&offered_token, nonce) .update(|val| *val += sell_amount); - self.send() - .direct(&caller, &payment_token, 0u64, &calculated_price); + self.tx() + .to(&caller) + .egld_or_single_esdt(&payment_token, 0u64, &calculated_price) + .transfer(); + self.token_details(&offered_token) .update(|details| details.add_nonce(nonce)); @@ -98,8 +101,10 @@ pub trait UserEndpointsModule: storage::StorageModule + events::EventsModule { match requested_nonce { OptionalValue::Some(nonce) => { - self.send() - .direct_esdt(&caller, &requested_token, nonce, &requested_amount); + self.tx() + .to(&caller) + .single_esdt(&requested_token, nonce, &requested_amount) + .transfer(); if self.nonce_amount(&requested_token, nonce).get() - requested_amount.clone() > 0 { self.nonce_amount(&requested_token, nonce) .update(|val| *val -= requested_amount.clone()); @@ -114,12 +119,10 @@ pub trait UserEndpointsModule: storage::StorageModule + events::EventsModule { }, }; - self.send().direct( - &caller, - &offered_token, - 0u64, - &(&payment - &calculated_price), - ); + self.tx() + .to(&caller) + .egld_or_single_esdt(&offered_token, 0u64, &(&payment - &calculated_price)) + .transfer(); self.buy_token_event(&caller, &calculated_price); } @@ -156,7 +159,7 @@ pub trait UserEndpointsModule: storage::StorageModule + events::EventsModule { } } - self.send().direct_multi(caller, &tokens_to_send); + self.tx().to(caller).multi_esdt(tokens_to_send).transfer(); self.token_details(&token) .update(|token_ownership| token_ownership.token_nonces = nonces); diff --git a/contracts/modules/src/claim_developer_rewards.rs b/contracts/modules/src/claim_developer_rewards.rs index 05be2a0012..ac1187ab20 100644 --- a/contracts/modules/src/claim_developer_rewards.rs +++ b/contracts/modules/src/claim_developer_rewards.rs @@ -4,9 +4,8 @@ multiversx_sc::imports!(); pub trait ClaimDeveloperRewardsModule { #[endpoint(claimDeveloperRewards)] fn claim_developer_rewards(&self, child_sc_address: ManagedAddress) { - let () = self - .send() + self.send() .claim_developer_rewards(child_sc_address) - .execute_on_dest_context(); + .sync_call(); } } diff --git a/contracts/modules/src/default_issue_callbacks.rs b/contracts/modules/src/default_issue_callbacks.rs index 7c0d096b2e..6edd7abeec 100644 --- a/contracts/modules/src/default_issue_callbacks.rs +++ b/contracts/modules/src/default_issue_callbacks.rs @@ -46,9 +46,9 @@ pub trait DefaultIssueCallbacksModule { } fn return_failed_issue_funds(&self, initial_caller: ManagedAddress) { - let egld_returned = self.call_value().egld_value(); - if *egld_returned > 0u32 { - self.send().direct_egld(&initial_caller, &egld_returned); + let egld_returned = self.call_value().egld_value().to_u64().unwrap(); + if egld_returned > 0u64 { + self.tx().to(&initial_caller).egld(egld_returned).transfer(); } } } diff --git a/contracts/modules/src/dns.rs b/contracts/modules/src/dns.rs index 0bbeb38101..7e8123a0cf 100644 --- a/contracts/modules/src/dns.rs +++ b/contracts/modules/src/dns.rs @@ -1,13 +1,4 @@ -mod dns_proxy { - multiversx_sc::imports!(); - - #[multiversx_sc::proxy] - pub trait Dns { - #[payable("EGLD")] - #[endpoint] - fn register(&self, name: &ManagedBuffer); - } -} +use crate::dns_proxy; multiversx_sc::imports!(); @@ -18,18 +9,16 @@ multiversx_sc::imports!(); /// #[multiversx_sc::module] pub trait DnsModule { - #[proxy] - fn dns_proxy(&self, to: ManagedAddress) -> dns_proxy::Proxy; - #[payable("EGLD")] #[only_owner] #[endpoint(dnsRegister)] fn dns_register(&self, dns_address: ManagedAddress, name: ManagedBuffer) { let payment = self.call_value().egld_value().clone_value(); - self.dns_proxy(dns_address) - .register(&name) - .with_egld_transfer(payment) - .async_call() - .call_and_exit() + self.tx() + .to(&dns_address) + .typed(dns_proxy::DnsProxy) + .register(name) + .egld(payment) + .async_call_and_exit(); } } diff --git a/contracts/modules/src/dns_proxy.rs b/contracts/modules/src/dns_proxy.rs new file mode 100644 index 0000000000..8ef8a82b94 --- /dev/null +++ b/contracts/modules/src/dns_proxy.rs @@ -0,0 +1,51 @@ +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct DnsProxy; + +impl TxProxyTrait for DnsProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = DnsProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + DnsProxyMethods { wrapped_tx: tx } + } +} + +pub struct DnsProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl DnsProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn register< + Arg0: ProxyArg>, + >( + self, + name: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("register") + .argument(&name) + .original_result() + } +} diff --git a/contracts/modules/src/esdt.rs b/contracts/modules/src/esdt.rs index 18f43b896f..ea977f53be 100644 --- a/contracts/modules/src/esdt.rs +++ b/contracts/modules/src/esdt.rs @@ -49,9 +49,8 @@ pub trait EsdtModule { token_type, num_decimals, ) - .async_call() .with_callback(self.callbacks().issue_callback()) - .call_and_exit() + .async_call_and_exit() } #[callback] @@ -64,9 +63,10 @@ pub trait EsdtModule { // return payment to initial caller let initial_caller = self.blockchain().get_owner_address(); let egld_returned = self.call_value().egld_value(); - if *egld_returned > 0u32 { - self.send().direct_egld(&initial_caller, &egld_returned); - } + self.tx() + .to(&initial_caller) + .egld(egld_returned) + .transfer_if_not_empty(); }, } } diff --git a/contracts/modules/src/governance/mod.rs b/contracts/modules/src/governance/mod.rs index ee343f7101..92eeb038db 100644 --- a/contracts/modules/src/governance/mod.rs +++ b/contracts/modules/src/governance/mod.rs @@ -84,12 +84,14 @@ pub trait GovernanceModule: for fee_entry in fees_to_send.iter() { let payment = fee_entry.tokens.clone(); - self.send().direct_esdt( - &fee_entry.depositor_addr, - &payment.token_identifier, - payment.token_nonce, - &payment.amount, - ); + self.tx() + .to(&fee_entry.depositor_addr) + .single_esdt( + &payment.token_identifier, + payment.token_nonce, + &payment.amount, + ) + .transfer(); self.user_claim_event(&caller, proposal_id, &fee_entry.tokens); } } @@ -276,16 +278,12 @@ pub trait GovernanceModule: self.clear_proposal(proposal_id); for action in proposal.actions { - let mut contract_call = self - .send() - .contract_call::<()>(action.dest_address, action.function_name) - .with_gas_limit(action.gas_limit); - - for arg in &action.arguments { - contract_call.push_raw_argument(arg); - } - - contract_call.transfer_execute(); + self.tx() + .to(&action.dest_address) + .raw_call(action.function_name) + .gas(action.gas_limit) + .arguments_raw(action.arguments.into()) + .transfer_execute() } self.proposal_executed_event(proposal_id); @@ -420,12 +418,14 @@ pub trait GovernanceModule: for fee_entry in payments.entries.iter() { let payment = fee_entry.tokens; - self.send().direct_esdt( - &fee_entry.depositor_addr, - &payment.token_identifier, - payment.token_nonce, - &payment.amount, - ); + self.tx() + .to(&fee_entry.depositor_addr) + .single_esdt( + &payment.token_identifier, + payment.token_nonce, + &payment.amount, + ) + .transfer(); } } diff --git a/contracts/modules/src/lib.rs b/contracts/modules/src/lib.rs index b1973e3fc0..d3b6c29f85 100644 --- a/contracts/modules/src/lib.rs +++ b/contracts/modules/src/lib.rs @@ -1,10 +1,10 @@ #![no_std] -#![feature(trait_alias)] pub mod bonding_curve; pub mod claim_developer_rewards; pub mod default_issue_callbacks; pub mod dns; +pub mod dns_proxy; pub mod esdt; pub mod features; pub mod governance; diff --git a/contracts/modules/src/staking.rs b/contracts/modules/src/staking.rs index 3db2350fb1..e30a457e51 100644 --- a/contracts/modules/src/staking.rs +++ b/contracts/modules/src/staking.rs @@ -90,8 +90,10 @@ pub trait StakingModule { staked_amount_mapper.set(&leftover_amount); let staking_token = self.staking_token().get(); - self.send() - .direct(&caller, &staking_token, 0, &unstake_amount); + self.tx() + .to(caller) + .egld_or_single_esdt(&staking_token, 0, &unstake_amount) + .transfer(); } #[endpoint(voteSlashMember)] diff --git a/contracts/modules/src/token_merge/custom_merged_token_attributes.rs b/contracts/modules/src/token_merge/custom_merged_token_attributes.rs index 0585685fd8..8d06d3530d 100644 --- a/contracts/modules/src/token_merge/custom_merged_token_attributes.rs +++ b/contracts/modules/src/token_merge/custom_merged_token_attributes.rs @@ -6,9 +6,19 @@ use multiversx_sc::codec::Empty; use super::merged_token_instances::MergedTokenInstances; -pub trait AllMergeScTraits = super::merged_token_setup::MergedTokenSetupModule +pub trait AllMergeScTraits: + super::merged_token_setup::MergedTokenSetupModule + crate::default_issue_callbacks::DefaultIssueCallbacksModule - + crate::pause::PauseModule; + + crate::pause::PauseModule +{ +} + +impl AllMergeScTraits for T where + T: super::merged_token_setup::MergedTokenSetupModule + + crate::default_issue_callbacks::DefaultIssueCallbacksModule + + crate::pause::PauseModule +{ +} pub trait MergedTokenAttributesCreator { type ScType: AllMergeScTraits; diff --git a/contracts/modules/src/token_merge/mod.rs b/contracts/modules/src/token_merge/mod.rs index 024626e2f1..b940980dfe 100644 --- a/contracts/modules/src/token_merge/mod.rs +++ b/contracts/modules/src/token_merge/mod.rs @@ -74,9 +74,11 @@ pub trait TokenMergeModule: let merged_token_payment = self.create_merged_token(merged_token_id, &all_merged_instances, attr_creator); - let caller = self.blockchain().get_caller(); - self.send() - .direct_non_zero_esdt_payment(&caller, &merged_token_payment); + + self.tx() + .to(ToCaller) + .payment(&merged_token_payment) + .transfer_if_not_empty(); merged_token_payment } @@ -118,8 +120,7 @@ pub trait TokenMergeModule: .esdt_local_burn(&token.token_identifier, token.token_nonce, &token.amount); } - let caller = self.blockchain().get_caller(); - self.send().direct_multi(&caller, &output_payments); + self.tx().to(ToCaller).payment(&output_payments).transfer(); output_payments } @@ -165,8 +166,7 @@ pub trait TokenMergeModule: ); tokens_to_remove.push(new_merged_token); - let caller = self.blockchain().get_caller(); - self.send().direct_multi(&caller, &tokens_to_remove); + self.tx().to(ToCaller).payment(&tokens_to_remove).transfer(); tokens_to_remove } diff --git a/contracts/modules/src/transfer_role_proxy.rs b/contracts/modules/src/transfer_role_proxy.rs index 80995eff04..d5249ce04c 100644 --- a/contracts/modules/src/transfer_role_proxy.rs +++ b/contracts/modules/src/transfer_role_proxy.rs @@ -13,19 +13,26 @@ pub trait TransferRoleProxyModule { &self, original_caller: ManagedAddress, dest: ManagedAddress, - payments: PaymentsVec, + payments: &PaymentsVec, data: ManagedBuffer, ) -> ! { - let contract_call = - ContractCallWithMultiEsdt::::new(dest, data, payments.clone()); + let transaction = self.tx().to(&dest).raw_call(data).payment(payments); - self.execute_async_call(original_caller, payments, contract_call, None); + self.execute_async_call(original_caller, payments, transaction, None) } fn transfer_to_contract_typed_call( &self, original_caller: ManagedAddress, - contract_call: ContractCallWithMultiEsdt, + transaction: Tx< + TxScEnv, + (), + &ManagedAddress, + &ManagedVec>, + (), + FunctionCall, + (), + >, opt_custom_callback: Option>, ) -> ! where @@ -33,8 +40,8 @@ pub trait TransferRoleProxyModule { { self.execute_async_call( original_caller, - contract_call.esdt_payments.clone(), - contract_call, + transaction.payment, + transaction, opt_custom_callback, ); } @@ -43,59 +50,55 @@ pub trait TransferRoleProxyModule { &self, original_caller: ManagedAddress, dest: ManagedAddress, - payments: PaymentsVec, + payments: &PaymentsVec, endpoint_name: ManagedBuffer, args: ManagedArgBuffer, opt_custom_callback: Option>, ) -> ! { - let contract_call = - ContractCallWithMultiEsdt::::new(dest, endpoint_name, payments.clone()) - .with_raw_arguments(args); - - self.execute_async_call( - original_caller, - payments, - contract_call, - opt_custom_callback, - ); + let transaction = self + .tx() + .to(&dest) + .raw_call(endpoint_name) + .payment(payments) + .arguments_raw(args); + + self.execute_async_call(original_caller, payments, transaction, opt_custom_callback) } - fn execute_async_call( + fn execute_async_call( &self, original_caller: ManagedAddress, - initial_payments: PaymentsVec, - contract_call: ContractCallWithMultiEsdt, + initial_payments: &PaymentsVec, + transaction: Tx< + TxScEnv, + (), + &ManagedAddress, + &ManagedVec>, + (), + FunctionCall, + (), + >, opt_custom_callback: Option>, - ) -> ! - where - T: TopEncodeMulti, - { + ) -> ! { require!( - self.destination_whitelist() - .contains(&contract_call.basic.to), + self.destination_whitelist().contains(transaction.to), "Destination address not whitelisted" ); let remaining_gas = self.blockchain().get_gas_left(); - let cb_gas_needed = - CALLBACK_RESERVED_GAS_PER_TOKEN * contract_call.esdt_payments.len() as u64; + let cb_gas_needed = CALLBACK_RESERVED_GAS_PER_TOKEN * transaction.payment.len() as u64; require!( remaining_gas > cb_gas_needed, "Not enough gas to launch async call" ); - let async_call_gas = remaining_gas - cb_gas_needed; let cb = match opt_custom_callback { Some(custom_cb) => custom_cb, None => TransferRoleProxyModule::callbacks(self) - .transfer_callback(original_caller, initial_payments), + .transfer_callback(original_caller, initial_payments.clone()), }; - contract_call - .with_gas_limit(async_call_gas) - .async_call() - .with_callback(cb) - .call_and_exit() + transaction.callback(cb).async_call_and_exit() } #[callback] @@ -109,8 +112,10 @@ pub trait TransferRoleProxyModule { ManagedAsyncCallResult::Ok(return_values) => return_values, ManagedAsyncCallResult::Err(err) => { if !initial_payments.is_empty() { - self.send() - .direct_multi(&original_caller, &initial_payments); + self.tx() + .to(&original_caller) + .payment(initial_payments) + .transfer(); } let mut err_result = MultiValueEncoded::new(); diff --git a/data/codec-derive/Cargo.toml b/data/codec-derive/Cargo.toml index f0911eb9d6..574b7dcb2c 100644 --- a/data/codec-derive/Cargo.toml +++ b/data/codec-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-codec-derive" -version = "0.18.6" +version = "0.19.0" edition = "2021" authors = ["dorin.iancu ", "Andrei Marinica ", "MultiversX "] @@ -21,7 +21,7 @@ proc-macro = true default = ["syn/full", "syn/parsing", "syn/extra-traits"] [dependencies] -proc-macro2 = "=1.0.78" -quote = "=1.0.35" -syn = "=2.0.48" +proc-macro2 = "=1.0.82" +quote = "=1.0.36" +syn = "=2.0.61" hex = "=0.4.3" diff --git a/data/codec-derive/src/nested_de_derive.rs b/data/codec-derive/src/nested_de_derive.rs index 2eb9d18f41..f24ab1a256 100644 --- a/data/codec-derive/src/nested_de_derive.rs +++ b/data/codec-derive/src/nested_de_derive.rs @@ -27,20 +27,20 @@ pub fn variant_dep_decode_snippets( ) -> Vec { let mut previous_disc: Vec = Vec::new(); data_enum - .variants - .iter() - .enumerate() - .map(|(variant_index, variant)| { + .variants + .iter() + .enumerate() + .map(|(variant_index, variant)| { let variant_discriminant = get_discriminant(variant_index, variant, &mut previous_disc); - let variant_ident = &variant.ident; - let variant_field_snippets = fields_decl_syntax(&variant.fields, |index, field| { - dep_decode_snippet(index, field, input_value) - }); - quote! { + let variant_ident = &variant.ident; + let variant_field_snippets = fields_decl_syntax(&variant.fields, |index, field| { + dep_decode_snippet(index, field, input_value) + }); + quote! { #variant_discriminant => core::result::Result::Ok( #name::#variant_ident #variant_field_snippets ), - } - }) - .collect() + } + }) + .collect() } pub fn nested_decode_impl(ast: &syn::DeriveInput) -> TokenStream { diff --git a/data/codec/Cargo.toml b/data/codec/Cargo.toml index b42b2051b5..d1acc107bf 100644 --- a/data/codec/Cargo.toml +++ b/data/codec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-codec" -version = "0.18.6" +version = "0.19.0" edition = "2021" authors = ["Andrei Marinica ", "MultiversX "] @@ -19,13 +19,14 @@ alloc = [] [dependencies.multiversx-sc-codec-derive] path = "../codec-derive" -version = "=0.18.6" +version = "=0.19.0" optional = true [dependencies] arrayvec = { version = "=0.7.4", default-features = false } -num-bigint = { version = "=0.4.4", optional = true } # can only be used in std contexts +num-bigint = { version = "=0.4.5", optional = true } # can only be used in std contexts +unwrap-infallible = "0.1.5" [dev-dependencies.multiversx-sc-codec-derive] path = "../codec-derive" -version = "=0.18.6" +version = "=0.19.0" diff --git a/data/codec/src/equivalent/codec_convert.rs b/data/codec/src/codec_convert.rs similarity index 71% rename from data/codec/src/equivalent/codec_convert.rs rename to data/codec/src/codec_convert.rs index dadcda2036..566035dfc3 100644 --- a/data/codec/src/equivalent/codec_convert.rs +++ b/data/codec/src/codec_convert.rs @@ -1,17 +1,22 @@ +use unwrap_infallible::UnwrapInfallible; + use crate::{ - CodecFrom, PanicErrorHandler, TopDecodeMultiInput, TopEncodeMulti, TopEncodeMultiOutput, + PanicErrorHandler, TopDecodeMulti, TopDecodeMultiInput, TopEncodeMulti, TopEncodeMultiOutput, }; +/// Little experiment: conversion using the codec. +/// +/// Not used anywhere. pub fn codec_convert_or_panic(from: From) -> To where From: TopEncodeMulti, - To: CodecFrom, + To: TopDecodeMulti, Medium: Default + TopDecodeMultiInput + TopEncodeMultiOutput, { let mut medium: Medium = Default::default(); - let Ok(()) = from.multi_encode_or_handle_err(&mut medium, PanicErrorHandler); - let Ok(result) = To::multi_decode_or_handle_err(&mut medium, PanicErrorHandler); - result + from.multi_encode_or_handle_err(&mut medium, PanicErrorHandler) + .unwrap_infallible(); + To::multi_decode_or_handle_err(&mut medium, PanicErrorHandler).unwrap_infallible() } #[allow(unused)] @@ -32,9 +37,7 @@ mod test { where T1: TopEncodeMulti, T2: TopEncodeMulti, - u32: CodecFrom, - u32: CodecFrom, - R: CodecFrom, + R: TopDecodeMulti, { let conv_x = codec_convert_or_panic::>>(x); let conv_y = codec_convert_or_panic::>>(y); diff --git a/data/codec/src/codec_err.rs b/data/codec/src/codec_err.rs index 34ae889e3f..fd78929764 100644 --- a/data/codec/src/codec_err.rs +++ b/data/codec/src/codec_err.rs @@ -8,15 +8,6 @@ impl From<&'static str> for EncodeError { } } -// TODO: convert to "from_bytes" deprecated method in next minor release. -// Please avoid: it bloats the contract with an unnecessary utf8 validation. -impl From<&'static [u8]> for EncodeError { - #[inline] - fn from(message_bytes: &'static [u8]) -> Self { - EncodeError(core::str::from_utf8(message_bytes).unwrap()) - } -} - impl EncodeError { #[inline] pub fn message_bytes(&self) -> &'static [u8] { @@ -41,15 +32,6 @@ impl From<&'static str> for DecodeError { } } -// TODO: convert to "from_bytes" deprecated method in next minor release. -// Please avoid: it bloats the contract with an unnecessary utf8 validation. -impl From<&'static [u8]> for DecodeError { - #[inline] - fn from(message_bytes: &'static [u8]) -> Self { - DecodeError(core::str::from_utf8(message_bytes).unwrap()) - } -} - impl DecodeError { #[inline] pub fn message_bytes(&self) -> &'static [u8] { @@ -73,34 +55,3 @@ impl DecodeError { pub const MULTI_TOO_FEW_ARGS: DecodeError = DecodeError("too few arguments"); pub const MULTI_TOO_MANY_ARGS: DecodeError = DecodeError("too many arguments"); } - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn decode_error_from_bytes() { - let from_bytes = DecodeError::from(&b"error as bytes"[..]); - assert_eq!(from_bytes.message_bytes(), b"error as bytes"); - assert_eq!(from_bytes.message_str(), "error as bytes"); - } - - #[test] - #[should_panic] - fn decode_error_from_bad_bytes() { - let _ = DecodeError::from(&[0, 159, 146, 150][..]); - } - - #[test] - fn encode_error_from_bytes() { - let from_bytes = EncodeError::from(&b"error as bytes"[..]); - assert_eq!(from_bytes.message_bytes(), b"error as bytes"); - assert_eq!(from_bytes.message_str(), "error as bytes"); - } - - #[test] - #[should_panic] - fn encode_error_from_bad_bytes() { - let _ = EncodeError::from(&[0, 159, 146, 150][..]); - } -} diff --git a/data/codec/src/codec_err_handler.rs b/data/codec/src/codec_err_handler.rs index c7e6d6d90d..e101d07b6e 100644 --- a/data/codec/src/codec_err_handler.rs +++ b/data/codec/src/codec_err_handler.rs @@ -1,3 +1,5 @@ +use core::convert::Infallible; + use crate::{DecodeError, EncodeError}; pub trait EncodeErrorHandler: Copy { @@ -39,7 +41,7 @@ impl DecodeErrorHandler for DefaultErrorHandler { pub struct PanicErrorHandler; impl EncodeErrorHandler for PanicErrorHandler { - type HandledErr = !; + type HandledErr = Infallible; #[inline] fn handle_error(&self, err: EncodeError) -> Self::HandledErr { @@ -48,7 +50,7 @@ impl EncodeErrorHandler for PanicErrorHandler { } impl DecodeErrorHandler for PanicErrorHandler { - type HandledErr = !; + type HandledErr = Infallible; #[inline] fn handle_error(&self, err: DecodeError) -> Self::HandledErr { diff --git a/data/codec/src/equivalent/codec_from.rs b/data/codec/src/equivalent/codec_from.rs deleted file mode 100644 index 27695a56a2..0000000000 --- a/data/codec/src/equivalent/codec_from.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::{TopDecodeMulti, TopEncodeMulti}; - -/// Signals that after serializing `T`, we can safely deserialize it as `Self`. -pub trait CodecFrom: TopDecodeMulti -where - T: TopEncodeMulti, -{ -} - -pub auto trait CodecFromSelf {} - -impl CodecFrom for T where T: TopEncodeMulti + TopDecodeMulti + CodecFromSelf {} - -impl<'a, T> CodecFrom<&'a T> for T -where - &'a T: TopEncodeMulti, - T: TopDecodeMulti, -{ -} - -// Unsigned integer types: the contract can return a smaller capacity result and and we can interpret it as a larger capacity type. - -impl CodecFrom for u64 {} -impl CodecFrom for u64 {} -impl CodecFrom for u64 {} -impl CodecFrom for u64 {} - -impl CodecFrom for u32 {} -impl CodecFrom for u32 {} -impl CodecFrom for u32 {} - -impl CodecFrom for usize {} -impl CodecFrom for usize {} -impl CodecFrom for usize {} - -impl CodecFrom for u16 {} - -// Signed, the same. - -impl CodecFrom for i64 {} -impl CodecFrom for i64 {} -impl CodecFrom for i64 {} -impl CodecFrom for i64 {} - -impl CodecFrom for i32 {} -impl CodecFrom for i32 {} -impl CodecFrom for i32 {} - -impl CodecFrom for isize {} -impl CodecFrom for isize {} -impl CodecFrom for isize {} - -impl CodecFrom for i16 {} diff --git a/data/codec/src/equivalent/codec_into.rs b/data/codec/src/equivalent/codec_into.rs deleted file mode 100644 index 3f4a60cdb2..0000000000 --- a/data/codec/src/equivalent/codec_into.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::{CodecFrom, TopDecodeMulti, TopEncodeMulti}; - -/// Signals that we can safely serialize `Self` in order to obtain a `T` on the other size. -pub trait CodecInto: TopEncodeMulti -where - T: TopDecodeMulti, -{ -} - -impl CodecInto for I -where - I: TopEncodeMulti, - F: CodecFrom, -{ -} diff --git a/data/codec/src/equivalent/mod.rs b/data/codec/src/equivalent/mod.rs deleted file mode 100644 index 3715c4a87c..0000000000 --- a/data/codec/src/equivalent/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod codec_convert; -mod codec_from; -mod codec_into; - -pub use codec_convert::*; -pub use codec_from::{CodecFrom, CodecFromSelf}; -pub use codec_into::CodecInto; diff --git a/data/codec/src/impl_for_types/impl_num_signed.rs b/data/codec/src/impl_for_types/impl_num_signed.rs index 50cb85614e..1f8ea12dcc 100644 --- a/data/codec/src/impl_for_types/impl_num_signed.rs +++ b/data/codec/src/impl_for_types/impl_num_signed.rs @@ -1,7 +1,7 @@ use crate::{ - dep_encode_num_mimic, num_conv::universal_decode_number, DecodeError, DecodeErrorHandler, - EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, NestedEncodeOutput, - TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, + dep_encode_num_mimic, DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, + NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, + TopEncodeOutput, }; macro_rules! top_encode_num_signed { @@ -42,7 +42,7 @@ macro_rules! dep_decode_num_signed { { let mut bytes = [0u8; $num_bytes]; input.read_into(&mut bytes[..], h)?; - let num = universal_decode_number(&bytes[..], true) as $ty; + let num = <$ty>::from_be_bytes(bytes); Ok(num) } } @@ -52,9 +52,18 @@ macro_rules! dep_decode_num_signed { dep_decode_num_signed!(i8, 1); dep_decode_num_signed!(i16, 2); dep_decode_num_signed!(i32, 4); -dep_decode_num_signed!(isize, 4); dep_decode_num_signed!(i64, 8); +impl NestedDecode for isize { + fn dep_decode_or_handle_err(input: &mut I, h: H) -> Result + where + I: NestedDecodeInput, + H: DecodeErrorHandler, + { + i32::dep_decode_or_handle_err(input, h).map(|num| num as isize) + } +} + macro_rules! top_decode_num_signed { ($ty:ty, $bounds_ty:ty) => { impl TopDecode for $ty { diff --git a/data/codec/src/impl_for_types/impl_num_unsigned.rs b/data/codec/src/impl_for_types/impl_num_unsigned.rs index b9e98051fc..40c84fef64 100644 --- a/data/codec/src/impl_for_types/impl_num_unsigned.rs +++ b/data/codec/src/impl_for_types/impl_num_unsigned.rs @@ -1,7 +1,7 @@ use crate::{ - dep_encode_num_mimic, num_conv::universal_decode_number, DecodeError, DecodeErrorHandler, - EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, NestedEncodeOutput, - TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, + dep_encode_num_mimic, DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, + NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, + TopEncodeOutput, }; // No reversing needed for u8, because it is a single byte. @@ -102,7 +102,7 @@ macro_rules! dep_decode_num_unsigned { { let mut bytes = [0u8; $num_bytes]; input.read_into(&mut bytes[..], h)?; - let num = universal_decode_number(&bytes[..], false) as $ty; + let num = <$ty>::from_be_bytes(bytes); Ok(num) } } @@ -111,9 +111,18 @@ macro_rules! dep_decode_num_unsigned { dep_decode_num_unsigned!(u16, 2); dep_decode_num_unsigned!(u32, 4); -dep_decode_num_unsigned!(usize, 4); dep_decode_num_unsigned!(u64, 8); +impl NestedDecode for usize { + fn dep_decode_or_handle_err(input: &mut I, h: H) -> Result + where + I: NestedDecodeInput, + H: DecodeErrorHandler, + { + u32::dep_decode_or_handle_err(input, h).map(|num| num as usize) + } +} + macro_rules! top_decode_num_unsigned { ($ty:ty, $bounds_ty:ty) => { impl TopDecode for $ty { diff --git a/data/codec/src/impl_for_types/impl_tuple.rs b/data/codec/src/impl_for_types/impl_tuple.rs index c59ead5126..b5278a92b5 100644 --- a/data/codec/src/impl_for_types/impl_tuple.rs +++ b/data/codec/src/impl_for_types/impl_tuple.rs @@ -11,18 +11,18 @@ macro_rules! tuple_impls { where $($name: NestedEncode,)+ { - fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> where O: TopEncodeOutput, H: EncodeErrorHandler, { - let mut buffer = output.start_nested_encode(); - $( + let mut buffer = output.start_nested_encode(); + $( self.$n.dep_encode_or_handle_err(&mut buffer, h)?; )+ - output.finalize_nested_encode(buffer); - Ok(()) - } + output.finalize_nested_encode(buffer); + Ok(()) + } } impl<$($name),+> TopDecode for ($($name,)+) @@ -42,16 +42,16 @@ macro_rules! tuple_impls { where $($name: NestedEncode,)+ { - fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> + fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> where O: NestedEncodeOutput, H: EncodeErrorHandler, { - $( + $( self.$n.dep_encode_or_handle_err(dest, h)?; )+ - Ok(()) - } + Ok(()) + } } impl<$($name),+> NestedDecode for ($($name,)+) diff --git a/data/codec/src/lib.rs b/data/codec/src/lib.rs index cea3384871..dac8727604 100644 --- a/data/codec/src/lib.rs +++ b/data/codec/src/lib.rs @@ -1,9 +1,4 @@ #![no_std] -#![feature(try_trait_v2)] -#![feature(never_type)] -#![feature(exhaustive_patterns)] -#![feature(auto_traits)] -#![feature(negative_impls)] extern crate alloc; @@ -22,10 +17,10 @@ pub use num_bigint; // TODO: group into smaller sub-modules +pub mod codec_convert; mod codec_err; mod codec_err_handler; mod default_traits; -mod equivalent; mod impl_for_types; mod multi; pub mod multi_types; @@ -44,7 +39,6 @@ pub use crate::{ pub use codec_err::{DecodeError, EncodeError}; pub use codec_err_handler::*; pub use default_traits::{DecodeDefault, EncodeDefault}; -pub use equivalent::*; pub use impl_for_types::impl_empty::Empty; pub use multi::*; pub use single::*; diff --git a/data/codec/src/multi_types/multi_value_ignore.rs b/data/codec/src/multi_types/multi_value_ignore.rs index 3522315a86..a621c76d22 100644 --- a/data/codec/src/multi_types/multi_value_ignore.rs +++ b/data/codec/src/multi_types/multi_value_ignore.rs @@ -1,6 +1,6 @@ use crate::{ - CodecFrom, CodecFromSelf, DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, - TopDecodeMultiInput, TopEncodeMulti, TopEncodeMultiOutput, + DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, TopEncodeMulti, + TopEncodeMultiOutput, }; /// Structure that allows taking a variable number of arguments, @@ -28,6 +28,3 @@ impl TopDecodeMulti for IgnoreValue { Ok(IgnoreValue) } } - -impl !CodecFromSelf for IgnoreValue {} -impl CodecFrom for IgnoreValue where T: TopEncodeMulti {} diff --git a/data/codec/src/multi_types/multi_value_optional.rs b/data/codec/src/multi_types/multi_value_optional.rs index d634d2a7e5..bcdf2a6460 100644 --- a/data/codec/src/multi_types/multi_value_optional.rs +++ b/data/codec/src/multi_types/multi_value_optional.rs @@ -1,8 +1,8 @@ use core::fmt::Debug; use crate::{ - CodecFrom, CodecFromSelf, DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, - TopDecodeMultiInput, TopEncodeMulti, TopEncodeMultiOutput, + DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, TopEncodeMulti, + TopEncodeMultiOutput, }; /// A smart contract argument or result that can be missing. @@ -80,23 +80,6 @@ where } } -impl !CodecFromSelf for OptionalValue {} - -impl CodecFrom> for OptionalValue -where - T: TopEncodeMulti + TopDecodeMulti, - U: CodecFrom, - OptionalValue: TopEncodeMulti, -{ -} - -impl CodecFrom for OptionalValue -where - T: TopEncodeMulti + TopDecodeMulti, - U: CodecFrom + CodecFromSelf + TopEncodeMulti + TopDecodeMulti, -{ -} - impl Debug for OptionalValue where T: Debug, diff --git a/data/codec/src/multi_types/multi_value_placeholder.rs b/data/codec/src/multi_types/multi_value_placeholder.rs index 1265342f9f..34b4af73a3 100644 --- a/data/codec/src/multi_types/multi_value_placeholder.rs +++ b/data/codec/src/multi_types/multi_value_placeholder.rs @@ -1,6 +1,6 @@ use crate::{ - CodecFrom, CodecFromSelf, DecodeError, DecodeErrorHandler, EncodeError, EncodeErrorHandler, - TopDecodeMulti, TopDecodeMultiInput, TopEncodeMulti, TopEncodeMultiOutput, + DecodeError, DecodeErrorHandler, EncodeError, EncodeErrorHandler, TopDecodeMulti, + TopDecodeMultiInput, TopEncodeMulti, TopEncodeMultiOutput, }; /// Temporary value used for any kind of templates. @@ -19,9 +19,6 @@ impl TopEncodeMulti for PlaceholderInput { } } -impl !CodecFromSelf for PlaceholderInput {} -impl CodecFrom for T where T: TopDecodeMulti + CodecFromSelf {} - /// Temporary value used for any kind of templates. /// /// Can be used for compiling example code, in which it decodes from anything, but will always fail at runtime. @@ -37,6 +34,3 @@ impl TopDecodeMulti for PlaceholderOutput { Err(h.handle_error(DecodeError::from("placeholder only, cannot decode"))) } } - -impl !CodecFromSelf for PlaceholderOutput {} -impl CodecFrom for PlaceholderOutput where T: TopEncodeMulti + CodecFromSelf {} diff --git a/data/codec/src/num_conv.rs b/data/codec/src/num_conv.rs index cfca20180b..978aab3280 100644 --- a/data/codec/src/num_conv.rs +++ b/data/codec/src/num_conv.rs @@ -110,23 +110,27 @@ fn fill_buffer_find_offset(x: u64, signed: bool, buffer: &mut TopEncodeNumberBuf /// /// No generics here, we avoid monomorphization to make the SC binary as small as possible. pub fn universal_decode_number(bytes: &[u8], signed: bool) -> u64 { - if bytes.is_empty() { - return 0; - } - let negative = signed && msbit_is_one(bytes[0]); - let mut result = if negative { - // start with all bits set to 1, - // to ensure that if there are fewer bytes than the result type width, - // the leading bits will be 1 instead of 0 - u64::MAX - } else { - 0u64 - }; - for byte in bytes.iter() { - result <<= 8; - result |= *byte as u64; - } - result + // it is almost impossible to get a slice longer than 8 + // just a basic overflow/underflow protection + let safe_len = bytes.len() % 9; + + unsafe { universal_decode_number_impl(bytes.as_ptr(), safe_len, signed) } +} + +/// Same as [`universal_decode_number`], but assumes that the input length does not exceed 8. +pub fn universal_decode_number_unchecked(bytes: &[u8], signed: bool) -> u64 { + unsafe { universal_decode_number_impl(bytes.as_ptr(), bytes.len(), signed) } +} + +unsafe fn universal_decode_number_impl(bytes: *const u8, len: usize, signed: bool) -> u64 { + let negative = signed && len > 0 && msbit_is_one(*bytes); + let skippable_byte = skippable_byte(negative); + + let mut extended_buffer = [skippable_byte; 8]; + let offset = 8usize.wrapping_sub(len); + core::ptr::copy_nonoverlapping(bytes, extended_buffer.as_mut_ptr().add(offset), len); + + u64::from_be_bytes(extended_buffer) } /// Most significant bit is 1. diff --git a/data/codec/src/single/top_de_input.rs b/data/codec/src/single/top_de_input.rs index 594785c35c..dd106d26a0 100644 --- a/data/codec/src/single/top_de_input.rs +++ b/data/codec/src/single/top_de_input.rs @@ -1,6 +1,7 @@ use crate::{ - num_conv::universal_decode_number, transmute::vec_into_boxed_slice, DecodeError, - DecodeErrorHandler, NestedDecodeInput, OwnedBytesNestedDecodeInput, TryStaticCast, + num_conv::{universal_decode_number, universal_decode_number_unchecked}, + transmute::vec_into_boxed_slice, + DecodeError, DecodeErrorHandler, NestedDecodeInput, OwnedBytesNestedDecodeInput, TryStaticCast, }; use alloc::{boxed::Box, vec::Vec}; @@ -20,6 +21,12 @@ pub trait TopDecodeInput: Sized { /// and returns the populated data slice from this buffer. /// /// Will return an error if the data exceeds the provided buffer. + /// + /// Currently only kept for backwards compatibility. + #[deprecated( + since = "0.48.1", + note = "Please use method `into_max_size_buffer_align_right` instead." + )] fn into_max_size_buffer( self, buffer: &mut [u8; MAX_LEN], @@ -28,6 +35,20 @@ pub trait TopDecodeInput: Sized { where H: DecodeErrorHandler; + /// Puts the underlying data into a fixed size byte buffer, + /// aligned to the right. + /// + /// This eases big endian decoding. + /// + /// Returns the length of the original buffer. + fn into_max_size_buffer_align_right( + self, + buffer: &mut [u8; MAX_LEN], + h: H, + ) -> Result + where + H: DecodeErrorHandler; + /// Retrieves the underlying data as a pre-parsed u64. /// Expected to panic if the conversion is not possible. /// @@ -37,8 +58,8 @@ pub trait TopDecodeInput: Sized { H: DecodeErrorHandler, { let mut buffer = [0u8; 8]; - let slice = self.into_max_size_buffer(&mut buffer, h)?; - Ok(universal_decode_number(slice, false)) + let _ = self.into_max_size_buffer_align_right(&mut buffer, h)?; + Ok(u64::from_be_bytes(buffer)) } /// Retrieves the underlying data as a pre-parsed i64. @@ -50,8 +71,8 @@ pub trait TopDecodeInput: Sized { H: DecodeErrorHandler, { let mut buffer = [0u8; 8]; - let slice = self.into_max_size_buffer(&mut buffer, h)?; - Ok(universal_decode_number(slice, true) as i64) + let len = self.into_max_size_buffer_align_right(&mut buffer, h)?; + Ok(universal_decode_number_unchecked(&buffer[8 - len..], true) as i64) } #[inline] @@ -81,6 +102,7 @@ impl TopDecodeInput for Box<[u8]> { self } + #[allow(deprecated)] fn into_max_size_buffer( self, buffer: &mut [u8; MAX_LEN], @@ -92,6 +114,17 @@ impl TopDecodeInput for Box<[u8]> { (&*self).into_max_size_buffer(buffer, h) } + fn into_max_size_buffer_align_right( + self, + buffer: &mut [u8; MAX_LEN], + h: H, + ) -> Result + where + H: DecodeErrorHandler, + { + (&*self).into_max_size_buffer_align_right(buffer, h) + } + fn into_nested_buffer(self) -> Self::NestedBuffer { OwnedBytesNestedDecodeInput::new(self) } @@ -108,6 +141,7 @@ impl TopDecodeInput for Vec { vec_into_boxed_slice(self) } + #[allow(deprecated)] fn into_max_size_buffer( self, buffer: &mut [u8; MAX_LEN], @@ -119,6 +153,17 @@ impl TopDecodeInput for Vec { self.as_slice().into_max_size_buffer(buffer, h) } + fn into_max_size_buffer_align_right( + self, + buffer: &mut [u8; MAX_LEN], + h: H, + ) -> Result + where + H: DecodeErrorHandler, + { + self.as_slice().into_max_size_buffer_align_right(buffer, h) + } + fn into_nested_buffer(self) -> Self::NestedBuffer { OwnedBytesNestedDecodeInput::new(self.into_boxed_slice()) } @@ -151,6 +196,24 @@ impl<'a> TopDecodeInput for &'a [u8] { Ok(&buffer[..l]) } + fn into_max_size_buffer_align_right( + self, + buffer: &mut [u8; MAX_LEN], + h: H, + ) -> Result + where + H: DecodeErrorHandler, + { + let len = self.len(); + if len > MAX_LEN { + return Err(h.handle_error(DecodeError::INPUT_TOO_LONG)); + } + let target_start = MAX_LEN - len; + let byte_slice = &mut buffer[target_start..]; + byte_slice.copy_from_slice(self); + Ok(len) + } + #[inline] fn into_u64(self, _h: H) -> Result where diff --git a/data/codec/src/single/top_en.rs b/data/codec/src/single/top_en.rs index 2826c7d3d2..dd131ffc1f 100644 --- a/data/codec/src/single/top_en.rs +++ b/data/codec/src/single/top_en.rs @@ -3,6 +3,7 @@ use crate::{ PanicErrorHandler, TopEncodeOutput, }; use alloc::vec::Vec; +use unwrap_infallible::UnwrapInfallible; pub trait TopEncode: Sized { /// Attempt to serialize the value to ouput. @@ -48,6 +49,7 @@ pub fn top_encode_to_vec_u8(obj: &T) -> Result, EncodeErro pub fn top_encode_to_vec_u8_or_panic(obj: &T) -> Vec { let mut bytes = Vec::::new(); - let Ok(()) = obj.top_encode_or_handle_err(&mut bytes, PanicErrorHandler); + obj.top_encode_or_handle_err(&mut bytes, PanicErrorHandler) + .unwrap_infallible(); bytes } diff --git a/data/codec/src/test_util.rs b/data/codec/src/test_util.rs index d8155a082c..1733fff8b9 100644 --- a/data/codec/src/test_util.rs +++ b/data/codec/src/test_util.rs @@ -1,12 +1,14 @@ use crate::*; use alloc::vec::Vec; use core::fmt::Debug; +use unwrap_infallible::UnwrapInfallible; /// Calls top encode and panics if an encoding error occurs. /// Do not use in smart contracts! pub fn top_encode_to_vec_u8_or_panic(obj: &T) -> Vec { let mut bytes = Vec::::new(); - let Ok(()) = obj.top_encode_or_handle_err(&mut bytes, PanicErrorHandler); + obj.top_encode_or_handle_err(&mut bytes, PanicErrorHandler) + .unwrap_infallible(); bytes } @@ -14,7 +16,8 @@ pub fn top_encode_to_vec_u8_or_panic(obj: &T) -> Vec { /// Do not use in smart contracts! pub fn dep_encode_to_vec_or_panic(obj: &T) -> Vec { let mut bytes = Vec::::new(); - let Ok(()) = obj.dep_encode_or_handle_err(&mut bytes, PanicErrorHandler); + obj.dep_encode_or_handle_err(&mut bytes, PanicErrorHandler) + .unwrap_infallible(); bytes } @@ -41,15 +44,14 @@ pub fn check_dep_encode(obj: &T) -> Vec { /// Calls nested decode and panics if an encoding error occurs. /// Do not use in smart contracts! pub fn dep_decode_from_byte_slice_or_panic(input: &[u8]) -> T { - let Ok(result) = dep_decode_from_byte_slice(input, PanicErrorHandler); - result + dep_decode_from_byte_slice(input, PanicErrorHandler).unwrap_infallible() } /// Calls both the fast exit and the regular top-decode, /// compares that the outputs are equal, then returns the result. /// To be used in serialization tests. pub fn check_top_decode(bytes: &[u8]) -> T { - let Ok(fast_exit_obj) = T::top_decode_or_handle_err(bytes, PanicErrorHandler); + let fast_exit_obj = T::top_decode_or_handle_err(bytes, PanicErrorHandler).unwrap_infallible(); let result_obj = T::top_decode_or_handle_err(bytes, DefaultErrorHandler).unwrap(); assert_eq!(fast_exit_obj, result_obj); fast_exit_obj @@ -59,7 +61,7 @@ pub fn check_top_decode(bytes: &[u8]) -> T { /// compares that the outputs are equal, then returns the result. /// To be used in serialization tests. pub fn check_dep_decode(bytes: &[u8]) -> T { - let Ok(fast_exit_obj) = dep_decode_from_byte_slice(bytes, PanicErrorHandler); + let fast_exit_obj = dep_decode_from_byte_slice(bytes, PanicErrorHandler).unwrap_infallible(); let result_obj = dep_decode_from_byte_slice(bytes, DefaultErrorHandler).unwrap(); assert_eq!(fast_exit_obj, result_obj); fast_exit_obj diff --git a/data/codec/tests/derive_enum_or_default_test.rs b/data/codec/tests/derive_enum_or_default_test.rs index 24d1017654..7d9b57c755 100644 --- a/data/codec/tests/derive_enum_or_default_test.rs +++ b/data/codec/tests/derive_enum_or_default_test.rs @@ -53,15 +53,15 @@ fn enum_not_defaults() { }; #[rustfmt::skip] - let enum_struct_bytes = &[ - /* discriminant */ 2, - /* int */ 0, 0x42, - /* seq length */ 0, 0, 0, 5, - /* seq contents */ 1, 2, 3, 4, 5, - /* another_byte */ 6, - /* uint_32 */ 0x00, 0x01, 0x23, 0x45, - /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, - ]; + let enum_struct_bytes = &[ + /* discriminant */ 2, + /* int */ 0, 0x42, + /* seq length */ 0, 0, 0, 5, + /* seq contents */ 1, 2, 3, 4, 5, + /* another_byte */ 6, + /* uint_32 */ 0x00, 0x01, 0x23, 0x45, + /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, + ]; check_top_encode_decode(enum_struct, enum_struct_bytes); } diff --git a/data/codec/tests/derive_enum_test.rs b/data/codec/tests/derive_enum_test.rs index b4626400ac..bd798b33ee 100644 --- a/data/codec/tests/derive_enum_test.rs +++ b/data/codec/tests/derive_enum_test.rs @@ -68,11 +68,11 @@ fn field_enum_variant_with_value() { let enum_tuple_0 = EnumWithEverything::Write(Vec::new(), 0); #[rustfmt::skip] - let enum_tuple_0_bytes = &[ - /* discriminant */ 2, - /* vec length */ 0, 0, 0, 0, - /* u16 */ 0, 0, - ]; + let enum_tuple_0_bytes = &[ + /* discriminant */ 2, + /* vec length */ 0, 0, 0, 0, + /* u16 */ 0, 0, + ]; check_top_encode_decode(enum_tuple_0.clone(), enum_tuple_0_bytes); check_dep_encode_decode(enum_tuple_0, enum_tuple_0_bytes); } @@ -81,12 +81,12 @@ fn field_enum_variant_with_value() { fn field_enum_variant_with_tuple() { let enum_tuple_1 = EnumWithEverything::Write([1, 2, 3].to_vec(), 4); #[rustfmt::skip] - let enum_tuple_1_bytes = &[ - /* discriminant */ 2, - /* vec length */ 0, 0, 0, 3, - /* vec contents */ 1, 2, 3, - /* an extra 16 */ 0, 4, - ]; + let enum_tuple_1_bytes = &[ + /* discriminant */ 2, + /* vec length */ 0, 0, 0, 3, + /* vec contents */ 1, 2, 3, + /* an extra 16 */ 0, 4, + ]; check_top_encode_decode(enum_tuple_1.clone(), enum_tuple_1_bytes); check_dep_encode_decode(enum_tuple_1, enum_tuple_1_bytes); @@ -103,15 +103,15 @@ fn field_enum_struct_variant() { }; #[rustfmt::skip] - let enum_struct_bytes = &[ - /* discriminant */ 3, - /* int */ 0, 0x42, - /* seq length */ 0, 0, 0, 5, - /* seq contents */ 1, 2, 3, 4, 5, - /* another_byte */ 6, - /* uint_32 */ 0x00, 0x01, 0x23, 0x45, - /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, - ]; + let enum_struct_bytes = &[ + /* discriminant */ 3, + /* int */ 0, 0x42, + /* seq length */ 0, 0, 0, 5, + /* seq contents */ 1, 2, 3, 4, 5, + /* another_byte */ 6, + /* uint_32 */ 0x00, 0x01, 0x23, 0x45, + /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, + ]; check_top_encode_decode(enum_struct.clone(), enum_struct_bytes); check_dep_encode_decode(enum_struct, enum_struct_bytes); diff --git a/data/codec/tests/derive_hygiene.rs b/data/codec/tests/derive_hygiene.rs index 4f9cc5e1f9..1ac67e6478 100644 --- a/data/codec/tests/derive_hygiene.rs +++ b/data/codec/tests/derive_hygiene.rs @@ -35,6 +35,7 @@ use crate::Result::{Err, Ok}; // They are not used in the derive, but just to make sure: fn top_encode_number() {} fn universal_decode_number() {} +fn universal_decode_number_unchecked() {} fn dep_decode_from_byte_slice() {} fn dep_encode_to_vec() {} fn top_decode_from_nested_or_handle_err() {} diff --git a/data/codec/tests/derive_struct_or_default_generic_test.rs b/data/codec/tests/derive_struct_or_default_generic_test.rs index e8ab6bbe20..d7631b0ae2 100644 --- a/data/codec/tests/derive_struct_or_default_generic_test.rs +++ b/data/codec/tests/derive_struct_or_default_generic_test.rs @@ -63,14 +63,14 @@ fn struct_or_default_not_default() { }; #[rustfmt::skip] - let bytes_1 = &[ - /* int */ 0, 0x42, - /* seq length */ 0, 0, 0, 5, - /* seq contents */ 1, 2, 3, 4, 5, - /* another_byte */ 6, - /* uint_32 */ 0x00, 0x01, 0x23, 0x45, - /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, - ]; + let bytes_1 = &[ + /* int */ 0, 0x42, + /* seq length */ 0, 0, 0, 5, + /* seq contents */ 1, 2, 3, 4, 5, + /* another_byte */ 6, + /* uint_32 */ 0x00, 0x01, 0x23, 0x45, + /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, + ]; check_top_encode_decode(s, bytes_1); } diff --git a/data/codec/tests/derive_struct_or_default_test.rs b/data/codec/tests/derive_struct_or_default_test.rs index 1b75d5962c..8953b94dc6 100644 --- a/data/codec/tests/derive_struct_or_default_test.rs +++ b/data/codec/tests/derive_struct_or_default_test.rs @@ -54,14 +54,14 @@ fn struct_or_default_not_default() { }; #[rustfmt::skip] - let bytes_1 = &[ - /* int */ 0, 0x42, - /* seq length */ 0, 0, 0, 5, - /* seq contents */ 1, 2, 3, 4, 5, - /* another_byte */ 6, - /* uint_32 */ 0x00, 0x01, 0x23, 0x45, - /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, - ]; + let bytes_1 = &[ + /* int */ 0, 0x42, + /* seq length */ 0, 0, 0, 5, + /* seq contents */ 1, 2, 3, 4, 5, + /* another_byte */ 6, + /* uint_32 */ 0x00, 0x01, 0x23, 0x45, + /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, + ]; check_top_encode_decode(s, bytes_1); } diff --git a/data/codec/tests/derive_struct_test.rs b/data/codec/tests/derive_struct_test.rs index b7967dd9ae..fbe293b7e1 100644 --- a/data/codec/tests/derive_struct_test.rs +++ b/data/codec/tests/derive_struct_test.rs @@ -26,14 +26,14 @@ fn struct_named_fields_test() { }; #[rustfmt::skip] - let bytes_1 = &[ - /* int */ 0, 0x42, - /* seq length */ 0, 0, 0, 5, - /* seq contents */ 1, 2, 3, 4, 5, - /* another_byte */ 6, - /* uint_32 */ 0x00, 0x01, 0x23, 0x45, - /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, - ]; + let bytes_1 = &[ + /* int */ 0, 0x42, + /* seq length */ 0, 0, 0, 5, + /* seq contents */ 1, 2, 3, 4, 5, + /* another_byte */ 6, + /* uint_32 */ 0x00, 0x01, 0x23, 0x45, + /* uint_64 */ 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, + ]; check_top_encode_decode(s.clone(), bytes_1); check_dep_encode_decode(s, bytes_1); diff --git a/data/codec/tests/derive_struct_with_generic_test.rs b/data/codec/tests/derive_struct_with_generic_test.rs index 80739b01b1..bde74b0a9d 100644 --- a/data/codec/tests/derive_struct_with_generic_test.rs +++ b/data/codec/tests/derive_struct_with_generic_test.rs @@ -9,6 +9,7 @@ use codec::{ // to test, run the following command in the crate folder: // cargo expand --test struct_with_generic_derive_test > expanded.rs +#[allow(dead_code)] trait SimpleTrait { fn simple_function(&self); } diff --git a/data/codec/tests/derive_tuple_struct_test.rs b/data/codec/tests/derive_tuple_struct_test.rs index 53e17ff529..4d6b3c9559 100644 --- a/data/codec/tests/derive_tuple_struct_test.rs +++ b/data/codec/tests/derive_tuple_struct_test.rs @@ -14,11 +14,11 @@ fn tuple_struct_derive_test() { let s = TupleStruct(8, 16, 32); #[rustfmt::skip] - let bytes = &[ - /* 0: u8 */ 8, - /* 1: u32 */ 0, 16, - /* 2: u64 */ 0, 0, 0, 32, - ]; + let bytes = &[ + /* 0: u8 */ 8, + /* 1: u32 */ 0, 16, + /* 2: u64 */ 0, 0, 0, 32, + ]; check_top_encode_decode(s.clone(), bytes); check_dep_encode_decode(s, bytes); diff --git a/framework/base/Cargo.toml b/framework/base/Cargo.toml index ad2b6e260c..3e348fd6d0 100644 --- a/framework/base/Cargo.toml +++ b/framework/base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc" -version = "0.47.5" +version = "0.50.3" edition = "2021" authors = ["Andrei Marinica ", "MultiversX "] @@ -19,18 +19,20 @@ all-features = true [features] num-bigint = ["multiversx-sc-codec/num-bigint"] alloc = ["multiversx-sc-codec/alloc"] +managed-buffer-builder-cached = [] esdt-token-payment-legacy-decode = [] [dependencies] hex-literal = "=0.4.1" -bitflags = "=2.4.2" -num-traits = { version = "=0.2.17", default-features = false } +bitflags = "=2.5.0" +num-traits = { version = "=0.2.19", default-features = false } +unwrap-infallible = "0.1.5" [dependencies.multiversx-sc-derive] -version = "=0.47.5" +version = "=0.50.3" path = "../derive" [dependencies.multiversx-sc-codec] -version = "=0.18.6" +version = "=0.19.0" path = "../../data/codec" features = ["derive"] diff --git a/framework/base/src/abi.rs b/framework/base/src/abi.rs index b79ae26124..c031a62166 100644 --- a/framework/base/src/abi.rs +++ b/framework/base/src/abi.rs @@ -4,18 +4,38 @@ mod endpoint_abi; mod esdt_attribute_abi; mod event_abi; mod type_abi; +mod type_abi_from; mod type_abi_impl_basic; mod type_abi_impl_codec_multi; mod type_description; mod type_description_container; +#[cfg(feature = "num-bigint")] +mod type_abi_impl_big_int; + pub use build_info_abi::*; pub use contract_abi::*; pub use endpoint_abi::*; pub use esdt_attribute_abi::EsdtAttributeAbi; pub use event_abi::*; pub use type_abi::*; +pub use type_abi_from::*; pub use type_description::*; pub use type_description_container::*; pub type TypeName = alloc::string::String; + +#[derive(Clone, Default, Debug, PartialEq, Eq)] +pub struct TypeNames { + pub abi: alloc::string::String, + pub rust: alloc::string::String, +} + +impl TypeNames { + pub const fn new() -> Self { + TypeNames { + abi: alloc::string::String::new(), + rust: alloc::string::String::new(), + } + } +} diff --git a/framework/base/src/abi/contract_abi.rs b/framework/base/src/abi/contract_abi.rs index 3b22d160e7..2c8ad67fba 100644 --- a/framework/base/src/abi/contract_abi.rs +++ b/framework/base/src/abi/contract_abi.rs @@ -10,6 +10,7 @@ pub struct ContractAbi { pub docs: Vec, pub name: String, pub constructors: Vec, + pub upgrade_constructors: Vec, pub endpoints: Vec, pub promise_callbacks: Vec, pub events: Vec, @@ -26,6 +27,7 @@ impl ContractAbi { docs: docs.iter().map(|s| s.to_string()).collect(), name: name.to_string(), constructors: Vec::new(), + upgrade_constructors: Vec::new(), endpoints: Vec::new(), promise_callbacks: Vec::new(), events: Vec::new(), @@ -39,6 +41,8 @@ impl ContractAbi { self.constructors .extend_from_slice(other.constructors.as_slice()); self.endpoints.extend_from_slice(other.endpoints.as_slice()); + self.upgrade_constructors + .extend_from_slice(other.upgrade_constructors.as_slice()); self.events.extend_from_slice(other.events.as_slice()); self.promise_callbacks .extend_from_slice(other.promise_callbacks.as_slice()); @@ -75,6 +79,7 @@ impl ContractAbi { pub fn iter_all_exports(&self) -> impl Iterator { self.constructors .iter() + .chain(self.upgrade_constructors.iter()) .chain(self.endpoints.iter()) .chain(self.promise_callbacks.iter()) } diff --git a/framework/base/src/abi/endpoint_abi.rs b/framework/base/src/abi/endpoint_abi.rs index 1ce6b5c363..03e098d0e9 100644 --- a/framework/base/src/abi/endpoint_abi.rs +++ b/framework/base/src/abi/endpoint_abi.rs @@ -7,15 +7,14 @@ use alloc::{ #[derive(Clone, Debug)] pub struct InputAbi { pub arg_name: String, - pub type_name: TypeName, - // pub original_type_name: TypeName, + pub type_names: TypeNames, pub multi_arg: bool, } #[derive(Clone, Debug)] pub struct OutputAbi { pub output_name: String, - pub type_name: TypeName, + pub type_names: TypeNames, pub multi_result: bool, } @@ -33,6 +32,7 @@ pub enum EndpointMutabilityAbi { pub enum EndpointTypeAbi { #[default] Init, + Upgrade, Endpoint, PromisesCallback, } @@ -89,7 +89,7 @@ impl EndpointAbi { pub fn add_input(&mut self, arg_name: &str) { self.inputs.push(InputAbi { arg_name: arg_name.to_string(), - type_name: T::type_name(), + type_names: T::type_names(), multi_arg: T::is_variadic(), }); } diff --git a/framework/base/src/abi/type_abi.rs b/framework/base/src/abi/type_abi.rs index cdf6c153ac..3e4c451b48 100644 --- a/framework/base/src/abi/type_abi.rs +++ b/framework/base/src/abi/type_abi.rs @@ -1,23 +1,44 @@ use super::*; -use alloc::{string::ToString, vec::Vec}; +use alloc::{format, string::ToString, vec::Vec}; + +/// Implemented for all types that can end up in the ABI: +/// - argument types, +/// - result types, +/// - event log arguments +/// - etc. +/// +/// Will be automatically implemented for struct ad enum types via the `#[type_abi]` annotation. +pub trait TypeAbi: TypeAbiFrom { + type Unmanaged; + + fn type_names() -> TypeNames { + TypeNames { + abi: Self::type_name(), + rust: Self::type_name_rust(), + } + } -pub trait TypeAbi { fn type_name() -> TypeName { core::any::type_name::().into() } + fn type_name_rust() -> TypeName { + core::any::type_name::().into() + } + /// A type can provide more than its own name. /// For instance, a struct can also provide the descriptions of the type of its fields. /// TypeAbi doesn't care for the exact accumulator type, /// which is abstracted by the TypeDescriptionContainer trait. fn provide_type_descriptions(accumulator: &mut TDC) { - let type_name = Self::type_name(); + let type_names = Self::type_names(); accumulator.insert( - type_name, + type_names, TypeDescription { docs: Vec::new(), - name: Self::type_name(), + names: Self::type_names(), contents: TypeContents::NotSpecified, + macro_attributes: Vec::new(), }, ); } @@ -44,7 +65,7 @@ pub trait TypeAbi { }; result.push(OutputAbi { output_name: output_name.to_string(), - type_name: Self::type_name(), + type_names: Self::type_names(), multi_result: Self::is_variadic(), }); result @@ -52,10 +73,11 @@ pub trait TypeAbi { } pub fn type_name_variadic() -> TypeName { - let mut repr = TypeName::from("variadic<"); - repr.push_str(T::type_name().as_str()); - repr.push('>'); - repr + format!("variadic<{}>", T::type_name()) +} + +pub fn type_name_multi_value_encoded() -> TypeName { + format!("MultiValueEncoded<$API, {}>", T::type_name_rust()) } pub fn type_name_optional() -> TypeName { diff --git a/framework/base/src/abi/type_abi_from.rs b/framework/base/src/abi/type_abi_from.rs new file mode 100644 index 0000000000..81f5345fd5 --- /dev/null +++ b/framework/base/src/abi/type_abi_from.rs @@ -0,0 +1,4 @@ +/// Indicates that 2 types have the same encoding, so they can be used interchangeably in proxies. +/// +/// Only relevant for serializable types. +pub trait TypeAbiFrom {} diff --git a/framework/base/src/abi/type_abi_impl_basic.rs b/framework/base/src/abi/type_abi_impl_basic.rs index 00965215de..2961604bb9 100644 --- a/framework/base/src/abi/type_abi_impl_basic.rs +++ b/framework/base/src/abi/type_abi_impl_basic.rs @@ -2,11 +2,16 @@ use super::*; use crate::arrayvec::ArrayVec; use alloc::{ boxed::Box, + format, string::{String, ToString}, vec::Vec, }; +impl TypeAbiFrom<()> for () {} + impl TypeAbi for () { + type Unmanaged = Self; + /// No another exception from the 1-type-1-output-abi rule: /// the unit type produces no output. fn output_abis(_output_names: &[&'static str]) -> OutputAbis { @@ -14,27 +19,47 @@ impl TypeAbi for () { } } +impl TypeAbiFrom<&U> for &T where T: TypeAbiFrom {} + impl TypeAbi for &T { + type Unmanaged = T::Unmanaged; + fn type_name() -> TypeName { T::type_name() } + fn type_name_rust() -> TypeName { + T::type_name_rust() + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } } +impl TypeAbiFrom> for Box where T: TypeAbiFrom {} + impl TypeAbi for Box { + type Unmanaged = Self; + fn type_name() -> TypeName { T::type_name() } + fn type_name_rust() -> TypeName { + format!("Box<{}>", T::type_name_rust()) + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } } +impl TypeAbiFrom<&[T]> for &[U] where T: TypeAbiFrom {} + impl TypeAbi for &[T] { + type Unmanaged = Vec; + fn type_name() -> TypeName { let t_name = T::type_name(); if t_name == "u8" { @@ -46,62 +71,121 @@ impl TypeAbi for &[T] { repr } + fn type_name_rust() -> TypeName { + // we need to convert to an owned type + format!("Box<[{}]>", T::type_name_rust()) + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } } +impl TypeAbiFrom> for Vec where T: TypeAbiFrom {} + impl TypeAbi for Vec { + type Unmanaged = Vec; + fn type_name() -> TypeName { <&[T]>::type_name() } + fn type_name_rust() -> TypeName { + format!("Vec<{}>", T::type_name_rust()) + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } } +impl TypeAbiFrom> for ArrayVec {} + impl TypeAbi for ArrayVec { + type Unmanaged = Self; + fn type_name() -> TypeName { <&[T]>::type_name() } + fn type_name_rust() -> TypeName { + format!("ArrayVec<{}, {}usize>", T::type_name_rust(), CAP) + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } } +impl TypeAbiFrom> for Box<[T]> {} + impl TypeAbi for Box<[T]> { + type Unmanaged = Self; + fn type_name() -> TypeName { <&[T]>::type_name() } + fn type_name_rust() -> TypeName { + format!("Box<[{}]>", T::type_name_rust()) + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } } +impl TypeAbiFrom for String {} +impl TypeAbiFrom<&String> for String {} +impl TypeAbiFrom<&str> for String {} +impl TypeAbiFrom> for String {} + impl TypeAbi for String { + type Unmanaged = Self; + fn type_name() -> TypeName { "utf-8 string".into() } } -impl TypeAbi for &str { +impl TypeAbiFrom<&'static str> for &'static str {} + +impl TypeAbi for &'static str { + type Unmanaged = Self; + fn type_name() -> TypeName { - TypeName::type_name() + String::type_name() + } + + fn type_name_rust() -> TypeName { + "&'static str".into() } } +impl TypeAbiFrom> for Box {} +impl TypeAbiFrom<&str> for Box {} +impl TypeAbiFrom for Box {} + impl TypeAbi for Box { + type Unmanaged = Self; + fn type_name() -> TypeName { - TypeName::type_name() + String::type_name() + } + + fn type_name_rust() -> TypeName { + "Box".into() } } macro_rules! type_abi_name_only { ($ty:ty, $name:expr) => { + impl TypeAbiFrom<$ty> for $ty {} + impl TypeAbiFrom<&$ty> for $ty {} + impl TypeAbi for $ty { + type Unmanaged = Self; + fn type_name() -> TypeName { TypeName::from($name) } @@ -125,13 +209,56 @@ type_abi_name_only!(i64, "i64"); type_abi_name_only!(core::num::NonZeroUsize, "NonZeroUsize"); type_abi_name_only!(bool, "bool"); +type_abi_name_only!(f64, "f64"); + +// Unsigned integer types: the contract can return a smaller capacity result and and we can interpret it as a larger capacity type. + +impl TypeAbiFrom for u64 {} +impl TypeAbiFrom for u64 {} +impl TypeAbiFrom for u64 {} +impl TypeAbiFrom for u64 {} + +impl TypeAbiFrom for u32 {} +impl TypeAbiFrom for u32 {} +impl TypeAbiFrom for u32 {} + +impl TypeAbiFrom for usize {} +impl TypeAbiFrom for usize {} +impl TypeAbiFrom for usize {} + +impl TypeAbiFrom for u16 {} + +// Signed, the same. + +impl TypeAbiFrom for i64 {} +impl TypeAbiFrom for i64 {} +impl TypeAbiFrom for i64 {} +impl TypeAbiFrom for i64 {} + +impl TypeAbiFrom for i32 {} +impl TypeAbiFrom for i32 {} +impl TypeAbiFrom for i32 {} + +impl TypeAbiFrom for isize {} +impl TypeAbiFrom for isize {} +impl TypeAbiFrom for isize {} + +impl TypeAbiFrom for i16 {} + +impl TypeAbiFrom> for Option where T: TypeAbiFrom {} + +impl TypeAbi for Option +where + T: TypeAbi, +{ + type Unmanaged = Option; -impl TypeAbi for Option { fn type_name() -> TypeName { - let mut repr = TypeName::from("Option<"); - repr.push_str(T::type_name().as_str()); - repr.push('>'); - repr + format!("Option<{}>", T::type_name()) + } + + fn type_name_rust() -> TypeName { + format!("Option<{}>", T::type_name_rust()) } fn provide_type_descriptions(accumulator: &mut TDC) { @@ -139,11 +266,23 @@ impl TypeAbi for Option { } } +impl TypeAbiFrom for Result {} + impl TypeAbi for Result { + type Unmanaged = Result; + fn type_name() -> TypeName { T::type_name() } + fn type_name_rust() -> TypeName { + format!( + "Result<{}, {}>", + T::type_name_rust(), + core::any::type_name::() + ) + } + /// Similar to the SCResult implementation. fn output_abis(output_names: &[&'static str]) -> OutputAbis { T::output_abis(output_names) @@ -157,28 +296,46 @@ impl TypeAbi for Result { macro_rules! tuple_impls { ($($len:expr => ($($n:tt $name:ident)+))+) => { $( + impl<$($name),+> TypeAbiFrom for ($($name,)+) + where + $($name: TypeAbi,)+ + {} + impl<$($name),+> TypeAbi for ($($name,)+) where $($name: TypeAbi,)+ { - fn type_name() -> TypeName { - let mut repr = TypeName::from("tuple"); - repr.push_str("<"); - $( - if $n > 0 { - repr.push(','); - } - repr.push_str($name::type_name().as_str()); + type Unmanaged = ($($name::Unmanaged,)+); + + fn type_name() -> TypeName { + let mut repr = TypeName::from("tuple<"); + $( + if $n > 0 { + repr.push(','); + } + repr.push_str($name::type_name().as_str()); )+ - repr.push('>'); - repr - } + repr.push('>'); + repr + } - fn provide_type_descriptions(accumulator: &mut TDC) { - $( - $name::provide_type_descriptions(accumulator); + fn type_name_rust() -> TypeName { + let mut repr = TypeName::from("("); + $( + if $n > 0 { + repr.push_str(", "); + } + repr.push_str($name::type_name_rust().as_str()); )+ - } + repr.push(')'); + repr + } + + fn provide_type_descriptions(accumulator: &mut TDC) { + $( + $name::provide_type_descriptions(accumulator); + )+ + } } )+ } @@ -203,7 +360,11 @@ tuple_impls! { 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) } +impl TypeAbiFrom<[U; N]> for [T; N] where T: TypeAbiFrom {} + impl TypeAbi for [T; N] { + type Unmanaged = [T::Unmanaged; N]; + fn type_name() -> TypeName { let mut repr = TypeName::from("array"); repr.push_str(N.to_string().as_str()); @@ -213,6 +374,15 @@ impl TypeAbi for [T; N] { repr } + fn type_name_rust() -> TypeName { + let mut repr = TypeName::from("["); + repr.push_str(T::type_name_rust().as_str()); + repr.push_str("; "); + repr.push_str(N.to_string().as_str()); + repr.push(']'); + repr + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/abi/type_abi_impl_big_int.rs b/framework/base/src/abi/type_abi_impl_big_int.rs new file mode 100644 index 0000000000..c3b0e6bccf --- /dev/null +++ b/framework/base/src/abi/type_abi_impl_big_int.rs @@ -0,0 +1,33 @@ +use crate::codec::num_bigint::{BigInt, BigUint}; + +use super::{TypeAbi, TypeAbiFrom, TypeName}; + +impl TypeAbiFrom for BigUint {} +impl TypeAbiFrom<&Self> for BigUint {} + +impl TypeAbi for BigUint { + type Unmanaged = Self; + + fn type_name() -> TypeName { + TypeName::from("BigUint") + } + + fn type_name_rust() -> TypeName { + TypeName::from("num_bigint::BigUint") + } +} + +impl TypeAbiFrom for BigInt {} +impl TypeAbiFrom<&Self> for BigInt {} + +impl TypeAbi for BigInt { + type Unmanaged = Self; + + fn type_name() -> TypeName { + TypeName::from("BigInt") + } + + fn type_name_rust() -> TypeName { + TypeName::from("num_bigint::BigInt") + } +} diff --git a/framework/base/src/abi/type_abi_impl_codec_multi.rs b/framework/base/src/abi/type_abi_impl_codec_multi.rs index 6227634258..7fcfa89ae5 100644 --- a/framework/base/src/abi/type_abi_impl_codec_multi.rs +++ b/framework/base/src/abi/type_abi_impl_codec_multi.rs @@ -1,14 +1,30 @@ +use alloc::format; + use crate::{ - abi::{OutputAbis, TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{OutputAbis, TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, codec::multi_types::{IgnoreValue, OptionalValue}, }; +#[cfg(feature = "alloc")] +impl TypeAbiFrom> + for crate::codec::multi_types::MultiValueVec +where + T: TypeAbiFrom, +{ +} + #[cfg(feature = "alloc")] impl TypeAbi for crate::codec::multi_types::MultiValueVec { + type Unmanaged = crate::codec::multi_types::MultiValueVec; + fn type_name() -> TypeName { super::type_name_variadic::() } + fn type_name_rust() -> TypeName { + format!("MultiValueVec<{}>", T::type_name_rust()) + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } @@ -18,21 +34,37 @@ impl TypeAbi for crate::codec::multi_types::MultiValueVec { } } +impl TypeAbiFrom for IgnoreValue {} + impl TypeAbi for IgnoreValue { + type Unmanaged = Self; + fn type_name() -> TypeName { TypeName::from("ignore") } + fn type_name_rust() -> TypeName { + "IgnoreValue".into() + } + fn is_variadic() -> bool { true } } +impl TypeAbiFrom> for OptionalValue where T: TypeAbiFrom {} + impl TypeAbi for OptionalValue { + type Unmanaged = OptionalValue; + fn type_name() -> TypeName { super::type_name_optional::() } + fn type_name_rust() -> TypeName { + format!("OptionalValue<{}>", T::type_name_rust()) + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } @@ -43,12 +75,19 @@ impl TypeAbi for OptionalValue { } macro_rules! multi_arg_impls { - ($(($mval_struct:ident $($n:tt $name:ident)+) )+) => { + ($(($mval_struct:ident $($n:tt $t:ident $u:ident)+) )+) => { $( - impl<$($name),+ > TypeAbi for crate::codec::multi_types::$mval_struct<$($name,)+> + impl<$($t, $u),+> TypeAbiFrom> for crate::codec::multi_types::$mval_struct<$($t,)+> + where + $($t: TypeAbiFrom<$u>,)+ + {} + + impl<$($t),+> TypeAbi for crate::codec::multi_types::$mval_struct<$($t,)+> where - $($name: TypeAbi,)+ + $($t: TypeAbi,)+ { + type Unmanaged = crate::codec::multi_types::$mval_struct<$($t::Unmanaged,)+>; + fn type_name() -> TypeName { let mut repr = TypeName::from("multi"); repr.push('<'); @@ -56,15 +95,28 @@ macro_rules! multi_arg_impls { if $n > 0 { repr.push(','); } - repr.push_str($name::type_name().as_str()); + repr.push_str($t::type_name().as_str()); + )+ + repr.push('>'); + repr + } + + fn type_name_rust() -> TypeName { + let mut repr = TypeName::from(stringify!($mval_struct)); + repr.push('<'); + $( + if $n > 0 { + repr.push_str(", "); + } + repr.push_str($t::type_name_rust().as_str()); )+ repr.push('>'); repr } fn provide_type_descriptions(accumulator: &mut TDC) { - $( - $name::provide_type_descriptions(accumulator); + $( + $t::provide_type_descriptions(accumulator); )+ } @@ -76,10 +128,10 @@ macro_rules! multi_arg_impls { let mut result = OutputAbis::new(); $( if output_names.len() > $n { - result.append(&mut $name::output_abis(&[output_names[$n]])); + result.append(&mut $t::output_abis(&[output_names[$n]])); } else { - result.append(&mut $name::output_abis(&[])); + result.append(&mut $t::output_abis(&[])); } )+ @@ -91,19 +143,19 @@ macro_rules! multi_arg_impls { } multi_arg_impls! { - (MultiValue2 0 T0 1 T1) - (MultiValue3 0 T0 1 T1 2 T2) - (MultiValue4 0 T0 1 T1 2 T2 3 T3) - (MultiValue5 0 T0 1 T1 2 T2 3 T3 4 T4) - (MultiValue6 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5) - (MultiValue7 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6) - (MultiValue8 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7) - (MultiValue9 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8) - (MultiValue10 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9) - (MultiValue11 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10) - (MultiValue12 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11) - (MultiValue13 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12) - (MultiValue14 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13) - (MultiValue15 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14) - (MultiValue16 0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) + (MultiValue2 0 T0 U0 1 T1 U1) + (MultiValue3 0 T0 U0 1 T1 U1 2 T2 U2) + (MultiValue4 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3) + (MultiValue5 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4) + (MultiValue6 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5) + (MultiValue7 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6) + (MultiValue8 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7) + (MultiValue9 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8) + (MultiValue10 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9) + (MultiValue11 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10) + (MultiValue12 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11) + (MultiValue13 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12) + (MultiValue14 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13) + (MultiValue15 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14) + (MultiValue16 0 T0 U0 1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15) } diff --git a/framework/base/src/abi/type_description.rs b/framework/base/src/abi/type_description.rs index 2f0f5a4336..f7e78ccef7 100644 --- a/framework/base/src/abi/type_description.rs +++ b/framework/base/src/abi/type_description.rs @@ -3,11 +3,14 @@ use alloc::{ vec::Vec, }; +use super::TypeNames; + #[derive(Clone, Debug)] pub struct TypeDescription { pub docs: Vec, - pub name: String, + pub names: TypeNames, pub contents: TypeContents, + pub macro_attributes: Vec, } impl TypeDescription { @@ -17,18 +20,28 @@ impl TypeDescription { /// We use this as value while the fields are being computed. pub const PLACEHOLDER: TypeDescription = TypeDescription { docs: Vec::new(), - name: String::new(), + names: TypeNames { + abi: String::new(), + rust: String::new(), + }, contents: TypeContents::NotSpecified, + macro_attributes: Vec::new(), }; } impl TypeDescription { /// Used in code generation. - pub fn new(docs: &[&str], name: String, contents: TypeContents) -> Self { + pub fn new( + docs: &[&str], + names: TypeNames, + contents: TypeContents, + macro_attributes: &[&str], + ) -> Self { TypeDescription { docs: docs.iter().map(|s| s.to_string()).collect(), - name, + names, contents, + macro_attributes: macro_attributes.iter().map(|s| s.to_string()).collect(), } } } @@ -78,12 +91,12 @@ impl EnumVariantDescription { pub struct StructFieldDescription { pub docs: Vec, pub name: String, - pub field_type: String, + pub field_type: TypeNames, } impl StructFieldDescription { /// Used in code generation. - pub fn new(docs: &[&str], name: &str, field_type: String) -> Self { + pub fn new(docs: &[&str], name: &str, field_type: TypeNames) -> Self { Self { docs: docs.iter().map(|s| s.to_string()).collect(), name: name.to_string(), diff --git a/framework/base/src/abi/type_description_container.rs b/framework/base/src/abi/type_description_container.rs index 7b9c0e892c..16dda2c8b9 100644 --- a/framework/base/src/abi/type_description_container.rs +++ b/framework/base/src/abi/type_description_container.rs @@ -8,17 +8,17 @@ pub trait TypeDescriptionContainer { // A placeholder gets inserted while computing field descriptions for a type, // to avoid an infinite loop for recursive types (if the same type appears again lower in the tree). - fn reserve_type_name(&mut self, type_name: TypeName) { - self.insert(type_name, TypeDescription::PLACEHOLDER); + fn reserve_type_name(&mut self, type_names: TypeNames) { + self.insert(type_names, TypeDescription::PLACEHOLDER); } - fn insert(&mut self, type_name: TypeName, type_description: TypeDescription); + fn insert(&mut self, type_names: TypeNames, type_description: TypeDescription); fn insert_all(&mut self, other: &Self); } #[derive(Clone, Default, Debug)] -pub struct TypeDescriptionContainerImpl(pub Vec<(TypeName, TypeDescription)>); +pub struct TypeDescriptionContainerImpl(pub Vec<(TypeNames, TypeDescription)>); impl TypeDescriptionContainer for TypeDescriptionContainerImpl { fn new() -> Self { @@ -28,16 +28,18 @@ impl TypeDescriptionContainer for TypeDescriptionContainerImpl { fn contains_type(&self, type_name: &str) -> bool { self.0 .iter() - .any(|(existing_type_name, _)| existing_type_name == type_name) + .any(|(existing_type_name, _)| existing_type_name.abi == type_name) } - fn insert(&mut self, type_name: TypeName, type_description: TypeDescription) { - if let Some((_existing_type_name, exisiting_type_description)) = - self.0.iter_mut().find(|(name, _)| name == &type_name) + fn insert(&mut self, type_names: TypeNames, type_description: TypeDescription) { + if let Some((_existing_type_name, exisiting_type_description)) = self + .0 + .iter_mut() + .find(|(name, _)| name.abi == type_names.abi) { *exisiting_type_description = type_description; } else { - self.0.push((type_name, type_description)); + self.0.push((type_names, type_description)); } } diff --git a/framework/base/src/api.rs b/framework/base/src/api.rs index 88f18ca94b..094522d1ac 100644 --- a/framework/base/src/api.rs +++ b/framework/base/src/api.rs @@ -1,5 +1,4 @@ mod blockchain_api; -mod builtin_function_names; mod call_value_api; mod composite_api; mod crypto_api; @@ -16,7 +15,6 @@ pub mod uncallable; mod vm_api; pub use blockchain_api::*; -pub use builtin_function_names::*; pub use call_value_api::*; pub use composite_api::*; pub use crypto_api::*; @@ -30,3 +28,6 @@ pub use print_api::*; pub use send_api::*; pub use storage_api::*; pub use vm_api::VMApi; + +// Backwards compatibility. +pub use crate::types::system_proxy::builtin_func_names::*; diff --git a/framework/base/src/api/composite_api.rs b/framework/base/src/api/composite_api.rs index bf197ade59..d1ca8413d8 100644 --- a/framework/base/src/api/composite_api.rs +++ b/framework/base/src/api/composite_api.rs @@ -2,7 +2,7 @@ use super::{ErrorApi, ManagedTypeApi, SendApi, StorageReadApi, StorageWriteApi}; /// Provided for convenience. /// Designed to be used in any types that send tokens or calls. -pub trait CallTypeApi: SendApi + ManagedTypeApi + ErrorApi {} +pub trait CallTypeApi: SendApi + ManagedTypeApi + StorageWriteApi + ErrorApi {} /// Provided for convenience. /// Designed to be used in storage mappers. diff --git a/framework/base/src/api/endpoint_arg_api.rs b/framework/base/src/api/endpoint_arg_api.rs index aa3201a07f..4d80935f52 100644 --- a/framework/base/src/api/endpoint_arg_api.rs +++ b/framework/base/src/api/endpoint_arg_api.rs @@ -59,7 +59,7 @@ pub trait EndpointArgumentApiImpl: ErrorApi + ManagedTypeApi { if let Some(value) = Self::managed_type_impl().bi_to_i64(big_int_temp_1) { value as u64 } else { - Self::error_api_impl().signal_error(err_msg::ARG_OUT_OF_RANGE) + Self::error_api_impl().signal_error(err_msg::ARG_OUT_OF_RANGE.as_bytes()) } } @@ -69,7 +69,7 @@ pub trait EndpointArgumentApiImpl: ErrorApi + ManagedTypeApi { if let Some(value) = Self::managed_type_impl().bi_to_i64(big_int_temp_1) { value } else { - Self::error_api_impl().signal_error(err_msg::ARG_OUT_OF_RANGE) + Self::error_api_impl().signal_error(err_msg::ARG_OUT_OF_RANGE.as_bytes()) } } diff --git a/framework/base/src/api/managed_types/big_int_api.rs b/framework/base/src/api/managed_types/big_int_api.rs index 295ca6b73e..13ce620d78 100644 --- a/framework/base/src/api/managed_types/big_int_api.rs +++ b/framework/base/src/api/managed_types/big_int_api.rs @@ -37,7 +37,7 @@ pub trait BigIntApiImpl: HandleTypeInfo + ErrorApi { ) { self.bi_sub(dest.clone(), x, y); if self.bi_sign(dest) == Sign::Minus { - Self::error_api_impl().signal_error(err_msg::BIG_UINT_SUB_NEGATIVE); + Self::error_api_impl().signal_error(err_msg::BIG_UINT_SUB_NEGATIVE.as_bytes()); } } diff --git a/framework/base/src/api/managed_types/const_handles.rs b/framework/base/src/api/managed_types/const_handles.rs index 73f329452e..283d9c55c6 100644 --- a/framework/base/src/api/managed_types/const_handles.rs +++ b/framework/base/src/api/managed_types/const_handles.rs @@ -23,6 +23,9 @@ pub const CALLBACK_CLOSURE_ARGS_BUFFER: RawHandle = -23; pub const MBUF_TEMPORARY_1: RawHandle = -25; pub const MBUF_TEMPORARY_2: RawHandle = -26; +pub const ADDRESS_CALLER: RawHandle = -30; +pub const ADDRESS_SELF: RawHandle = -31; + pub const NEW_HANDLE_START_FROM: RawHandle = -200; // > -100 reserved for APIs // Vec of 64 entries of 1 bit diff --git a/framework/base/src/contract_base.rs b/framework/base/src/contract_base.rs index 07ee908d93..b7ae48ea10 100644 --- a/framework/base/src/contract_base.rs +++ b/framework/base/src/contract_base.rs @@ -9,7 +9,7 @@ mod wrappers; pub use callable_contract::{CallableContract, CallableContractBuilder}; pub use contract_abi_provider::ContractAbiProvider; pub use contract_base_trait::ContractBase; -pub use proxy_obj_base::ProxyObjBase; +pub use proxy_obj_base::{ProxyObjBase, ProxyObjNew}; pub use proxy_obj_callback_base::CallbackProxyObjBase; pub use universal_contract_obj::*; pub use wrappers::*; diff --git a/framework/base/src/contract_base/contract_base_trait.rs b/framework/base/src/contract_base/contract_base_trait.rs index cec45dfa0f..342b9ea61d 100644 --- a/framework/base/src/contract_base/contract_base_trait.rs +++ b/framework/base/src/contract_base/contract_base_trait.rs @@ -2,7 +2,10 @@ use super::{ BlockchainWrapper, CallValueWrapper, CryptoWrapper, ErrorHelper, ManagedSerializer, SendRawWrapper, SendWrapper, StorageRawWrapper, }; -use crate::api::VMApi; +use crate::{ + api::VMApi, + types::{Tx, TxBaseWithEnv, TxScEnv}, +}; /// Interface to be used by the actual smart contract code. /// @@ -26,6 +29,12 @@ pub trait ContractBase: Sized { SendWrapper::new() } + /// Starts the declaration of a new transaction. + #[inline] + fn tx(&self) -> TxBaseWithEnv> { + Tx::new_tx_from_sc() + } + /// Low-level functionality related to sending transactions from the current contract. /// /// For almost all cases contracts should instead use `self.send()` and `ContractCall`. diff --git a/framework/base/src/contract_base/proxy_obj_base.rs b/framework/base/src/contract_base/proxy_obj_base.rs index 54eadd26cd..0d3053d8f4 100644 --- a/framework/base/src/contract_base/proxy_obj_base.rs +++ b/framework/base/src/contract_base/proxy_obj_base.rs @@ -1,18 +1,11 @@ use crate::{ api::VMApi, - types::{ManagedAddress, ManagedOption}, + types::{ManagedAddress, ManagedOption, TxScEnv, TxTo}, }; pub trait ProxyObjBase { type Api: VMApi; - - #[doc(hidden)] - fn new_proxy_obj() -> Self; - - /// Specify the target contract to call. - /// Not taken into account for deploys. - #[must_use] - fn contract(self, address: ManagedAddress) -> Self; + type To: TxTo>; /// Extracts the address contained in the proxy object and replaces it with None. /// @@ -25,4 +18,19 @@ pub trait ProxyObjBase { /// Will crash if no address was specified. #[doc(hidden)] fn extract_address(&mut self) -> ManagedAddress; + + #[doc(hidden)] + fn extract_proxy_to(&mut self) -> Self::To; +} + +pub trait ProxyObjNew: ProxyObjBase { + type ProxyTo: ProxyObjBase; + + #[doc(hidden)] + fn new_proxy_obj() -> Self; + + /// Specify the target contract to call. + /// Not taken into account for deploys. + #[must_use] + fn contract(self, address: ManagedAddress) -> Self::ProxyTo; } diff --git a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs index 01ce71d189..c499c9f663 100644 --- a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs @@ -77,7 +77,7 @@ where pub fn check_caller_is_owner(&self) { if self.get_owner_address() != self.get_caller() { - A::error_api_impl().signal_error(ONLY_OWNER_CALLER); + A::error_api_impl().signal_error(ONLY_OWNER_CALLER.as_bytes()); } } @@ -85,7 +85,7 @@ where let mbuf_temp_1: A::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); A::blockchain_api_impl().load_caller_managed(mbuf_temp_1.clone()); if A::blockchain_api_impl().is_smart_contract(mbuf_temp_1) { - A::error_api_impl().signal_error(ONLY_USER_ACCOUNT_CALLER); + A::error_api_impl().signal_error(ONLY_USER_ACCOUNT_CALLER.as_bytes()); } } @@ -153,8 +153,9 @@ where #[inline] pub fn get_sc_balance(&self, token: &EgldOrEsdtTokenIdentifier, nonce: u64) -> BigUint { token.map_ref_or_else( - || self.get_balance(&self.get_sc_address()), - |token_identifier| { + (), + |()| self.get_balance(&self.get_sc_address()), + |(), token_identifier| { self.get_esdt_balance(&self.get_sc_address(), token_identifier, nonce) }, ) diff --git a/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs b/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs index 5635c0b44a..5d290369df 100644 --- a/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs @@ -79,20 +79,12 @@ where &self, to: &ManagedAddress, token: &TokenIdentifier, - egld_value: &BigUint, + value: &BigUint, gas_limit: u64, endpoint_name: &ManagedBuffer, arg_buffer: &ManagedArgBuffer, ) -> Result<(), &'static [u8]> { - self.transfer_esdt_nft_execute( - to, - token, - 0, - egld_value, - gas_limit, - endpoint_name, - arg_buffer, - ) + self.transfer_esdt_nft_execute(to, token, 0, value, gas_limit, endpoint_name, arg_buffer) } #[allow(clippy::too_many_arguments)] diff --git a/framework/base/src/contract_base/wrappers/send_wrapper.rs b/framework/base/src/contract_base/wrappers/send_wrapper.rs index 78f4f045d6..3a11bde247 100644 --- a/framework/base/src/contract_base/wrappers/send_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_wrapper.rs @@ -3,18 +3,13 @@ use core::marker::PhantomData; use crate::codec::Empty; use crate::{ - api::{ - BlockchainApi, BlockchainApiImpl, CallTypeApi, StorageReadApi, - CHANGE_OWNER_BUILTIN_FUNC_NAME, CLAIM_DEVELOPER_REWARDS_FUNC_NAME, - ESDT_LOCAL_BURN_FUNC_NAME, ESDT_LOCAL_MINT_FUNC_NAME, ESDT_NFT_ADD_QUANTITY_FUNC_NAME, - ESDT_NFT_ADD_URI_FUNC_NAME, ESDT_NFT_BURN_FUNC_NAME, ESDT_NFT_CREATE_FUNC_NAME, - ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME, - }, + api::{BlockchainApi, CallTypeApi, StorageReadApi}, codec, - esdt::ESDTSystemSmartContractProxy, types::{ - BigUint, ContractCall, ContractCallNoPayment, EgldOrEsdtTokenIdentifier, EsdtTokenPayment, - ManagedAddress, ManagedArgBuffer, ManagedBuffer, ManagedType, ManagedVec, TokenIdentifier, + system_proxy, BigUint, ContractCallNoPayment, ESDTSystemSCAddress, + EgldOrEsdtTokenIdentifier, EsdtTokenPayment, FunctionCall, GasLeft, ManagedAddress, + ManagedArgBuffer, ManagedBuffer, ManagedType, ManagedVec, NotPayable, OriginalResultMarker, + ReturnsRawResult, ReturnsResult, ToSelf, TokenIdentifier, Tx, TxScEnv, }, }; @@ -50,12 +45,21 @@ where SendRawWrapper::new() } - /// A proxy for calling the system smart contract. - /// - /// Use the methods of this proxy to launch contract calls to the system SC. - #[inline] - pub fn esdt_system_sc_proxy(&self) -> ESDTSystemSmartContractProxy { - ESDTSystemSmartContractProxy::new_proxy_obj() + /// Backwards compatibility, synonymous to `esdt_system_sc_tx`, which is the more appropriate name now. + pub fn esdt_system_sc_proxy( + &self, + ) -> system_proxy::ESDTSystemSCProxyMethods, (), ESDTSystemSCAddress, ()> { + self.esdt_system_sc_tx() + } + + /// Prepares a proxy object to call the system SC. + /// It has the destination address set, as well as the contract type (as specified in the proxy). + pub fn esdt_system_sc_tx( + &self, + ) -> system_proxy::ESDTSystemSCProxyMethods, (), ESDTSystemSCAddress, ()> { + Tx::new_tx_from_sc() + .to(ESDTSystemSCAddress) + .typed(system_proxy::ESDTSystemSCProxy) } /// Convenient way to quickly instance a minimal contract call (with no EGLD, no arguments, etc.) @@ -74,7 +78,7 @@ where /// Used especially for sending EGLD to regular accounts. #[inline] pub fn direct_egld(&self, to: &ManagedAddress, amount: &BigUint) { - self.send_raw_wrapper().direct_egld(to, amount, Empty) + Tx::new_tx_from_sc().to(to).egld(amount).transfer(); } /// Sends EGLD to a given address, directly. @@ -82,11 +86,10 @@ where /// /// If the amount is 0, it returns without error. pub fn direct_non_zero_egld(&self, to: &ManagedAddress, amount: &BigUint) { - if amount == &0 { - return; - } - - self.direct_egld(to, amount) + Tx::new_tx_from_sc() + .to(to) + .egld(amount) + .transfer_if_not_empty(); } /// Sends either EGLD, ESDT or NFT to the target address, @@ -188,16 +191,17 @@ where } /// Sends a single ESDT transfer to target address. - #[inline] - #[allow(clippy::too_many_arguments)] pub fn direct_esdt( &self, to: &ManagedAddress, token_identifier: &TokenIdentifier, - nonce: u64, + token_nonce: u64, amount: &BigUint, ) { - self.direct_esdt_with_gas_limit(to, token_identifier, nonce, amount, 0, Empty, &[]); + Tx::new_tx_from_sc() + .to(to) + .single_esdt(token_identifier, token_nonce, amount) + .transfer(); } /// Sends a single ESDT transfer to target address. @@ -290,13 +294,7 @@ where to: &ManagedAddress, payments: &ManagedVec>, ) { - let _ = self.send_raw_wrapper().multi_esdt_transfer_execute( - to, - payments, - 0, - &ManagedBuffer::new(), - &ManagedArgBuffer::new(), - ); + Tx::new_tx_from_sc().to(to).payment(payments).transfer(); } /// Performs a simple ESDT/NFT transfer, but via async call. @@ -314,10 +312,10 @@ where nonce: u64, amount: BigUint, ) -> ! { - ContractCallNoPayment::::new(to, ManagedBuffer::new()) - .with_esdt_transfer((token, nonce, amount)) - .async_call() - .call_and_exit_ignore_callback() + Tx::new_tx_from_sc() + .to(to) + .esdt((token, nonce, amount)) + .async_call_and_exit() } /// Performs a simple ESDT/NFT transfer, but via async call. @@ -339,10 +337,7 @@ where if amount == 0 { return; } - ContractCallNoPayment::::new(to, ManagedBuffer::new()) - .with_esdt_transfer((token, nonce, amount)) - .async_call() - .call_and_exit_ignore_callback() + self.transfer_esdt_via_async_call(to, token, nonce, amount) } /// Sends multiple ESDT tokens to a target address, via an async call. @@ -351,32 +346,51 @@ where to: ManagedAddress, payments: ManagedVec>, ) -> ! { - ContractCallNoPayment::::new(to, ManagedBuffer::new()) - .with_multi_token_transfer(payments) - .async_call() - .call_and_exit_ignore_callback() + Tx::new_tx_from_sc() + .to(to) + .payment(payments) + .async_call_and_exit() } /// Creates a call to the `ClaimDeveloperRewards` builtin function. - /// - /// In itself, this does nothing. You need to then call turn the contract call into an async call. + #[allow(clippy::type_complexity)] pub fn claim_developer_rewards( &self, child_sc_address: ManagedAddress, - ) -> ContractCallNoPayment { - ContractCallNoPayment::new(child_sc_address, CLAIM_DEVELOPER_REWARDS_FUNC_NAME) + ) -> Tx< + TxScEnv, + (), + ManagedAddress, + NotPayable, + (), + FunctionCall, + OriginalResultMarker<()>, + > { + Tx::new_tx_from_sc() + .to(child_sc_address) + .typed(system_proxy::UserBuiltinProxy) + .claim_developer_rewards() } /// Creates a call to the `ChangeOwnerAddress` builtin function. - /// - /// In itself, this does nothing. You need to then call turn the contract call into an async call. + #[allow(clippy::type_complexity)] pub fn change_owner_address( &self, child_sc_address: ManagedAddress, new_owner: &ManagedAddress, - ) -> ContractCallNoPayment { - self.contract_call(child_sc_address, CHANGE_OWNER_BUILTIN_FUNC_NAME) - .argument(&new_owner) + ) -> Tx< + TxScEnv, + (), + ManagedAddress, + NotPayable, + (), + FunctionCall, + OriginalResultMarker<()>, + > { + Tx::new_tx_from_sc() + .to(child_sc_address) + .typed(system_proxy::UserBuiltinProxy) + .change_owner_address(new_owner) } /// Allows synchronously calling a local function by name. Execution is resumed afterwards. @@ -385,11 +399,16 @@ where pub fn call_local_esdt_built_in_function( &self, gas: u64, - endpoint_name: &ManagedBuffer, - arg_buffer: &ManagedArgBuffer, + endpoint_name: ManagedBuffer, + arg_buffer: ManagedArgBuffer, ) -> ManagedVec> { - self.send_raw_wrapper() - .call_local_esdt_built_in_function(gas, endpoint_name, arg_buffer) + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(gas) + .raw_call(endpoint_name) + .arguments_raw(arg_buffer) + .returns(ReturnsRawResult) + .sync_call() } /// Allows synchronous minting of ESDT/SFT (depending on nonce). Execution is resumed afterwards. @@ -401,25 +420,12 @@ where /// /// This function cannot be used for NFTs. pub fn esdt_local_mint(&self, token: &TokenIdentifier, nonce: u64, amount: &BigUint) { - let mut arg_buffer = ManagedArgBuffer::new(); - let func_name: &str; - - arg_buffer.push_arg(token); - - if nonce == 0 { - func_name = ESDT_LOCAL_MINT_FUNC_NAME; - } else { - func_name = ESDT_NFT_ADD_QUANTITY_FUNC_NAME; - arg_buffer.push_arg(nonce); - } - - arg_buffer.push_arg(amount); - - let _ = self.call_local_esdt_built_in_function( - A::blockchain_api_impl().get_gas_left(), - &ManagedBuffer::from(func_name), - &arg_buffer, - ); + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .esdt_local_mint(token, nonce, amount) + .sync_call() } /// Allows synchronous minting of ESDT/SFT (depending on nonce). Execution is resumed afterwards. @@ -448,24 +454,12 @@ where /// Note that the SC must have the ESDTLocalBurn or ESDTNftBurn roles set, /// or this will fail with "action is not allowed". pub fn esdt_local_burn(&self, token: &TokenIdentifier, nonce: u64, amount: &BigUint) { - let mut arg_buffer = ManagedArgBuffer::new(); - let func_name: &str; - - arg_buffer.push_arg(token); - if nonce == 0 { - func_name = ESDT_LOCAL_BURN_FUNC_NAME; - } else { - func_name = ESDT_NFT_BURN_FUNC_NAME; - arg_buffer.push_arg(nonce); - } - - arg_buffer.push_arg(amount); - - let _ = self.call_local_esdt_built_in_function( - A::blockchain_api_impl().get_gas_left(), - &ManagedBuffer::from(func_name), - &arg_buffer, - ); + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .esdt_local_burn(token, nonce, amount) + .sync_call() } /// Allows synchronous burning of ESDT/SFT/NFT (depending on nonce). Execution is resumed afterwards. @@ -533,36 +527,13 @@ where attributes: &T, uris: &ManagedVec>, ) -> u64 { - let mut arg_buffer = ManagedArgBuffer::new(); - arg_buffer.push_arg(token); - arg_buffer.push_arg(amount); - arg_buffer.push_arg(name); - arg_buffer.push_arg(royalties); - arg_buffer.push_arg(hash); - arg_buffer.push_arg(attributes); - - if uris.is_empty() { - // at least one URI is required, so we push an empty one - arg_buffer.push_arg(codec::Empty); - } else { - // The API function has the last argument as variadic, - // so we top-encode each and send as separate argument - for uri in uris { - arg_buffer.push_arg(uri); - } - } - - let output = self.call_local_esdt_built_in_function( - A::blockchain_api_impl().get_gas_left(), - &ManagedBuffer::from(ESDT_NFT_CREATE_FUNC_NAME), - &arg_buffer, - ); - - if let Some(first_result_bytes) = output.try_get(0) { - first_result_bytes.parse_as_u64().unwrap_or_default() - } else { - 0 - } + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .esdt_nft_create(token, amount, name, royalties, hash, attributes, uris) + .returns(ReturnsResult) + .sync_call() } /// Creates a new NFT token of a certain type (determined by `token_identifier`). @@ -767,19 +738,12 @@ where return; } - let mut arg_buffer = ManagedArgBuffer::new(); - arg_buffer.push_arg(token_id); - arg_buffer.push_arg(nft_nonce); - - for uri in new_uris { - arg_buffer.push_arg(uri); - } - - let _ = self.call_local_esdt_built_in_function( - A::blockchain_api_impl().get_gas_left(), - &ManagedBuffer::from(ESDT_NFT_ADD_URI_FUNC_NAME), - &arg_buffer, - ); + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .nft_add_multiple_uri(token_id, nft_nonce, new_uris) + .sync_call() } /// Changes attributes of an NFT, via a synchronous builtin function call. @@ -789,15 +753,11 @@ where nft_nonce: u64, new_attributes: &T, ) { - let mut arg_buffer = ManagedArgBuffer::new(); - arg_buffer.push_arg(token_id); - arg_buffer.push_arg(nft_nonce); - arg_buffer.push_arg(new_attributes); - - let _ = self.call_local_esdt_built_in_function( - A::blockchain_api_impl().get_gas_left(), - &ManagedBuffer::from(ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME), - &arg_buffer, - ); + Tx::new_tx_from_sc() + .to(ToSelf) + .gas(GasLeft) + .typed(system_proxy::UserBuiltinProxy) + .nft_update_attributes(token_id, nft_nonce, new_attributes) + .sync_call() } } diff --git a/framework/base/src/contract_base/wrappers/serializer.rs b/framework/base/src/contract_base/wrappers/serializer.rs index 00c3e9649c..07fa41dbb5 100644 --- a/framework/base/src/contract_base/wrappers/serializer.rs +++ b/framework/base/src/contract_base/wrappers/serializer.rs @@ -1,4 +1,6 @@ -use core::marker::PhantomData; +use core::{convert::Infallible, marker::PhantomData}; + +use unwrap_infallible::UnwrapInfallible; use crate::codec::{ DecodeError, DecodeErrorHandler, EncodeError, EncodeErrorHandler, TopDecode, TopEncode, @@ -30,19 +32,23 @@ where pub fn top_encode_to_managed_buffer(&self, value: &T) -> ManagedBuffer { let mut result = ManagedBuffer::new(); - let Ok(()) = value.top_encode_or_handle_err( - &mut result, - ExitCodecErrorHandler::::from(err_msg::SERIALIZER_ENCODE_ERROR), - ); + value + .top_encode_or_handle_err( + &mut result, + ExitCodecErrorHandler::::from(err_msg::SERIALIZER_ENCODE_ERROR), + ) + .unwrap_infallible(); result } pub fn top_encode_to_boxed_bytes(&self, value: &T) -> BoxedBytes { let mut result = BoxedBytes::empty(); - let Ok(()) = value.top_encode_or_handle_err( - &mut result, - ExitCodecErrorHandler::::from(err_msg::SERIALIZER_ENCODE_ERROR), - ); + value + .top_encode_or_handle_err( + &mut result, + ExitCodecErrorHandler::::from(err_msg::SERIALIZER_ENCODE_ERROR), + ) + .unwrap_infallible(); result } @@ -53,21 +59,21 @@ where pub fn top_decode_from_managed_buffer_custom_message( &self, buffer: &ManagedBuffer, - error_message: &'static [u8], + error_message: &'static str, ) -> T { - let Ok(value) = T::top_decode_or_handle_err( + T::top_decode_or_handle_err( buffer.clone(), // TODO: remove clone ExitCodecErrorHandler::::from(error_message), - ); - value + ) + .unwrap_infallible() } pub fn top_decode_from_byte_slice(&self, slice: &[u8]) -> T { - let Ok(value) = T::top_decode_or_handle_err( + T::top_decode_or_handle_err( slice, ExitCodecErrorHandler::::from(err_msg::SERIALIZER_DECODE_ERROR), - ); - value + ) + .unwrap_infallible() } } @@ -77,16 +83,16 @@ where M: ManagedTypeApi + ErrorApi, { _phantom: PhantomData, - pub base_message: &'static [u8], + pub base_message: &'static str, } impl Copy for ExitCodecErrorHandler where M: ManagedTypeApi + ErrorApi {} -impl From<&'static [u8]> for ExitCodecErrorHandler +impl From<&'static str> for ExitCodecErrorHandler where M: ManagedTypeApi + ErrorApi, { - fn from(base_message: &'static [u8]) -> Self { + fn from(base_message: &'static str) -> Self { ExitCodecErrorHandler { _phantom: PhantomData, base_message, @@ -98,10 +104,10 @@ impl EncodeErrorHandler for ExitCodecErrorHandler where M: ManagedTypeApi + ErrorApi, { - type HandledErr = !; + type HandledErr = Infallible; fn handle_error(&self, err: EncodeError) -> Self::HandledErr { - let mut message_buffer = ManagedBuffer::::new_from_bytes(self.base_message); + let mut message_buffer = ManagedBuffer::::new_from_bytes(self.base_message.as_bytes()); message_buffer.append_bytes(err.message_bytes()); M::error_api_impl().signal_error_from_buffer(message_buffer.get_handle()) } @@ -111,10 +117,10 @@ impl DecodeErrorHandler for ExitCodecErrorHandler where M: ManagedTypeApi + ErrorApi, { - type HandledErr = !; + type HandledErr = Infallible; fn handle_error(&self, err: DecodeError) -> Self::HandledErr { - let mut message_buffer = ManagedBuffer::::new_from_bytes(self.base_message); + let mut message_buffer = ManagedBuffer::::new_from_bytes(self.base_message.as_bytes()); message_buffer.append_bytes(err.message_bytes()); M::error_api_impl().signal_error_from_buffer(message_buffer.get_handle()) } diff --git a/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs b/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs index 0b0280a111..5a4992c36e 100644 --- a/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs @@ -1,5 +1,7 @@ use core::marker::PhantomData; +use unwrap_infallible::UnwrapInfallible; + use crate::codec::{TopDecode, TopEncode}; use crate::{ @@ -63,9 +65,8 @@ where result_buffer.get_handle(), ); - let Ok(value) = - V::top_decode_or_handle_err(result_buffer, StorageGetErrorHandler::::default()); - value + V::top_decode_or_handle_err(result_buffer, StorageGetErrorHandler::::default()) + .unwrap_infallible() } /// Write a serializable value to storage under the given key diff --git a/framework/base/src/derive_imports.rs b/framework/base/src/derive_imports.rs new file mode 100644 index 0000000000..64f45ead1d --- /dev/null +++ b/framework/base/src/derive_imports.rs @@ -0,0 +1,7 @@ +pub use crate::{ + codec, + codec::derive::{ + NestedDecode, NestedEncode, TopDecode, TopDecodeOrDefault, TopEncode, TopEncodeOrDefault, + }, + derive::{type_abi, ManagedVecItem, TypeAbi}, +}; diff --git a/framework/base/src/err_msg.rs b/framework/base/src/err_msg.rs index 46f43e3313..f24878517b 100644 --- a/framework/base/src/err_msg.rs +++ b/framework/base/src/err_msg.rs @@ -3,7 +3,7 @@ pub const MEM_ALLOC_ERROR: &str = "memory allocation error"; pub const NON_PAYABLE_FUNC_ESDT: &str = "function does not accept ESDT payment"; pub const BAD_TOKEN_PROVIDED: &str = "bad call value token provided"; -pub const BAD_TOKEN_TICKER_FORMAT: &[u8] = b"bad token ticker format"; +pub const BAD_TOKEN_TICKER_FORMAT: &str = "bad token ticker format"; pub const SINGLE_ESDT_EXPECTED: &str = "function expects single ESDT payment"; pub const TOO_MANY_ESDT_TRANSFERS: &str = "too many ESDT transfers"; pub const ESDT_INVALID_TOKEN_INDEX: &str = "invalid token index"; @@ -11,34 +11,33 @@ pub const INCORRECT_NUM_ESDT_TRANSFERS: &str = "incorrect number of ESDT transfe pub static FUNGIBLE_TOKEN_EXPECTED_ERR_MSG: &str = "fungible ESDT token expected"; pub const ARG_WRONG_NUMBER: &str = "wrong number of arguments"; -pub const ARG_ASYNC_WRONG_NUMBER: &[u8] = b"wrong number of arguments provided to async call"; -pub const ARG_ASYNC_RETURN_WRONG_NUMBER: &[u8] = - b"wrong number of arguments returned by async call"; -pub const ARG_CALLBACK_TOO_FEW: &[u8] = b"too few callback arguments provided"; -pub const ARG_CALLBACK_TOO_MANY: &[u8] = b"too many callback arguments provided"; +pub const ARG_ASYNC_WRONG_NUMBER: &str = "wrong number of arguments provided to async call"; +pub const ARG_ASYNC_RETURN_WRONG_NUMBER: &str = "wrong number of arguments returned by async call"; +pub const ARG_CALLBACK_TOO_FEW: &str = "too few callback arguments provided"; +pub const ARG_CALLBACK_TOO_MANY: &str = "too many callback arguments provided"; -pub const ARG_OUT_OF_RANGE: &[u8] = b"argument out of range"; -pub const ARG_BAD_LENGTH: &[u8] = b"argument has wrong length"; -pub const ARG_BAD_LENGTH_32: &[u8] = b"argument has wrong length: 32 bytes expected"; -pub const ARG_DECODE_ERROR_1: &[u8] = b"argument decode error ("; -pub const ARG_DECODE_ERROR_2: &[u8] = b"): "; -pub const STORAGE_VALUE_OUT_OF_RANGE: &[u8] = b"storage value out of range"; -pub const STORAGE_DECODE_ERROR: &[u8] = b"storage decode error: "; -pub const STORAGE_ENCODE_ERROR: &[u8] = b"storage encode error: "; -pub const STORAGE_KEY_ENCODE_ERROR: &[u8] = b"storage key encode error: "; -pub const STORAGE_VALUE_EXCEEDS_BUFFER: &[u8] = b"storage value exceeds buffer"; -pub const FINISH_ENCODE_ERROR: &[u8] = b"endpoint result encode error: "; -pub const SERIALIZER_DECODE_ERROR: &[u8] = b"serializer decode error: "; -pub const SERIALIZER_ENCODE_ERROR: &[u8] = b"serializer encode error: "; -pub const FORMATTER_ENCODE_ERROR: &[u8] = b"formatter encode error: "; -pub const LOG_TOPIC_ENCODE_ERROR: &[u8] = b"log topic encode error: "; -pub const LOG_DATA_ENCODE_ERROR: &[u8] = b"log data encode error: "; -pub const CONTRACT_CALL_ENCODE_ERROR: &[u8] = b"contract call encode error: "; +pub const ARG_OUT_OF_RANGE: &str = "argument out of range"; +pub const ARG_BAD_LENGTH: &str = "argument has wrong length"; +pub const ARG_BAD_LENGTH_32: &str = "argument has wrong length: 32 bytes expected"; +pub const ARG_DECODE_ERROR_1: &str = "argument decode error ("; +pub const ARG_DECODE_ERROR_2: &str = "): "; +pub const STORAGE_VALUE_OUT_OF_RANGE: &str = "storage value out of range"; +pub const STORAGE_DECODE_ERROR: &str = "storage decode error: "; +pub const STORAGE_ENCODE_ERROR: &str = "storage encode error: "; +pub const STORAGE_KEY_ENCODE_ERROR: &str = "storage key encode error: "; +pub const STORAGE_VALUE_EXCEEDS_BUFFER: &str = "storage value exceeds buffer"; +pub const FINISH_ENCODE_ERROR: &str = "endpoint result encode error: "; +pub const SERIALIZER_DECODE_ERROR: &str = "serializer decode error: "; +pub const SERIALIZER_ENCODE_ERROR: &str = "serializer encode error: "; +pub const FORMATTER_ENCODE_ERROR: &str = "formatter encode error: "; +pub const LOG_TOPIC_ENCODE_ERROR: &str = "log topic encode error: "; +pub const LOG_DATA_ENCODE_ERROR: &str = "log data encode error: "; +pub const CONTRACT_CALL_ENCODE_ERROR: &str = "contract call encode error: "; -pub const VALUE_EXCEEDS_SLICE: &[u8] = b"value exceeds target slice"; -pub const CAST_TO_I64_ERROR: &[u8] = b"cast to i64 error"; -pub const BIG_UINT_EXCEEDS_SLICE: &[u8] = b"big uint as_bytes exceed target slice"; -pub const BIG_UINT_SUB_NEGATIVE: &[u8] = b"cannot subtract because result would be negative"; +pub const VALUE_EXCEEDS_SLICE: &str = "value exceeds target slice"; +pub const CAST_TO_I64_ERROR: &str = "cast to i64 error"; +pub const BIG_UINT_EXCEEDS_SLICE: &str = "big uint as_bytes exceed target slice"; +pub const BIG_UINT_SUB_NEGATIVE: &str = "cannot subtract because result would be negative"; pub const DESERIALIZATION_INVALID_BYTE: &str = "call data deserialization error: not a valid byte"; pub const DESERIALIZATION_NOT_32_BYTES: &str = @@ -48,14 +47,14 @@ pub const DESERIALIZATION_ODD_DIGITS: &str = pub const DESERIALIZATION_ARG_OUT_OF_RANGE: &str = "call data deserialization error: argument out of range"; -pub const CALLBACK_BAD_FUNC: &[u8] = b"no callback function with that name exists in contract"; +pub const CALLBACK_BAD_FUNC: &str = "no callback function with that name exists in contract"; pub const RECIPIENT_ADDRESS_NOT_SET: &str = "recipient address not set"; -pub static ONLY_OWNER_CALLER: &[u8] = b"Endpoint can only be called by owner"; -pub static ONLY_USER_ACCOUNT_CALLER: &[u8] = b"Endpoint can only be called by user accounts"; +pub static ONLY_OWNER_CALLER: &str = "Endpoint can only be called by owner"; +pub static ONLY_USER_ACCOUNT_CALLER: &str = "Endpoint can only be called by user accounts"; -pub const STORAGE_NOT_I64: &[u8] = b"storage not i64"; -pub const STORAGE_NOT_32_BYTES: &[u8] = b"32 bytes of data expected in storage at key"; +pub const STORAGE_NOT_I64: &str = "storage not i64"; +pub const STORAGE_NOT_32_BYTES: &str = "32 bytes of data expected in storage at key"; /// An additional non-VM status, meant just to signal an error in the debugger infrastructure of in the tests. pub const DEBUG_API_ERR_STATUS: u64 = 100; diff --git a/framework/base/src/esdt.rs b/framework/base/src/esdt.rs deleted file mode 100644 index db1730be29..0000000000 --- a/framework/base/src/esdt.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod properties; -mod system_sc_proxy; - -pub use properties::*; -pub use system_sc_proxy::ESDTSystemSmartContractProxy; diff --git a/framework/base/src/external_view_contract.rs b/framework/base/src/external_view_contract.rs index ba14d7072a..2b01176176 100644 --- a/framework/base/src/external_view_contract.rs +++ b/framework/base/src/external_view_contract.rs @@ -49,7 +49,7 @@ pub fn external_view_contract_constructor_abi() -> EndpointAbi { ); endpoint_abi.inputs.push(InputAbi { arg_name: "target_contract_address".to_string(), - type_name: crate::types::heap::Address::type_name(), + type_names: crate::types::heap::Address::type_names(), multi_arg: false, }); endpoint_abi diff --git a/framework/base/src/formatter/formatter_traits.rs b/framework/base/src/formatter/formatter_traits.rs index 7faa0b00f5..11a24baf96 100644 --- a/framework/base/src/formatter/formatter_traits.rs +++ b/framework/base/src/formatter/formatter_traits.rs @@ -1,3 +1,5 @@ +use unwrap_infallible::UnwrapInfallible; + use crate::codec::TopEncode; use crate::{ @@ -90,10 +92,11 @@ pub trait SCCodec { impl SCCodec for T { fn fmt(&self, f: &mut F) { let mut encoded = ManagedBuffer::::new(); - let Ok(()) = self.top_encode_or_handle_err( + self.top_encode_or_handle_err( &mut encoded, ExitCodecErrorHandler::::from(err_msg::FORMATTER_ENCODE_ERROR), - ); + ) + .unwrap_infallible(); SCLowerHex::fmt(&encoded, f); } } diff --git a/framework/base/src/imports.rs b/framework/base/src/imports.rs new file mode 100644 index 0000000000..f8fa5cd6cf --- /dev/null +++ b/framework/base/src/imports.rs @@ -0,0 +1,22 @@ +pub use crate::{ + abi::TypeAbi, + api::{ErrorApiImpl, ManagedTypeApi, VMApi}, + arrayvec::ArrayVec, + codec::{ + multi_types::*, DecodeError, Empty, IntoMultiValue, NestedDecode, NestedEncode, TopDecode, + TopEncode, + }, + contract_base::{ContractBase, ProxyObjBase, ProxyObjNew}, + err_msg, + io::*, + non_zero_usize, + non_zero_util::*, + require, sc_format, sc_panic, sc_print, + storage::mappers::*, + types::{system_proxy::*, *}, +}; + +pub use core::ops::{ + Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, + Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign, +}; diff --git a/framework/base/src/io/arg_de_input.rs b/framework/base/src/io/arg_de_input.rs index 42e4fc7f0f..98faef2899 100644 --- a/framework/base/src/io/arg_de_input.rs +++ b/framework/base/src/io/arg_de_input.rs @@ -92,6 +92,19 @@ where self.to_managed_buffer().into_max_size_buffer(buffer, h) } + #[inline] + fn into_max_size_buffer_align_right( + self, + buffer: &mut [u8; MAX_LEN], + h: H, + ) -> Result + where + H: DecodeErrorHandler, + { + self.to_managed_buffer() + .into_max_size_buffer_align_right(buffer, h) + } + #[inline] fn into_u64(self, _h: H) -> Result where diff --git a/framework/base/src/io/arg_error_handler.rs b/framework/base/src/io/arg_error_handler.rs index 3fd6c19c8f..10b3fa2560 100644 --- a/framework/base/src/io/arg_error_handler.rs +++ b/framework/base/src/io/arg_error_handler.rs @@ -1,4 +1,4 @@ -use core::marker::PhantomData; +use core::{convert::Infallible, marker::PhantomData}; use crate::{ api::{ErrorApi, ManagedTypeApi}, @@ -33,7 +33,7 @@ impl DecodeErrorHandler for ArgErrorHandler where M: ManagedTypeApi + ErrorApi, { - type HandledErr = !; + type HandledErr = Infallible; #[inline(always)] fn handle_error(&self, err: DecodeError) -> Self::HandledErr { diff --git a/framework/base/src/io/arg_nested_tuple.rs b/framework/base/src/io/arg_nested_tuple.rs index c3838766e3..fca34c9886 100644 --- a/framework/base/src/io/arg_nested_tuple.rs +++ b/framework/base/src/io/arg_nested_tuple.rs @@ -1,3 +1,5 @@ +use unwrap_infallible::UnwrapInfallible; + use super::{EndpointDynArgLoader, EndpointSingleArgLoader, ManagedResultArgLoader}; use crate::{ api::{ @@ -71,8 +73,7 @@ where { let mut arg_loader = EndpointSingleArgLoader::::new(index); let h = ArgErrorHandler::::from(arg_id); - let Ok(value) = T::multi_decode_or_handle_err(&mut arg_loader, h); - value + T::multi_decode_or_handle_err(&mut arg_loader, h).unwrap_infallible() } #[inline(never)] @@ -83,9 +84,7 @@ where T: TopDecodeMulti, { let h = ArgErrorHandler::::from(arg_id); - let result = T::multi_decode_or_handle_err(loader, h); - let Ok(value) = result; - value + T::multi_decode_or_handle_err(loader, h).unwrap_infallible() } /// Models an argument tree of the form `(arg1, (arg2, ... (argn, ())))`, used for retrieving endpoint arguments. diff --git a/framework/base/src/io/finish.rs b/framework/base/src/io/finish.rs index f44cc02c5e..45e9f6c13d 100644 --- a/framework/base/src/io/finish.rs +++ b/framework/base/src/io/finish.rs @@ -1,5 +1,7 @@ use core::marker::PhantomData; +use unwrap_infallible::UnwrapInfallible; + use crate::codec::{EncodeErrorHandler, TopEncodeMulti, TopEncodeMultiOutput, TryStaticCast}; use crate::{ @@ -8,8 +10,8 @@ use crate::{ contract_base::ExitCodecErrorHandler, err_msg, types::{ - BigInt, BigUint, ManagedBuffer, ManagedBufferCachedBuilder, ManagedSCError, ManagedType, - SCError, StaticSCError, + BigInt, BigUint, ManagedBuffer, ManagedBufferBuilder, ManagedSCError, ManagedType, SCError, + StaticSCError, }, }; @@ -20,7 +22,8 @@ where { let h = ExitCodecErrorHandler::::from(err_msg::FINISH_ENCODE_ERROR); let mut output = ApiOutputAdapter::::default(); - let Ok(()) = item.multi_encode_or_handle_err(&mut output, h); + item.multi_encode_or_handle_err(&mut output, h) + .unwrap_infallible() } #[derive(Clone)] @@ -47,7 +50,7 @@ impl TopEncodeOutput for ApiOutputAdapter where FA: ManagedTypeApi + EndpointFinishApi, { - type NestedBuffer = ManagedBufferCachedBuilder; + type NestedBuffer = ManagedBufferBuilder; fn set_slice_u8(self, bytes: &[u8]) { FA::finish_api_impl().finish_slice_u8(bytes); @@ -94,7 +97,7 @@ where } fn start_nested_encode(&self) -> Self::NestedBuffer { - ManagedBufferCachedBuilder::new_from_slice(&[]) + ManagedBufferBuilder::new_from_slice(&[]) } fn finalize_nested_encode(self, nb: Self::NestedBuffer) { diff --git a/framework/base/src/io/signal_error.rs b/framework/base/src/io/signal_error.rs index c84c1273fb..5a78918fba 100644 --- a/framework/base/src/io/signal_error.rs +++ b/framework/base/src/io/signal_error.rs @@ -10,9 +10,10 @@ pub fn signal_arg_de_error(arg_id: ArgId, decode_err: DecodeError) -> ! where EA: ManagedTypeApi + ErrorApi, { - let mut message_buffer = ManagedBuffer::::new_from_bytes(err_msg::ARG_DECODE_ERROR_1); + let mut message_buffer = + ManagedBuffer::::new_from_bytes(err_msg::ARG_DECODE_ERROR_1.as_bytes()); message_buffer.append_bytes(arg_id.as_bytes()); - message_buffer.append_bytes(err_msg::ARG_DECODE_ERROR_2); + message_buffer.append_bytes(err_msg::ARG_DECODE_ERROR_2.as_bytes()); message_buffer.append_bytes(decode_err.message_bytes()); EA::error_api_impl().signal_error_from_buffer(message_buffer.get_handle()) } diff --git a/framework/base/src/lib.rs b/framework/base/src/lib.rs index 951e3b5b4f..3b8fc6c0f5 100644 --- a/framework/base/src/lib.rs +++ b/framework/base/src/lib.rs @@ -1,11 +1,4 @@ #![no_std] -#![feature(never_type)] -#![feature(exhaustive_patterns)] -#![feature(try_trait_v2)] -#![feature(control_flow_enum)] -#![feature(negative_impls)] -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] #![allow(deprecated)] pub use multiversx_sc_derive::{self as derive, contract, module, proxy}; @@ -23,7 +16,6 @@ pub mod abi; pub mod api; pub mod contract_base; pub mod err_msg; -pub mod esdt; pub mod external_view_contract; pub mod formatter; pub mod hex_call_data; @@ -32,6 +24,7 @@ pub mod log_util; mod macros; pub mod non_zero_util; pub mod storage; +pub mod tuple_util; pub mod types; pub use hex_call_data::*; @@ -39,39 +32,12 @@ pub use hex_literal; pub use storage::{storage_clear, storage_get, storage_get_len, storage_set}; /// Conveniently groups all framework imports required by a smart contract form the framework. -pub mod imports { - pub use crate::{ - abi::TypeAbi, - api::{ErrorApiImpl, ManagedTypeApi}, - arrayvec::ArrayVec, - codec::{ - multi_types::*, DecodeError, IntoMultiValue, NestedDecode, NestedEncode, TopDecode, - TopEncode, - }, - contract_base::{ContractBase, ProxyObjBase}, - err_msg, - esdt::*, - io::*, - non_zero_usize, - non_zero_util::*, - require, sc_format, sc_panic, sc_print, - storage::mappers::*, - types::*, - }; - pub use core::ops::{ - Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, - DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign, - }; -} +pub mod imports; /// Conveniently groups all imports required for deriving framework-related traits for types. -pub mod derive_imports { - pub use crate::{ - codec, - codec::derive::{ - NestedDecode, NestedEncode, TopDecode, TopDecodeOrDefault, TopEncode, - TopEncodeOrDefault, - }, - derive::{ManagedVecItem, TypeAbi}, - }; +pub mod derive_imports; + +/// Conveniently groups all imports required for generated proxies. +pub mod proxy_imports { + pub use super::{derive_imports::*, imports::*}; } diff --git a/framework/base/src/log_util.rs b/framework/base/src/log_util.rs index 4fa4b14963..0cca3bc2a2 100644 --- a/framework/base/src/log_util.rs +++ b/framework/base/src/log_util.rs @@ -1,3 +1,5 @@ +use unwrap_infallible::UnwrapInfallible; + use crate::codec::{TopEncode, TopEncodeMulti}; use crate::{ @@ -21,10 +23,12 @@ where A: ErrorApi + ManagedTypeApi, T: TopEncodeMulti, { - let Ok(()) = topic.multi_encode_or_handle_err( - accumulator, - ExitCodecErrorHandler::::from(err_msg::LOG_TOPIC_ENCODE_ERROR), - ); + topic + .multi_encode_or_handle_err( + accumulator, + ExitCodecErrorHandler::::from(err_msg::LOG_TOPIC_ENCODE_ERROR), + ) + .unwrap_infallible(); } pub fn serialize_log_data(data: T) -> ManagedBuffer @@ -33,10 +37,11 @@ where A: ErrorApi + ManagedTypeApi, { let mut data_buffer = ManagedBuffer::new(); - let Ok(()) = data.top_encode_or_handle_err( + data.top_encode_or_handle_err( &mut data_buffer, ExitCodecErrorHandler::::from(err_msg::LOG_DATA_ENCODE_ERROR), - ); + ) + .unwrap_infallible(); data_buffer } diff --git a/framework/base/src/macros.rs b/framework/base/src/macros.rs index 1754688d03..86c963a057 100644 --- a/framework/base/src/macros.rs +++ b/framework/base/src/macros.rs @@ -63,7 +63,7 @@ macro_rules! require_old { macro_rules! sc_panic { ($msg:tt, $($arg:expr),+ $(,)?) => {{ let mut ___buffer___ = - multiversx_sc::types::ManagedBufferCachedBuilder::::new_from_slice(&[]); + multiversx_sc::types::ManagedBufferBuilder::::new_from_slice(&[]); multiversx_sc::derive::format_receiver_args!(___buffer___, $msg, $($arg),+); multiversx_sc::contract_base::ErrorHelper::::signal_error_with_message(___buffer___.into_managed_buffer()); }}; @@ -123,7 +123,7 @@ macro_rules! sc_print { macro_rules! sc_format { ($msg:tt, $($arg:expr),+ $(,)?) => {{ let mut ___buffer___ = - multiversx_sc::types::ManagedBufferCachedBuilder::::new_from_slice(&[]); + multiversx_sc::types::ManagedBufferBuilder::::new_from_slice(&[]); multiversx_sc::derive::format_receiver_args!(___buffer___, $msg, $($arg),+); ___buffer___.into_managed_buffer() }}; diff --git a/framework/base/src/storage/mappers/bi_di_mapper.rs b/framework/base/src/storage/mappers/bi_di_mapper.rs index 42c55e5275..c47f38474c 100644 --- a/framework/base/src/storage/mappers/bi_di_mapper.rs +++ b/framework/base/src/storage/mappers/bi_di_mapper.rs @@ -1,8 +1,9 @@ use core::marker::PhantomData; use crate::{ + abi::TypeAbiFrom, codec::{ - multi_encode_iter_or_handle_err, multi_types::MultiValue2, CodecFrom, EncodeErrorHandler, + multi_encode_iter_or_handle_err, multi_types::MultiValue2, EncodeErrorHandler, NestedDecode, NestedEncode, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, }, types::ManagedAddress, @@ -298,7 +299,7 @@ where } } -impl CodecFrom> +impl TypeAbiFrom> for MultiValueEncoded> where SA: StorageMapperApi, @@ -307,6 +308,14 @@ where { } +impl TypeAbiFrom for BiDiMapper +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, + V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, +{ +} + impl TypeAbi for BiDiMapper where SA: StorageMapperApi, @@ -327,10 +336,16 @@ where + PartialEq + TypeAbi, { + type Unmanaged = Self; + fn type_name() -> TypeName { MultiValueEncoded::>::type_name() } + fn type_name_rust() -> TypeName { + MultiValueEncoded::>::type_name_rust() + } + fn provide_type_descriptions(accumulator: &mut TDC) { K::provide_type_descriptions(accumulator); V::provide_type_descriptions(accumulator); diff --git a/framework/base/src/storage/mappers/linked_list_mapper.rs b/framework/base/src/storage/mappers/linked_list_mapper.rs index d58c0ad19d..fd65fdec91 100644 --- a/framework/base/src/storage/mappers/linked_list_mapper.rs +++ b/framework/base/src/storage/mappers/linked_list_mapper.rs @@ -5,7 +5,7 @@ use super::{ StorageClearable, StorageMapper, }; use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::StorageMapperApi, codec::{ self, @@ -13,8 +13,8 @@ use crate::{ NestedDecode, NestedEncode, TopDecode, TopDecodeOrDefault, TopEncode, TopEncodeOrDefault, }, - CodecFrom, DecodeDefault, EncodeDefault, EncodeErrorHandler, NestedDecode, NestedEncode, - TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, + DecodeDefault, EncodeDefault, EncodeErrorHandler, NestedDecode, NestedEncode, TopDecode, + TopEncode, TopEncodeMulti, TopEncodeMultiOutput, }, storage::{storage_set, StorageKey}, types::{heap::BoxedBytes, ManagedAddress, ManagedType, MultiValueEncoded}, @@ -612,11 +612,18 @@ where } } -impl CodecFrom> for MultiValueEncoded +impl TypeAbiFrom> for MultiValueEncoded +where + SA: StorageMapperApi, + T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, + U: TypeAbiFrom, +{ +} + +impl TypeAbiFrom for LinkedListMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, - U: CodecFrom, { } @@ -625,10 +632,16 @@ where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + TypeAbi, { + type Unmanaged = Self; + fn type_name() -> TypeName { crate::abi::type_name_variadic::() } + fn type_name_rust() -> TypeName { + crate::abi::type_name_multi_value_encoded::() + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/storage/mappers/map_mapper.rs b/framework/base/src/storage/mappers/map_mapper.rs index af4bbda6ff..aa5d105b9e 100644 --- a/framework/base/src/storage/mappers/map_mapper.rs +++ b/framework/base/src/storage/mappers/map_mapper.rs @@ -5,10 +5,10 @@ use super::{ SetMapper, StorageClearable, StorageMapper, }; use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::StorageMapperApi, codec::{ - multi_encode_iter_or_handle_err, multi_types::MultiValue2, CodecFrom, EncodeErrorHandler, + multi_encode_iter_or_handle_err, multi_types::MultiValue2, EncodeErrorHandler, NestedDecode, NestedEncode, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, }, storage::{storage_clear, storage_set, StorageKey}, @@ -539,7 +539,7 @@ where } } -impl CodecFrom> +impl TypeAbiFrom> for MultiValueEncoded> where SA: StorageMapperApi, @@ -548,6 +548,14 @@ where { } +impl TypeAbiFrom for MapMapper +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + V: TopEncode + TopDecode + 'static, +{ +} + /// Behaves like a MultiResultVec> when an endpoint result. impl TypeAbi for MapMapper where @@ -555,10 +563,16 @@ where K: TopEncode + TopDecode + NestedEncode + NestedDecode + TypeAbi + 'static, V: TopEncode + TopDecode + TypeAbi + 'static, { + type Unmanaged = Self; + fn type_name() -> TypeName { MultiValueEncoded::>::type_name() } + fn type_name_rust() -> TypeName { + MultiValueEncoded::>::type_name_rust() + } + fn provide_type_descriptions(accumulator: &mut TDC) { K::provide_type_descriptions(accumulator); V::provide_type_descriptions(accumulator); diff --git a/framework/base/src/storage/mappers/map_storage_mapper.rs b/framework/base/src/storage/mappers/map_storage_mapper.rs index e19f005861..5b101452b8 100644 --- a/framework/base/src/storage/mappers/map_storage_mapper.rs +++ b/framework/base/src/storage/mappers/map_storage_mapper.rs @@ -7,6 +7,7 @@ use super::{ use crate::{ api::StorageMapperApi, codec::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + contract_base::ErrorHelper, storage::{self, StorageKey}, types::ManagedAddress, }; @@ -232,7 +233,9 @@ where #[inline] fn next(&mut self) -> Option<(K, V)> { if let Some(key) = self.key_iter.next() { - let value = self.hash_map.get(&key).unwrap(); + let Some(value) = self.hash_map.get(&key) else { + ErrorHelper::::signal_error_with_message("missing key") + }; return Some((key, value)); } None diff --git a/framework/base/src/storage/mappers/ordered_binary_tree_mapper.rs b/framework/base/src/storage/mappers/ordered_binary_tree_mapper.rs index 8d56c302aa..064e90551c 100644 --- a/framework/base/src/storage/mappers/ordered_binary_tree_mapper.rs +++ b/framework/base/src/storage/mappers/ordered_binary_tree_mapper.rs @@ -3,10 +3,10 @@ use core::marker::PhantomData; use codec::Empty; use crate::{ - api::StorageMapperApi, - imports::{ErrorApiImpl, ManagedType}, + api::{ErrorApiImpl, StorageMapperApi}, storage::StorageKey, storage_set, + types::ManagedType, }; use super::{ @@ -239,7 +239,7 @@ where let mut opt_new_node_parent = None; let mut opt_current_node = self.get_root(); while opt_current_node.is_some() { - opt_new_node_parent = opt_current_node.clone(); + opt_new_node_parent.clone_from(&opt_current_node); let current_node = unsafe { opt_current_node.unwrap_unchecked() }; if new_node.data == current_node.data { diff --git a/framework/base/src/storage/mappers/queue_mapper.rs b/framework/base/src/storage/mappers/queue_mapper.rs index 79ac5f37d7..ac65764c36 100644 --- a/framework/base/src/storage/mappers/queue_mapper.rs +++ b/framework/base/src/storage/mappers/queue_mapper.rs @@ -5,13 +5,13 @@ use super::{ StorageClearable, StorageMapper, }; use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::StorageMapperApi, codec::{ self, derive::{TopDecode, TopDecodeOrDefault, TopEncode, TopEncodeOrDefault}, - multi_encode_iter_or_handle_err, CodecFrom, DecodeDefault, EncodeDefault, - EncodeErrorHandler, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, + multi_encode_iter_or_handle_err, DecodeDefault, EncodeDefault, EncodeErrorHandler, + TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, }, storage::{storage_set, StorageKey}, types::{ManagedAddress, ManagedType, MultiValueEncoded}, @@ -518,7 +518,14 @@ where } } -impl CodecFrom> for MultiValueEncoded +impl TypeAbiFrom> for MultiValueEncoded +where + SA: StorageMapperApi, + T: TopEncode + TopDecode, +{ +} + +impl TypeAbiFrom for QueueMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -531,10 +538,16 @@ where SA: StorageMapperApi, T: TopEncode + TopDecode + TypeAbi, { + type Unmanaged = Self; + fn type_name() -> TypeName { crate::abi::type_name_variadic::() } + fn type_name_rust() -> TypeName { + crate::abi::type_name_multi_value_encoded::() + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/storage/mappers/set_mapper.rs b/framework/base/src/storage/mappers/set_mapper.rs index 28941a7a8c..2ab1deb4f2 100644 --- a/framework/base/src/storage/mappers/set_mapper.rs +++ b/framework/base/src/storage/mappers/set_mapper.rs @@ -5,11 +5,11 @@ use storage_get_from_address::storage_get_len_from_address; pub use super::queue_mapper::Iter; use super::{QueueMapper, StorageClearable, StorageMapper}; use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::StorageMapperApi, codec::{ - self, multi_encode_iter_or_handle_err, CodecFrom, EncodeErrorHandler, NestedDecode, - NestedEncode, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, + self, multi_encode_iter_or_handle_err, EncodeErrorHandler, NestedDecode, NestedEncode, + TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, }, storage::{storage_get_from_address, storage_set, StorageKey}, storage_get, storage_get_len, @@ -294,7 +294,14 @@ where } } -impl CodecFrom> for MultiValueEncoded +impl TypeAbiFrom> for MultiValueEncoded +where + SA: StorageMapperApi, + T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, +{ +} + +impl TypeAbiFrom for SetMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, @@ -307,10 +314,16 @@ where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode + TypeAbi, { + type Unmanaged = Self; + fn type_name() -> TypeName { crate::abi::type_name_variadic::() } + fn type_name_rust() -> TypeName { + crate::abi::type_name_multi_value_encoded::() + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/storage/mappers/single_value_mapper.rs b/framework/base/src/storage/mappers/single_value_mapper.rs index b00d605542..1f121250ff 100644 --- a/framework/base/src/storage/mappers/single_value_mapper.rs +++ b/framework/base/src/storage/mappers/single_value_mapper.rs @@ -5,12 +5,11 @@ use super::{ StorageMapper, }; use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::StorageMapperApi, codec::{ - multi_types::PlaceholderOutput, CodecFrom, CodecFromSelf, DecodeErrorHandler, - EncodeErrorHandler, TopDecode, TopDecodeInput, TopEncode, TopEncodeMulti, - TopEncodeMultiOutput, TopEncodeOutput, + multi_types::PlaceholderOutput, DecodeErrorHandler, EncodeErrorHandler, TopDecode, + TopDecodeInput, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, TopEncodeOutput, }, storage::{storage_clear, storage_set, StorageKey}, types::{ManagedAddress, ManagedType}, @@ -158,7 +157,7 @@ where /// Intermediary type for deserializing the result of an endpoint that returns a `SingleValueMapper`. /// -/// Necessary because we cannot implement `CodecFrom` directly on `T`. +/// Necessary because we cannot implement `TypeAbiFrom` directly on `T`. pub struct SingleValue(T); impl TopEncode for SingleValue { @@ -194,26 +193,25 @@ impl SingleValue { } } -impl !CodecFromSelf for SingleValueMapper +impl TypeAbiFrom> for SingleValue where SA: StorageMapperApi, - A: StorageAddress, T: TopEncode + TopDecode, + R: TopDecode + TypeAbiFrom, { } -impl CodecFrom> for SingleValue +impl TypeAbiFrom> for PlaceholderOutput where SA: StorageMapperApi, T: TopEncode + TopDecode, - R: TopDecode + CodecFrom, { } -impl CodecFrom> for PlaceholderOutput +impl TypeAbiFrom for SingleValueMapper where SA: StorageMapperApi, - T: TopEncode + TopDecode, + T: TopEncode + TopDecode + TypeAbi, { } @@ -222,10 +220,16 @@ where SA: StorageMapperApi, T: TopEncode + TopDecode + TypeAbi, { + type Unmanaged = T::Unmanaged; + fn type_name() -> TypeName { T::type_name() } + fn type_name_rust() -> TypeName { + T::type_name_rust() + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator) } diff --git a/framework/base/src/storage/mappers/token/fungible_token_mapper.rs b/framework/base/src/storage/mappers/token/fungible_token_mapper.rs index 5cc3b88e2a..384e0d6096 100644 --- a/framework/base/src/storage/mappers/token/fungible_token_mapper.rs +++ b/framework/base/src/storage/mappers/token/fungible_token_mapper.rs @@ -1,8 +1,12 @@ use crate::{ - abi::TypeAbi, + abi::{TypeAbi, TypeAbiFrom}, api::ErrorApiImpl, - codec::{CodecFrom, EncodeErrorHandler, TopEncodeMulti, TopEncodeMultiOutput}, + codec::{EncodeErrorHandler, TopEncodeMulti, TopEncodeMultiOutput}, storage_clear, storage_get, storage_set, + types::{ + system_proxy::{ESDTSystemSCProxy, FungibleTokenProperties}, + ESDTSystemSCAddress, Tx, + }, }; use super::{ @@ -14,11 +18,10 @@ use crate::{ abi::TypeName, api::{CallTypeApi, StorageMapperApi}, contract_base::{BlockchainWrapper, SendWrapper}, - esdt::{ESDTSystemSmartContractProxy, FungibleTokenProperties}, storage::StorageKey, types::{ - BigUint, CallbackClosure, ContractCall, EsdtTokenPayment, EsdtTokenType, ManagedAddress, - ManagedBuffer, ManagedType, TokenIdentifier, + BigUint, CallbackClosure, EsdtTokenPayment, EsdtTokenType, ManagedAddress, ManagedBuffer, + ManagedType, TokenIdentifier, }, }; @@ -113,7 +116,6 @@ where ) -> ! { check_not_set(self); - let system_sc_proxy = ESDTSystemSmartContractProxy::::new_proxy_obj(); let callback = match opt_callback { Some(cb) => cb, None => self.default_callback_closure_obj(&initial_supply), @@ -124,7 +126,9 @@ where }; storage_set(self.get_storage_key(), &TokenMapperState::::Pending); - system_sc_proxy + Tx::new_tx_from_sc() + .to(ESDTSystemSCAddress) + .typed(ESDTSystemSCProxy) .issue_fungible( issue_cost, &token_display_name, @@ -132,9 +136,8 @@ where &initial_supply, properties, ) - .async_call() - .with_callback(callback) - .call_and_exit(); + .callback(callback) + .async_call_and_exit() } /// Important: If you use custom callback, remember to save the token ID in the callback and clear the mapper in case of error! Clear is unusable outside this specific case. @@ -165,14 +168,15 @@ where ) -> ! { check_not_set(self); - let system_sc_proxy = ESDTSystemSmartContractProxy::::new_proxy_obj(); let callback = match opt_callback { Some(cb) => cb, None => self.default_callback_closure_obj(&BigUint::zero()), }; storage_set(self.get_storage_key(), &TokenMapperState::::Pending); - system_sc_proxy + Tx::new_tx_from_sc() + .to(ESDTSystemSCAddress) + .typed(ESDTSystemSCProxy) .issue_and_set_all_roles( issue_cost, token_display_name, @@ -180,9 +184,8 @@ where EsdtTokenType::Fungible, num_decimals, ) - .async_call() - .with_callback(callback) - .call_and_exit(); + .callback(callback) + .async_call_and_exit(); } pub fn clear(&mut self) { @@ -243,8 +246,10 @@ where } fn send_payment(&self, to: &ManagedAddress, payment: &EsdtTokenPayment) { - let send_wrapper = SendWrapper::::new(); - send_wrapper.direct_esdt(to, &payment.token_identifier, 0, &payment.amount); + Tx::new_tx_from_sc() + .to(to) + .single_esdt(&payment.token_identifier, 0, &payment.amount) + .transfer(); } } @@ -265,19 +270,27 @@ where } } -impl CodecFrom> for TokenIdentifier where +impl TypeAbiFrom> for TokenIdentifier where SA: StorageMapperApi + CallTypeApi { } +impl TypeAbiFrom for FungibleTokenMapper where SA: StorageMapperApi + CallTypeApi {} + impl TypeAbi for FungibleTokenMapper where SA: StorageMapperApi + CallTypeApi, { + type Unmanaged = Self; + fn type_name() -> TypeName { TokenIdentifier::::type_name() } + fn type_name_rust() -> TypeName { + TokenIdentifier::::type_name_rust() + } + fn provide_type_descriptions(accumulator: &mut TDC) { TokenIdentifier::::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/storage/mappers/token/non_fungible_token_mapper.rs b/framework/base/src/storage/mappers/token/non_fungible_token_mapper.rs index 11207c70a3..70fc3be81f 100644 --- a/framework/base/src/storage/mappers/token/non_fungible_token_mapper.rs +++ b/framework/base/src/storage/mappers/token/non_fungible_token_mapper.rs @@ -1,8 +1,11 @@ use crate::{ - codec::{ - CodecFrom, EncodeErrorHandler, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, - }, + abi::TypeAbiFrom, + codec::{EncodeErrorHandler, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput}, storage_clear, storage_get, storage_set, + types::{ + system_proxy::ESDTSystemSCProxy, ESDTSystemSCAddress, EgldPayment, FunctionCall, + OriginalResultMarker, Tx, TxScEnv, + }, }; use super::{ @@ -15,20 +18,28 @@ use crate::{ abi::{TypeAbi, TypeName}, api::{CallTypeApi, ErrorApiImpl, StorageMapperApi}, contract_base::{BlockchainWrapper, SendWrapper}, - esdt::{ - ESDTSystemSmartContractProxy, MetaTokenProperties, NonFungibleTokenProperties, - SemiFungibleTokenProperties, - }, storage::StorageKey, types::{ - BigUint, CallbackClosure, ContractCall, ContractCallWithEgld, EsdtTokenData, - EsdtTokenPayment, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedType, - TokenIdentifier, + system_proxy::{ + MetaTokenProperties, NonFungibleTokenProperties, SemiFungibleTokenProperties, + }, + BigUint, CallbackClosure, EsdtTokenData, EsdtTokenPayment, EsdtTokenType, ManagedAddress, + ManagedBuffer, ManagedType, TokenIdentifier, }, }; const INVALID_TOKEN_TYPE_ERR_MSG: &[u8] = b"Invalid token type for NonFungible issue"; +pub type IssueCallTo = Tx< + TxScEnv, + (), + ESDTSystemSCAddress, + EgldPayment, + (), + FunctionCall, + OriginalResultMarker>, +>; + pub struct NonFungibleTokenMapper where SA: StorageMapperApi + CallTypeApi, @@ -134,10 +145,7 @@ where }; storage_set(self.get_storage_key(), &TokenMapperState::::Pending); - contract_call - .async_call() - .with_callback(callback) - .call_and_exit(); + contract_call.with_callback(callback).async_call_and_exit(); } /// Important: If you use custom callback, remember to save the token ID in the callback and clear the mapper in case of error! Clear is unusable outside this specific case. @@ -173,14 +181,15 @@ where SA::error_api_impl().signal_error(INVALID_TOKEN_TYPE_ERR_MSG); } - let system_sc_proxy = ESDTSystemSmartContractProxy::::new_proxy_obj(); let callback = match opt_callback { Some(cb) => cb, None => self.default_callback_closure_obj(), }; storage_set(self.get_storage_key(), &TokenMapperState::::Pending); - system_sc_proxy + Tx::new_tx_from_sc() + .to(ESDTSystemSCAddress) + .typed(ESDTSystemSCProxy) .issue_and_set_all_roles( issue_cost, token_display_name, @@ -188,9 +197,8 @@ where token_type, num_decimals, ) - .async_call() - .with_callback(callback) - .call_and_exit(); + .callback(callback) + .async_call_and_exit() } pub fn clear(&mut self) { @@ -215,28 +223,32 @@ where issue_cost: BigUint, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer, - ) -> ContractCallWithEgld { - let system_sc_proxy = ESDTSystemSmartContractProxy::::new_proxy_obj(); - system_sc_proxy.issue_non_fungible( - issue_cost, - &token_display_name, - &token_ticker, - NonFungibleTokenProperties::default(), - ) + ) -> IssueCallTo { + Tx::new_tx_from_sc() + .to(ESDTSystemSCAddress) + .typed(ESDTSystemSCProxy) + .issue_non_fungible( + issue_cost, + &token_display_name, + &token_ticker, + NonFungibleTokenProperties::default(), + ) } fn sft_issue( issue_cost: BigUint, token_display_name: ManagedBuffer, token_ticker: ManagedBuffer, - ) -> ContractCallWithEgld { - let system_sc_proxy = ESDTSystemSmartContractProxy::::new_proxy_obj(); - system_sc_proxy.issue_semi_fungible( - issue_cost, - &token_display_name, - &token_ticker, - SemiFungibleTokenProperties::default(), - ) + ) -> IssueCallTo { + Tx::new_tx_from_sc() + .to(ESDTSystemSCAddress) + .typed(ESDTSystemSCProxy) + .issue_semi_fungible( + issue_cost, + &token_display_name, + &token_ticker, + SemiFungibleTokenProperties::default(), + ) } fn meta_issue( @@ -244,19 +256,16 @@ where token_display_name: ManagedBuffer, token_ticker: ManagedBuffer, num_decimals: usize, - ) -> ContractCallWithEgld { - let system_sc_proxy = ESDTSystemSmartContractProxy::::new_proxy_obj(); + ) -> IssueCallTo { let properties = MetaTokenProperties { num_decimals, ..Default::default() }; - system_sc_proxy.register_meta_esdt( - issue_cost, - &token_display_name, - &token_ticker, - properties, - ) + Tx::new_tx_from_sc() + .to(ESDTSystemSCAddress) + .typed(ESDTSystemSCProxy) + .register_meta_esdt(issue_cost, &token_display_name, &token_ticker, properties) } pub fn nft_create( @@ -368,13 +377,14 @@ where } fn send_payment(&self, to: &ManagedAddress, payment: &EsdtTokenPayment) { - let send_wrapper = SendWrapper::::new(); - send_wrapper.direct_esdt( - to, - &payment.token_identifier, - payment.token_nonce, - &payment.amount, - ); + Tx::new_tx_from_sc() + .to(to) + .single_esdt( + &payment.token_identifier, + payment.token_nonce, + &payment.amount, + ) + .transfer(); } } @@ -395,19 +405,27 @@ where } } -impl CodecFrom> for TokenIdentifier where +impl TypeAbiFrom> for TokenIdentifier where SA: StorageMapperApi + CallTypeApi { } +impl TypeAbiFrom for NonFungibleTokenMapper where SA: StorageMapperApi + CallTypeApi {} + impl TypeAbi for NonFungibleTokenMapper where SA: StorageMapperApi + CallTypeApi, { + type Unmanaged = Self; + fn type_name() -> TypeName { TokenIdentifier::::type_name() } + fn type_name_rust() -> TypeName { + TokenIdentifier::::type_name_rust() + } + fn provide_type_descriptions(accumulator: &mut TDC) { TokenIdentifier::::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/storage/mappers/token/token_mapper.rs b/framework/base/src/storage/mappers/token/token_mapper.rs index e0867f7414..77f435a546 100644 --- a/framework/base/src/storage/mappers/token/token_mapper.rs +++ b/framework/base/src/storage/mappers/token/token_mapper.rs @@ -1,12 +1,11 @@ use crate::{ api::{CallTypeApi, ErrorApiImpl, StorageMapperApi}, contract_base::BlockchainWrapper, - esdt::ESDTSystemSmartContractProxy, storage::StorageKey, storage_get, storage_get_len, storage_set, types::{ - CallbackClosure, ContractCall, EsdtLocalRole, EsdtTokenPayment, ManagedAddress, ManagedRef, - ManagedVec, TokenIdentifier, + system_proxy::ESDTSystemSCProxy, CallbackClosure, ESDTSystemSCAddress, EsdtLocalRole, + EsdtTokenPayment, ManagedAddress, ManagedRef, ManagedVec, TokenIdentifier, Tx, }, }; @@ -81,17 +80,13 @@ where ) -> ! { self.require_issued_or_set(); - let system_sc_proxy = ESDTSystemSmartContractProxy::::new_proxy_obj(); let token_id = self.get_token_id_ref(); - let mut async_call = system_sc_proxy + Tx::new_tx_from_sc() + .to(ESDTSystemSCAddress) + .typed(ESDTSystemSCProxy) .set_special_roles(address, token_id, roles[..].iter().cloned()) - .async_call(); - - if let Some(cb) = opt_callback { - async_call = async_call.with_callback(cb); - } - - async_call.call_and_exit() + .callback(opt_callback) + .async_call_and_exit() } fn get_sc_address() -> ManagedAddress { diff --git a/framework/base/src/storage/mappers/unique_id_mapper.rs b/framework/base/src/storage/mappers/unique_id_mapper.rs index 779e1a1b71..4ee1faa624 100644 --- a/framework/base/src/storage/mappers/unique_id_mapper.rs +++ b/framework/base/src/storage/mappers/unique_id_mapper.rs @@ -1,7 +1,7 @@ use crate::{ + abi::TypeAbiFrom, codec::{ - multi_encode_iter_or_handle_err, CodecFrom, EncodeErrorHandler, TopEncodeMulti, - TopEncodeMultiOutput, + multi_encode_iter_or_handle_err, EncodeErrorHandler, TopEncodeMulti, TopEncodeMultiOutput, }, types::ManagedAddress, }; @@ -213,20 +213,28 @@ where } } -impl CodecFrom> for MultiValueEncoded where +impl TypeAbiFrom> for MultiValueEncoded where SA: StorageMapperApi { } +impl TypeAbiFrom for UniqueIdMapper where SA: StorageMapperApi {} + /// Behaves like a MultiResultVec when an endpoint result. impl TypeAbi for UniqueIdMapper where SA: StorageMapperApi, { + type Unmanaged = Self; + fn type_name() -> TypeName { crate::abi::type_name_variadic::() } + fn type_name_rust() -> TypeName { + crate::abi::type_name_multi_value_encoded::() + } + fn provide_type_descriptions(accumulator: &mut TDC) { usize::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/storage/mappers/unordered_set_mapper.rs b/framework/base/src/storage/mappers/unordered_set_mapper.rs index fa151759ea..254e56c6b5 100644 --- a/framework/base/src/storage/mappers/unordered_set_mapper.rs +++ b/framework/base/src/storage/mappers/unordered_set_mapper.rs @@ -6,11 +6,11 @@ use super::{ StorageClearable, StorageMapper, VecMapper, }; use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::StorageMapperApi, codec::{ - multi_encode_iter_or_handle_err, CodecFrom, EncodeErrorHandler, NestedDecode, NestedEncode, - TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, + multi_encode_iter_or_handle_err, EncodeErrorHandler, NestedDecode, NestedEncode, TopDecode, + TopEncode, TopEncodeMulti, TopEncodeMultiOutput, }, storage::StorageKey, storage_clear, storage_set, @@ -225,7 +225,14 @@ where } } -impl CodecFrom> for MultiValueEncoded +impl TypeAbiFrom> for MultiValueEncoded +where + SA: StorageMapperApi, + T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, +{ +} + +impl TypeAbiFrom for UnorderedSetMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, @@ -238,10 +245,16 @@ where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode + TypeAbi, { + type Unmanaged = Self; + fn type_name() -> TypeName { crate::abi::type_name_variadic::() } + fn type_name_rust() -> TypeName { + crate::abi::type_name_multi_value_encoded::() + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/storage/mappers/user_mapper.rs b/framework/base/src/storage/mappers/user_mapper.rs index bbfdcfb27b..52039da9d5 100644 --- a/framework/base/src/storage/mappers/user_mapper.rs +++ b/framework/base/src/storage/mappers/user_mapper.rs @@ -1,8 +1,10 @@ use core::marker::PhantomData; -use crate::codec::{ - multi_encode_iter_or_handle_err, CodecFrom, EncodeErrorHandler, TopEncodeMulti, - TopEncodeMultiOutput, +use crate::{ + abi::TypeAbiFrom, + codec::{ + multi_encode_iter_or_handle_err, EncodeErrorHandler, TopEncodeMulti, TopEncodeMultiOutput, + }, }; use super::{ @@ -219,20 +221,28 @@ where } } -impl CodecFrom> for MultiValueEncoded> where +impl TypeAbiFrom> for MultiValueEncoded> where SA: StorageMapperApi { } +impl TypeAbiFrom for UserMapper where SA: StorageMapperApi {} + /// Behaves like a MultiResultVec when an endpoint result. impl TypeAbi for UserMapper where SA: StorageMapperApi, { + type Unmanaged = Self; + fn type_name() -> TypeName { crate::abi::type_name_variadic::>() } + fn type_name_rust() -> TypeName { + crate::abi::type_name_multi_value_encoded::>() + } + fn is_variadic() -> bool { true } diff --git a/framework/base/src/storage/mappers/vec_mapper.rs b/framework/base/src/storage/mappers/vec_mapper.rs index 49c9c159cc..de2eb55d82 100644 --- a/framework/base/src/storage/mappers/vec_mapper.rs +++ b/framework/base/src/storage/mappers/vec_mapper.rs @@ -3,11 +3,11 @@ use super::{ StorageClearable, StorageMapper, }; use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::{ErrorApiImpl, StorageMapperApi}, codec::{ - multi_encode_iter_or_handle_err, CodecFrom, EncodeErrorHandler, TopDecode, TopEncode, - TopEncodeMulti, TopEncodeMultiOutput, + multi_encode_iter_or_handle_err, EncodeErrorHandler, TopDecode, TopEncode, TopEncodeMulti, + TopEncodeMultiOutput, }, storage::{storage_clear, storage_set, StorageKey}, types::{ManagedAddress, ManagedType, MultiValueEncoded}, @@ -202,7 +202,7 @@ where /// Set item at index in storage. /// Index must be valid (1 <= index <= count). - pub fn set(&self, index: usize, item: &T) { + pub fn set(&mut self, index: usize, item: &T) { if index == 0 || index > self.len() { SA::error_api_impl().signal_error(&b"index out of range"[..]); } @@ -344,7 +344,14 @@ where } } -impl CodecFrom> for MultiValueEncoded +impl TypeAbiFrom> for MultiValueEncoded +where + SA: StorageMapperApi, + T: TopEncode + TopDecode, +{ +} + +impl TypeAbiFrom for VecMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -357,10 +364,16 @@ where SA: StorageMapperApi, T: TopEncode + TopDecode + TypeAbi, { + type Unmanaged = Self; + fn type_name() -> TypeName { crate::abi::type_name_variadic::() } + fn type_name_rust() -> TypeName { + crate::abi::type_name_multi_value_encoded::() + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/storage/storage_get.rs b/framework/base/src/storage/storage_get.rs index c4504df70f..4fc8ee9259 100644 --- a/framework/base/src/storage/storage_get.rs +++ b/framework/base/src/storage/storage_get.rs @@ -1,4 +1,4 @@ -use core::marker::PhantomData; +use core::{convert::Infallible, marker::PhantomData}; use crate::{ api::{ @@ -12,6 +12,7 @@ use crate::{ }, }; use alloc::boxed::Box; +use unwrap_infallible::UnwrapInfallible; use super::StorageKey; @@ -81,6 +82,27 @@ where self.to_managed_buffer().into_max_size_buffer(buffer, h) } + #[inline] + fn into_max_size_buffer_align_right( + self, + buffer: &mut [u8; MAX_LEN], + h: H, + ) -> Result + where + H: DecodeErrorHandler, + { + self.to_managed_buffer() + .into_max_size_buffer_align_right(buffer, h) + } + + #[inline] + fn into_i64(self, h: H) -> Result + where + H: DecodeErrorHandler, + { + self.to_managed_buffer().into_i64(h) + } + #[inline] fn supports_specialized_type() -> bool { T::type_eq::>() || T::type_eq::>() || T::type_eq::>() @@ -113,11 +135,11 @@ where T: TopDecode, A: StorageReadApi + ManagedTypeApi + ErrorApi, { - let Ok(value) = T::top_decode_or_handle_err( + T::top_decode_or_handle_err( StorageGetInput::new(key), StorageGetErrorHandler::::default(), - ); - value + ) + .unwrap_infallible() } /// Useful for storage mappers. @@ -158,10 +180,11 @@ impl DecodeErrorHandler for StorageGetErrorHandler where M: ManagedTypeApi + ErrorApi, { - type HandledErr = !; + type HandledErr = Infallible; fn handle_error(&self, err: DecodeError) -> Self::HandledErr { - let mut message_buffer = ManagedBuffer::::new_from_bytes(err_msg::STORAGE_DECODE_ERROR); + let mut message_buffer = + ManagedBuffer::::new_from_bytes(err_msg::STORAGE_DECODE_ERROR.as_bytes()); message_buffer.append_bytes(err.message_bytes()); M::error_api_impl().signal_error_from_buffer(message_buffer.get_handle()) } diff --git a/framework/base/src/storage/storage_get_from_address.rs b/framework/base/src/storage/storage_get_from_address.rs index 8cfeb531f1..504e725724 100644 --- a/framework/base/src/storage/storage_get_from_address.rs +++ b/framework/base/src/storage/storage_get_from_address.rs @@ -10,6 +10,7 @@ use crate::{ }, }; use alloc::boxed::Box; +use unwrap_infallible::UnwrapInfallible; use super::{StorageGetErrorHandler, StorageKey}; @@ -91,6 +92,27 @@ where self.to_managed_buffer().into_max_size_buffer(buffer, h) } + #[inline] + fn into_max_size_buffer_align_right( + self, + buffer: &mut [u8; MAX_LEN], + h: H, + ) -> Result + where + H: DecodeErrorHandler, + { + self.to_managed_buffer() + .into_max_size_buffer_align_right(buffer, h) + } + + #[inline] + fn into_i64(self, h: H) -> Result + where + H: DecodeErrorHandler, + { + self.to_managed_buffer().into_i64(h) + } + #[inline] fn supports_specialized_type() -> bool { T::type_eq::>() || T::type_eq::>() || T::type_eq::>() @@ -126,11 +148,11 @@ where T: TopDecode, A: StorageReadApi + ManagedTypeApi + ErrorApi, { - let Ok(value) = T::top_decode_or_handle_err( + T::top_decode_or_handle_err( StorageGetFromAddressInput::new(addr, key), StorageGetErrorHandler::::default(), - ); - value + ) + .unwrap_infallible() } /// Useful for storage mappers. diff --git a/framework/base/src/storage/storage_key.rs b/framework/base/src/storage/storage_key.rs index 47520108a6..b56358218b 100644 --- a/framework/base/src/storage/storage_key.rs +++ b/framework/base/src/storage/storage_key.rs @@ -1,3 +1,5 @@ +use unwrap_infallible::UnwrapInfallible; + use crate::{ api::{ErrorApi, ManagedTypeApi}, codec::*, @@ -60,10 +62,11 @@ where where T: NestedEncode, { - let Ok(()) = item.dep_encode_or_handle_err( + item.dep_encode_or_handle_err( &mut self.buffer, ExitCodecErrorHandler::::from(err_msg::STORAGE_KEY_ENCODE_ERROR), - ); + ) + .unwrap_infallible() } #[inline] diff --git a/framework/base/src/storage/storage_set.rs b/framework/base/src/storage/storage_set.rs index e988b47351..a2f3c3b722 100644 --- a/framework/base/src/storage/storage_set.rs +++ b/framework/base/src/storage/storage_set.rs @@ -1,3 +1,5 @@ +use unwrap_infallible::UnwrapInfallible; + use crate::{ api::{ const_handles, use_raw_handle, ErrorApi, ManagedBufferApiImpl, ManagedTypeApi, @@ -6,7 +8,7 @@ use crate::{ codec::*, contract_base::ExitCodecErrorHandler, err_msg, - types::{BigInt, BigUint, ManagedBuffer, ManagedBufferCachedBuilder, ManagedRef, ManagedType}, + types::{BigInt, BigUint, ManagedBuffer, ManagedBufferBuilder, ManagedRef, ManagedType}, }; use super::StorageKey; @@ -39,7 +41,7 @@ impl<'k, A> TopEncodeOutput for StorageSetOutput<'k, A> where A: StorageWriteApi + ManagedTypeApi + ErrorApi + 'static, { - type NestedBuffer = ManagedBufferCachedBuilder; + type NestedBuffer = ManagedBufferBuilder; fn set_slice_u8(self, bytes: &[u8]) { self.set_managed_buffer(&bytes.into()) @@ -71,7 +73,7 @@ where } fn start_nested_encode(&self) -> Self::NestedBuffer { - ManagedBufferCachedBuilder::new_from_slice(&[]) + ManagedBufferBuilder::new_from_slice(&[]) } fn finalize_nested_encode(self, nb: Self::NestedBuffer) { @@ -85,10 +87,12 @@ where T: TopEncode, A: StorageWriteApi + ManagedTypeApi + ErrorApi, { - let Ok(()) = value.top_encode_or_handle_err( - StorageSetOutput::new(key), - ExitCodecErrorHandler::::from(err_msg::STORAGE_ENCODE_ERROR), - ); + value + .top_encode_or_handle_err( + StorageSetOutput::new(key), + ExitCodecErrorHandler::::from(err_msg::STORAGE_ENCODE_ERROR), + ) + .unwrap_infallible() } /// Useful for storage mappers. diff --git a/framework/base/src/tuple_util.rs b/framework/base/src/tuple_util.rs new file mode 100644 index 0000000000..717058e641 --- /dev/null +++ b/framework/base/src/tuple_util.rs @@ -0,0 +1,3 @@ +mod nested_tuples; + +pub use nested_tuples::*; diff --git a/framework/base/src/tuple_util/nested_tuples.rs b/framework/base/src/tuple_util/nested_tuples.rs new file mode 100644 index 0000000000..a6dda04391 --- /dev/null +++ b/framework/base/src/tuple_util/nested_tuples.rs @@ -0,0 +1,137 @@ +/// A tuple of the form (A, (B, (... (N, ())))). +/// +/// It is always terminated with a unit. +pub trait NestedTuple {} + +impl NestedTuple for () {} + +impl NestedTuple for (Head, Tail) where Tail: NestedTuple {} + +/// Allows to append at the end of a nested tuple list. +pub trait NestedTupleAppend { + type Output; + + fn append(self, t: T) -> Self::Output; +} + +impl NestedTupleAppend for () { + type Output = (T, ()); + + fn append(self, t: T) -> Self::Output { + (t, ()) + } +} + +impl NestedTupleAppend for (Head, Tail) +where + Tail: NestedTupleAppend, +{ + type Output = (Head, Tail::Output); + + fn append(self, t: T) -> Self::Output { + (self.0, self.1.append(t)) + } +} + +/// Defines conversion of a nested tuple list to a regular tuple. +pub trait NestedTupleFlatten: NestedTuple { + type Flattened; + type Unpacked; + + /// Converts a nested tuple list to a regular tuple. + fn flatten(self) -> Self::Flattened; + + /// Same as `flatten`, converts a nested tuple list to a regular tuple, + /// but additionally, it unpacks singleton tuples into their content (`(item,)` -> `item`). + fn flatten_unpack(self) -> Self::Unpacked; +} + +impl NestedTupleFlatten for () { + type Flattened = (); + type Unpacked = (); + + fn flatten(self) -> Self::Flattened {} + fn flatten_unpack(self) -> Self::Unpacked {} +} + +impl NestedTupleFlatten for (T, ()) { + type Flattened = (T,); + type Unpacked = T; + + fn flatten(self) -> Self::Flattened { + (self.0,) + } + + fn flatten_unpack(self) -> Self::Unpacked { + self.0 + } +} + +macro_rules! tuple_list_type { + () => ( () ); + ($i:ty) => ( ($i, ()) ); + ($i:ty, $($e:ty),*) => ( ($i, tuple_list_type!($($e),*)) ); +} + +macro_rules! unnest { + (($layer:expr); ($($v:expr),*); ($u:ident, $($us:ident,)*)) => { + unnest!(($layer . 1); ($($v,)* $layer . 0); ($($us,)*)) + }; + (($layer:expr); ($($v:expr),*); ()) => { ($($v,)*) }; +} + +macro_rules! flatten_impl { + ($(($t:ident $($ts:ident)+))+) => { + $( + impl<$t,$($ts),+> NestedTupleFlatten for tuple_list_type!($t,$($ts),+) { + type Flattened = ($t,$($ts),+); + type Unpacked = ($t,$($ts),+); + + fn flatten(self) -> Self::Flattened { + unnest!((self); (); ($t, $($ts,)*)) + } + + fn flatten_unpack(self) -> Self::Unpacked { + self.flatten() + } + } + )+ + } +} + +flatten_impl! { + (T1 T2) + (T1 T2 T3) + (T1 T2 T3 T4) + (T1 T2 T3 T4 T5) + (T1 T2 T3 T4 T5 T6) + (T1 T2 T3 T4 T5 T6 T7) + (T1 T2 T3 T4 T5 T6 T7 T8) + (T1 T2 T3 T4 T5 T6 T7 T8 T9) + (T1 T2 T3 T4 T5 T6 T7 T8 T9 T10) + (T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11) + (T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12) + (T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13) + (T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14) + (T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15) + (T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_flatten() { + let flat2 = (1, (2, ())).flatten(); + assert_eq!(flat2, (1, 2)); + + let n3 = (1u8, (2u16, (3u32, ()))); + let flat3 = n3.flatten(); + assert_eq!(flat3, (1u8, 2u16, 3u32)); + + let n4 = n3.append(4u64); + let flat4 = n4.flatten(); + assert_eq!(flat4, (1u8, 2u16, 3u32, 4u64)); + } +} diff --git a/framework/base/src/types/crypto/message_hash_type.rs b/framework/base/src/types/crypto/message_hash_type.rs index 18d3f384fe..209887fdfc 100644 --- a/framework/base/src/types/crypto/message_hash_type.rs +++ b/framework/base/src/types/crypto/message_hash_type.rs @@ -1,7 +1,9 @@ use crate::{ - abi::{TypeAbi, TypeName}, - codec, - codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, + codec::{ + self, + derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + }, }; /// Message hash type for the `verifyCustomSecp256k1` CryptoApi function @@ -38,7 +40,11 @@ impl From for MessageHashType { } } +impl TypeAbiFrom for MessageHashType {} + impl TypeAbi for MessageHashType { + type Unmanaged = Self; + fn type_name() -> TypeName { "MessageHashType".into() } diff --git a/framework/base/src/types/flags/code_metadata.rs b/framework/base/src/types/flags/code_metadata.rs index 89df4b91de..9275e976cf 100644 --- a/framework/base/src/types/flags/code_metadata.rs +++ b/framework/base/src/types/flags/code_metadata.rs @@ -1,7 +1,7 @@ #![allow(clippy::bad_bit_mask)] use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, codec::*, formatter::{hex_util, FormatByteReceiver, SCBinary, SCDisplay, SCLowerHex}, }; @@ -103,10 +103,18 @@ impl TopDecode for CodeMetadata { } } +impl TypeAbiFrom for CodeMetadata {} + impl TypeAbi for CodeMetadata { + type Unmanaged = Self; + fn type_name() -> TypeName { "CodeMetadata".into() } + + fn type_name_rust() -> TypeName { + "CodeMetadata".into() + } } impl SCDisplay for CodeMetadata { diff --git a/framework/base/src/types/flags/esdt_local_role.rs b/framework/base/src/types/flags/esdt_local_role.rs index f0f241d931..b66ac612f5 100644 --- a/framework/base/src/types/flags/esdt_local_role.rs +++ b/framework/base/src/types/flags/esdt_local_role.rs @@ -1,11 +1,13 @@ -use crate::{ - codec, - codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, -}; - use super::EsdtLocalRoleFlags; use crate as multiversx_sc; -use crate::{derive::TypeAbi, types::ManagedVecItem}; +use crate::{ + codec::{ + self, + derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + }, + derive::type_abi, + types::{ManagedVecItem, ManagedVecItemPayloadBuffer}, +}; static ESDT_ROLE_NONE: &[u8] = &[]; static ESDT_ROLE_LOCAL_MINT: &[u8] = b"ESDTRoleLocalMint"; @@ -17,9 +19,8 @@ static ESDT_ROLE_NFT_ADD_URI: &[u8] = b"ESDTRoleNFTAddURI"; static ESDT_ROLE_NFT_UPDATE_ATTRIBUTES: &[u8] = b"ESDTRoleNFTUpdateAttributes"; static ESDT_ROLE_TRANSFER: &[u8] = b"ESDTTransferRole"; -#[derive( - TopDecode, TopEncode, NestedDecode, NestedEncode, TypeAbi, Clone, PartialEq, Eq, Debug, Copy, -)] +#[type_abi] +#[derive(TopDecode, TopEncode, NestedDecode, NestedEncode, Clone, PartialEq, Eq, Debug, Copy)] pub enum EsdtLocalRole { None, Mint, @@ -138,7 +139,7 @@ impl<'a> From<&'a [u8]> for EsdtLocalRole { } impl ManagedVecItem for EsdtLocalRole { - const PAYLOAD_SIZE: usize = 1; + type PAYLOAD = ManagedVecItemPayloadBuffer<1>; const SKIPS_RESERIALIZATION: bool = false; // TODO: might be ok to be true, but needs testing type Ref<'a> = Self; diff --git a/framework/base/src/types/flags/esdt_token_type.rs b/framework/base/src/types/flags/esdt_token_type.rs index 2348254455..e80b91590d 100644 --- a/framework/base/src/types/flags/esdt_token_type.rs +++ b/framework/base/src/types/flags/esdt_token_type.rs @@ -1,6 +1,9 @@ -use multiversx_sc_derive::ManagedVecItem; +use multiversx_sc_derive::{type_abi, ManagedVecItem}; -use crate::codec::*; +use crate::codec::{ + self, + derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, +}; const ESDT_TYPE_FUNGIBLE: &[u8] = b"FungibleESDT"; const ESDT_TYPE_NON_FUNGIBLE: &[u8] = b"NonFungibleESDT"; @@ -9,10 +12,13 @@ const ESDT_TYPE_META: &[u8] = b"MetaESDT"; const ESDT_TYPE_INVALID: &[u8] = &[]; use crate as multiversx_sc; // needed by the TypeAbi generated code -use crate::derive::TypeAbi; // Note: In the current implementation, SemiFungible is never returned -#[derive(Clone, PartialEq, Eq, Debug, TypeAbi, ManagedVecItem)] + +#[type_abi] +#[derive( + TopDecode, TopEncode, NestedDecode, NestedEncode, Clone, PartialEq, Eq, Debug, ManagedVecItem, +)] pub enum EsdtTokenType { Fungible, NonFungible, @@ -80,45 +86,3 @@ impl<'a> From<&'a [u8]> for EsdtTokenType { } } } - -impl NestedEncode for EsdtTokenType { - #[inline] - fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> - where - O: NestedEncodeOutput, - H: EncodeErrorHandler, - { - self.as_u8().dep_encode_or_handle_err(dest, h) - } -} - -impl TopEncode for EsdtTokenType { - #[inline] - fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> - where - O: TopEncodeOutput, - H: EncodeErrorHandler, - { - self.as_u8().top_encode_or_handle_err(output, h) - } -} - -impl NestedDecode for EsdtTokenType { - fn dep_decode_or_handle_err(input: &mut I, h: H) -> Result - where - I: NestedDecodeInput, - H: DecodeErrorHandler, - { - Ok(Self::from(u8::dep_decode_or_handle_err(input, h)?)) - } -} - -impl TopDecode for EsdtTokenType { - fn top_decode_or_handle_err(input: I, h: H) -> Result - where - I: TopDecodeInput, - H: DecodeErrorHandler, - { - Ok(Self::from(u8::top_decode_or_handle_err(input, h)?)) - } -} diff --git a/framework/base/src/types/heap/arg_buffer.rs b/framework/base/src/types/heap/arg_buffer.rs index 9313157c77..c27be12f2c 100644 --- a/framework/base/src/types/heap/arg_buffer.rs +++ b/framework/base/src/types/heap/arg_buffer.rs @@ -1,6 +1,8 @@ use crate::{ + abi::{TypeAbiFrom, TypeName}, api::ManagedTypeApi, codec::TopEncodeOutput, + proxy_imports::TypeAbi, types::{heap::BoxedBytes, ManagedArgBuffer}, }; use alloc::vec::Vec; @@ -111,6 +113,21 @@ impl Clone for ArgBuffer { } } +impl TypeAbiFrom for ArgBuffer {} + +impl TypeAbi for ArgBuffer { + type Unmanaged = Self; + + /// It is semantically equivalent to any list of `T`. + fn type_name() -> TypeName { + <&[Vec] as TypeAbi>::type_name() + } + + fn type_name_rust() -> TypeName { + "ArgBuffer".into() + } +} + impl TopEncodeOutput for &mut ArgBuffer { type NestedBuffer = Vec; diff --git a/framework/base/src/types/heap/async_call_result.rs b/framework/base/src/types/heap/async_call_result.rs index 4084c83bc7..ab738cba71 100644 --- a/framework/base/src/types/heap/async_call_result.rs +++ b/framework/base/src/types/heap/async_call_result.rs @@ -1,5 +1,5 @@ use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, codec::{ DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, TopEncodeMulti, TopEncodeMultiOutput, @@ -82,7 +82,11 @@ where } } +impl TypeAbiFrom for AsyncCallResult {} + impl TypeAbi for AsyncCallResult { + type Unmanaged = Self; + fn type_name() -> TypeName { let mut repr = TypeName::from("AsyncCallResult<"); repr.push_str(T::type_name().as_str()); diff --git a/framework/base/src/types/heap/boxed_bytes.rs b/framework/base/src/types/heap/boxed_bytes.rs index 24c08d1199..336b0874a8 100644 --- a/framework/base/src/types/heap/boxed_bytes.rs +++ b/framework/base/src/types/heap/boxed_bytes.rs @@ -1,13 +1,15 @@ -use crate::{ - abi::{TypeAbi, TypeName}, - codec::*, -}; use alloc::{ - alloc::{alloc, alloc_zeroed, realloc, Layout}, + alloc::{alloc, realloc, Layout}, boxed::Box, + vec, vec::Vec, }; +use crate::{ + abi::{TypeAbi, TypeAbiFrom, TypeName}, + codec::*, +}; + /// Simple wrapper around a boxed byte slice, /// but with a lot of optimized methods for manipulating it. /// The focus is on reducing code size rather improving speed. @@ -20,23 +22,7 @@ impl BoxedBytes { } pub fn zeros(len: usize) -> Self { - unsafe { - let layout = Layout::from_size_align(len, core::mem::align_of::()).unwrap(); - let bytes_ptr = alloc_zeroed(layout); - let bytes_box = Box::from_raw(core::slice::from_raw_parts_mut(bytes_ptr, len)); - BoxedBytes(bytes_box) - } - } - - /// Allocates an uninitialized BoxedBytes to heap. - /// - /// # Safety - /// - /// Should only be called if the contents are initialized immediately afterwards, e.g. via a FFI call. - pub unsafe fn allocate(len: usize) -> Self { - let layout = Layout::from_size_align(len, core::mem::align_of::()).unwrap(); - let bytes_ptr = alloc(layout); - let bytes_box = Box::from_raw(core::slice::from_raw_parts_mut(bytes_ptr, len)); + let bytes_box = Box::from(vec![0u8; len]); BoxedBytes(bytes_box) } @@ -222,11 +208,9 @@ impl NestedDecode for BoxedBytes { H: DecodeErrorHandler, { let size = usize::dep_decode_or_handle_err(input, h)?; - unsafe { - let mut result = BoxedBytes::allocate(size); - input.read_into(result.as_mut_slice(), h)?; - Ok(result) - } + let mut result = BoxedBytes::zeros(size); + input.read_into(result.as_mut_slice(), h)?; + Ok(result) } } @@ -240,10 +224,18 @@ impl TopDecode for BoxedBytes { } } +impl TypeAbiFrom for BoxedBytes {} + impl TypeAbi for BoxedBytes { + type Unmanaged = Self; + fn type_name() -> TypeName { "bytes".into() } + + fn type_name_rust() -> TypeName { + "BoxedBytes".into() + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/framework/base/src/types/heap/h256.rs b/framework/base/src/types/heap/h256.rs index 5dd0a2786b..f440765d00 100644 --- a/framework/base/src/types/heap/h256.rs +++ b/framework/base/src/types/heap/h256.rs @@ -1,5 +1,5 @@ use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, types::heap::BoxedBytes, }; use alloc::{boxed::Box, vec::Vec}; @@ -224,10 +224,18 @@ impl TopDecode for H256 { } } +impl TypeAbiFrom for H256 {} + impl TypeAbi for H256 { + type Unmanaged = Self; + fn type_name() -> TypeName { "H256".into() } + + fn type_name_rust() -> TypeName { + "H256".into() + } } #[cfg(test)] diff --git a/framework/base/src/types/heap/h256_address.rs b/framework/base/src/types/heap/h256_address.rs index e4c9b055d2..a9fa69c2e7 100644 --- a/framework/base/src/types/heap/h256_address.rs +++ b/framework/base/src/types/heap/h256_address.rs @@ -1,6 +1,6 @@ use super::h256::H256; use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, types::heap::BoxedBytes, }; use alloc::{boxed::Box, vec::Vec}; @@ -202,10 +202,18 @@ impl TopDecode for Address { } } +impl TypeAbiFrom for Address {} + impl TypeAbi for Address { + type Unmanaged = Self; + fn type_name() -> TypeName { "Address".into() } + + fn type_name_rust() -> TypeName { + "Address".into() + } } #[cfg(test)] diff --git a/framework/base/src/types/heap/queue.rs b/framework/base/src/types/heap/queue.rs index 1c32848acf..cbb0b03d58 100644 --- a/framework/base/src/types/heap/queue.rs +++ b/framework/base/src/types/heap/queue.rs @@ -1,5 +1,5 @@ use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, codec::*, }; use alloc::vec::Vec; @@ -136,7 +136,11 @@ impl TopDecode for Queue { } } +impl TypeAbiFrom for Queue {} + impl TypeAbi for Queue { + type Unmanaged = Self; + fn type_name() -> TypeName { let mut repr = TypeName::from("Queue<"); repr.push_str(T::type_name().as_str()); diff --git a/framework/base/src/types/interaction.rs b/framework/base/src/types/interaction.rs new file mode 100644 index 0000000000..710b482b8c --- /dev/null +++ b/framework/base/src/types/interaction.rs @@ -0,0 +1,46 @@ +mod annotated; +mod back_transfers; +mod callback_closure; +mod callback_selector_result; +mod contract_call_legacy; +mod expr; +mod managed_arg_buffer; +mod markers; +mod result_handlers; +pub mod system_proxy; +mod tx; +mod tx_data; +mod tx_env; +mod tx_exec; +mod tx_from; +mod tx_gas; +mod tx_payment; +mod tx_proxy; +mod tx_result_handler; +mod tx_result_handler_list; +mod tx_to; + +pub use annotated::*; +pub use back_transfers::BackTransfers; +pub use callback_closure::{ + new_callback_call, CallbackClosure, CallbackClosureForDeser, CallbackClosureMatcher, +}; +pub use callback_selector_result::CallbackSelectorResult; +pub use contract_call_legacy::*; +pub use expr::*; +pub use managed_arg_buffer::ManagedArgBuffer; +pub use markers::*; +pub use result_handlers::*; +pub use tx::*; +pub use tx_data::*; +pub use tx_env::*; +pub use tx_exec::*; +pub use tx_from::*; +pub use tx_gas::*; +pub use tx_payment::*; +pub use tx_proxy::*; +pub use tx_result_handler::{TxEmptyResultHandler, TxResultHandler}; +pub use tx_result_handler_list::*; +pub use tx_to::*; + +pub type TxScBase = TxBaseWithEnv>; diff --git a/framework/base/src/types/interaction/annotated.rs b/framework/base/src/types/interaction/annotated.rs new file mode 100644 index 0000000000..315994e66e --- /dev/null +++ b/framework/base/src/types/interaction/annotated.rs @@ -0,0 +1,53 @@ +mod annotated_impl_big_uint; +mod annotated_impl_managed_address; +mod annotated_impl_managed_buffer; +mod annotated_impl_token_identifier; +mod annotated_impl_u64; + +use crate::{ + api::ManagedTypeApi, + formatter::FormatBuffer, + types::{ManagedBuffer, ManagedBufferCachedBuilder}, +}; + +use super::TxEnv; + +/// Describes a value can also have a custom representation in a mandos scenario. +/// +/// It is based on managed types in order to be embedded into parametric tests too. +pub trait AnnotatedValue: Sized +where + Env: TxEnv, +{ + fn annotation(&self, env: &Env) -> ManagedBuffer; + + /// Produces the value from a reference of the annotated type. Might involve a `.clone()` in some cases. + fn to_value(&self, env: &Env) -> T; + + /// Consumes annotated value to produce actual value. + /// + /// Override whenever it helps to avoid an unnecessary clone. + fn into_value(self, env: &Env) -> T { + self.to_value(env) + } + + /// Can be used when working with references only. + /// + /// Override whenever it helps to avoid an unnecessary clone. + fn with_value_ref(&self, env: &Env, f: F) -> R + where + F: FnOnce(&T) -> R, + { + f(&self.to_value(env)) + } +} + +/// Useful for u64 display in several places. +pub(super) fn display_u64(n: u64) -> ManagedBuffer +where + Api: ManagedTypeApi, +{ + let mut result = ManagedBufferCachedBuilder::new_from_slice(&[]); + result.append_display(&n); + result.into_managed_buffer() +} diff --git a/framework/base/src/types/interaction/annotated/annotated_impl_big_uint.rs b/framework/base/src/types/interaction/annotated/annotated_impl_big_uint.rs new file mode 100644 index 0000000000..f05952ab75 --- /dev/null +++ b/framework/base/src/types/interaction/annotated/annotated_impl_big_uint.rs @@ -0,0 +1,132 @@ +use crate::types::{BigUint, ManagedBuffer, ManagedRef, NotPayable}; + +use super::{AnnotatedValue, TxEnv}; + +impl AnnotatedValue> for BigUint +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.to_display() + } + + fn to_value(&self, _env: &Env) -> BigUint { + self.clone() + } + + fn into_value(self, _env: &Env) -> BigUint { + self + } + + #[inline] + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&BigUint) -> R, + { + f(self) + } +} + +impl AnnotatedValue> for &BigUint +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.to_display() + } + + fn to_value(&self, _env: &Env) -> BigUint { + (*self).clone() + } + + #[inline] + fn into_value(self, _env: &Env) -> BigUint { + self.clone() + } + + #[inline] + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&BigUint) -> R, + { + f(self) + } +} + +impl<'a, Env> AnnotatedValue> for ManagedRef<'a, Env::Api, BigUint> +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.to_display() + } + + #[inline] + fn to_value(&self, _env: &Env) -> BigUint { + (*self).clone_value() + } + + fn into_value(self, _env: &Env) -> BigUint { + self.clone_value() + } + + #[inline] + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&BigUint) -> R, + { + f(self) + } +} + +impl AnnotatedValue> for u64 +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + BigUint::from(*self).to_display() + } + + fn to_value(&self, _env: &Env) -> BigUint { + BigUint::from(*self) + } +} + +impl AnnotatedValue> for i32 +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + BigUint::from(*self as u64).to_display() + } + + fn to_value(&self, _env: &Env) -> BigUint { + BigUint::from(*self as u64) + } +} + +impl AnnotatedValue> for () +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + ManagedBuffer::from("0") + } + + fn to_value(&self, _env: &Env) -> BigUint { + BigUint::zero() + } +} + +impl AnnotatedValue> for NotPayable +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + ManagedBuffer::from("0") + } + + fn to_value(&self, _env: &Env) -> BigUint { + BigUint::zero() + } +} diff --git a/framework/base/src/types/interaction/annotated/annotated_impl_managed_address.rs b/framework/base/src/types/interaction/annotated/annotated_impl_managed_address.rs new file mode 100644 index 0000000000..403ccf4603 --- /dev/null +++ b/framework/base/src/types/interaction/annotated/annotated_impl_managed_address.rs @@ -0,0 +1,77 @@ +use crate::types::{heap::Address, ManagedAddress, ManagedBuffer}; + +use super::{AnnotatedValue, TxEnv}; + +impl AnnotatedValue> for ManagedAddress +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.hex_expr() + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + self.clone() + } + + fn into_value(self, _env: &Env) -> ManagedAddress { + self + } + + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&ManagedAddress) -> R, + { + f(self) + } +} + +impl AnnotatedValue> for &ManagedAddress +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.hex_expr() + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + (*self).clone() + } + + fn into_value(self, _env: &Env) -> ManagedAddress { + self.clone() + } + + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&ManagedAddress) -> R, + { + f(self) + } +} + +impl AnnotatedValue> for Address +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + ManagedAddress::from(self).hex_expr() + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + ManagedAddress::from(self) + } +} + +impl AnnotatedValue> for &Address +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + ManagedAddress::from(*self).hex_expr() + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + ManagedAddress::from(*self) + } +} diff --git a/framework/base/src/types/interaction/annotated/annotated_impl_managed_buffer.rs b/framework/base/src/types/interaction/annotated/annotated_impl_managed_buffer.rs new file mode 100644 index 0000000000..eecaad75b5 --- /dev/null +++ b/framework/base/src/types/interaction/annotated/annotated_impl_managed_buffer.rs @@ -0,0 +1,43 @@ +use crate::types::ManagedBuffer; + +use super::{AnnotatedValue, TxEnv}; + +impl AnnotatedValue> for ManagedBuffer +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.hex_expr() + } + + #[inline] + fn to_value(&self, _env: &Env) -> ManagedBuffer { + self.clone() + } + + #[inline] + fn into_value(self, _env: &Env) -> ManagedBuffer { + self + } + + #[inline] + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&ManagedBuffer) -> R, + { + f(self) + } +} + +impl AnnotatedValue> for () +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + ManagedBuffer::new() + } + + fn to_value(&self, _env: &Env) -> ManagedBuffer { + ManagedBuffer::new() + } +} diff --git a/framework/base/src/types/interaction/annotated/annotated_impl_token_identifier.rs b/framework/base/src/types/interaction/annotated/annotated_impl_token_identifier.rs new file mode 100644 index 0000000000..c689024632 --- /dev/null +++ b/framework/base/src/types/interaction/annotated/annotated_impl_token_identifier.rs @@ -0,0 +1,56 @@ +use crate::{ + proxy_imports::ManagedBufferBuilder, + types::{ManagedBuffer, TokenIdentifier}, +}; + +use super::{AnnotatedValue, TxEnv}; + +impl AnnotatedValue> for TokenIdentifier +where + Env: TxEnv, +{ + fn annotation(&self, env: &Env) -> ManagedBuffer { + (&self).annotation(env) + } + + fn to_value(&self, _env: &Env) -> TokenIdentifier { + self.clone() + } + + fn into_value(self, _env: &Env) -> TokenIdentifier { + self + } + + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&TokenIdentifier) -> R, + { + f(self) + } +} + +impl AnnotatedValue> for &TokenIdentifier +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + let mut annot = ManagedBufferBuilder::::new_from_slice("str:".as_bytes()); + annot.append_managed_buffer(self.as_managed_buffer()); + annot.into_managed_buffer() + } + + fn to_value(&self, _env: &Env) -> TokenIdentifier { + (*self).clone() + } + + fn into_value(self, _env: &Env) -> TokenIdentifier { + (*self).clone() + } + + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&TokenIdentifier) -> R, + { + f(self) + } +} diff --git a/framework/base/src/types/interaction/annotated/annotated_impl_u64.rs b/framework/base/src/types/interaction/annotated/annotated_impl_u64.rs new file mode 100644 index 0000000000..ed310d1f43 --- /dev/null +++ b/framework/base/src/types/interaction/annotated/annotated_impl_u64.rs @@ -0,0 +1,29 @@ +use crate::types::ManagedBuffer; + +use super::{display_u64, AnnotatedValue, TxEnv}; + +impl AnnotatedValue for u64 +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + display_u64(*self) + } + + fn to_value(&self, _env: &Env) -> u64 { + *self + } +} + +impl AnnotatedValue for i32 +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + display_u64(*self as u64) + } + + fn to_value(&self, _env: &Env) -> u64 { + *self as u64 + } +} diff --git a/framework/base/src/types/interaction/async_call.rs b/framework/base/src/types/interaction/async_call.rs deleted file mode 100644 index 9c5554baba..0000000000 --- a/framework/base/src/types/interaction/async_call.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::{ - api::{CallTypeApi, StorageWriteApi}, - contract_base::SendRawWrapper, - types::{BigUint, CallbackClosure, ManagedAddress}, -}; - -use super::FunctionCall; - -#[must_use] -pub struct AsyncCall -where - SA: CallTypeApi + 'static, -{ - pub(crate) to: ManagedAddress, - pub(crate) egld_payment: BigUint, - pub(crate) function_call: FunctionCall, - pub(crate) callback_call: Option>, -} - -#[allow(clippy::return_self_not_must_use)] -impl AsyncCall -where - SA: CallTypeApi, -{ - pub fn with_callback(self, callback_call: CallbackClosure) -> Self { - AsyncCall { - callback_call: Some(callback_call), - ..self - } - } -} - -impl AsyncCall -where - SA: CallTypeApi, -{ - pub fn call_and_exit_ignore_callback(&self) -> ! { - SendRawWrapper::::new().async_call_raw( - &self.to, - &self.egld_payment, - &self.function_call.function_name, - &self.function_call.arg_buffer, - ) - } -} - -impl AsyncCall -where - SA: CallTypeApi + StorageWriteApi, -{ - pub fn call_and_exit(&self) -> ! { - // first, save the callback closure - if let Some(callback_call) = &self.callback_call { - callback_call.save_to_storage::(); - } - - // last, send the async call, which will kill the execution - self.call_and_exit_ignore_callback() - } -} diff --git a/framework/base/src/types/interaction/callback_closure.rs b/framework/base/src/types/interaction/callback_closure.rs index 98b6fece64..6b2b73feee 100644 --- a/framework/base/src/types/interaction/callback_closure.rs +++ b/framework/base/src/types/interaction/callback_closure.rs @@ -1,3 +1,5 @@ +use unwrap_infallible::UnwrapInfallible; + use crate::{ api::{BlockchainApi, ErrorApi, ManagedTypeApi, StorageReadApi, StorageWriteApi}, codec::{ @@ -28,11 +30,22 @@ pub const CALLBACK_CLOSURE_STORAGE_BASE_KEY: &[u8] = b"CB_CLOSURE"; /// /// In both cases the framework hides all the magic, the developer shouldn't worry about it. #[derive(TopEncode)] -pub struct CallbackClosure { +pub struct CallbackClosure +where + M: ManagedTypeApi + ErrorApi, +{ pub(super) callback_name: &'static str, pub(super) closure_args: ManagedArgBuffer, } +pub struct CallbackClosureWithGas +where + M: ManagedTypeApi + ErrorApi, +{ + pub(super) closure: CallbackClosure, + pub(super) gas_for_callback: u64, +} + /// Syntactical sugar to help macros to generate code easier. /// Unlike calling `CallbackClosure::::new`, here types can be inferred from the context. pub fn new_callback_call(callback_name: &'static str) -> CallbackClosure @@ -52,7 +65,9 @@ impl CallbackClosure { pub fn push_endpoint_arg(&mut self, endpoint_arg: &T) { let h = ExitCodecErrorHandler::::from(err_msg::CONTRACT_CALL_ENCODE_ERROR); - let Ok(()) = endpoint_arg.multi_encode_or_handle_err(&mut self.closure_args, h); + endpoint_arg + .multi_encode_or_handle_err(&mut self.closure_args, h) + .unwrap_infallible() } pub fn save_to_storage(&self) { diff --git a/framework/base/src/types/interaction/mod.rs b/framework/base/src/types/interaction/contract_call_legacy.rs similarity index 63% rename from framework/base/src/types/interaction/mod.rs rename to framework/base/src/types/interaction/contract_call_legacy.rs index 3de007ee79..8532f6de09 100644 --- a/framework/base/src/types/interaction/mod.rs +++ b/framework/base/src/types/interaction/contract_call_legacy.rs @@ -1,8 +1,5 @@ mod async_call; mod async_call_promises; -mod back_transfers; -mod callback_closure; -mod callback_selector_result; mod contract_call_convert; mod contract_call_exec; mod contract_call_no_payment; @@ -12,22 +9,20 @@ mod contract_call_with_egld; mod contract_call_with_egld_or_single_esdt; mod contract_call_with_multi_esdt; mod contract_deploy; -mod function_call; -mod managed_arg_buffer; +mod typed_function_call; pub use async_call::AsyncCall; pub use async_call_promises::AsyncCallPromises; -pub use back_transfers::BackTransfers; -pub use callback_closure::{ - new_callback_call, CallbackClosure, CallbackClosureForDeser, CallbackClosureMatcher, -}; -pub use callback_selector_result::CallbackSelectorResult; pub use contract_call_no_payment::ContractCallNoPayment; -pub use contract_call_trait::ContractCall; +pub use contract_call_trait::{ContractCall, ContractCallBase}; pub use contract_call_with_any_payment::ContractCallWithAnyPayment; pub use contract_call_with_egld::ContractCallWithEgld; pub use contract_call_with_egld_or_single_esdt::ContractCallWithEgldOrSingleEsdt; pub use contract_call_with_multi_esdt::ContractCallWithMultiEsdt; pub use contract_deploy::{new_contract_deploy, ContractDeploy}; -pub use function_call::FunctionCall; -pub use managed_arg_buffer::ManagedArgBuffer; +pub use typed_function_call::TypedFunctionCall; + +/// Using max u64 to represent maximum possible gas, +/// so that the value zero is not reserved and can be specified explicitly. +/// Leaving the gas limit unspecified will replace it with `api.get_gas_left()`. +pub(crate) const UNSPECIFIED_GAS_LIMIT: u64 = u64::MAX; diff --git a/framework/base/src/types/interaction/contract_call_legacy/async_call.rs b/framework/base/src/types/interaction/contract_call_legacy/async_call.rs new file mode 100644 index 0000000000..05faf11c2d --- /dev/null +++ b/framework/base/src/types/interaction/contract_call_legacy/async_call.rs @@ -0,0 +1,39 @@ +use crate::{ + api::{CallTypeApi, StorageWriteApi}, + types::{CallbackClosure, EgldPayment, FunctionCall, ManagedAddress, Tx, TxScEnv}, +}; + +/// Kept as alias for backwards compatibility. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] +pub type AsyncCall = Tx< + TxScEnv, + (), + ManagedAddress, + EgldPayment, + (), + FunctionCall, + Option>, +>; + +#[allow(clippy::return_self_not_must_use)] +impl AsyncCall +where + Api: CallTypeApi, +{ + pub fn with_callback(mut self, callback_call: CallbackClosure) -> Self { + self.result_handler = Some(callback_call); + self + } +} + +impl AsyncCall +where + Api: CallTypeApi + StorageWriteApi, +{ + pub fn call_and_exit_ignore_callback(self) -> ! { + self.async_call_and_exit() + } +} diff --git a/framework/base/src/types/interaction/async_call_promises.rs b/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs similarity index 91% rename from framework/base/src/types/interaction/async_call_promises.rs rename to framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs index ea03c0e777..ee3726c0eb 100644 --- a/framework/base/src/types/interaction/async_call_promises.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs @@ -1,12 +1,14 @@ use crate::{ api::CallTypeApi, contract_base::SendRawWrapper, - types::{BigUint, CallbackClosure, ManagedAddress, ManagedBuffer}, + types::{BigUint, CallbackClosure, FunctionCall, ManagedAddress, ManagedBuffer}, }; -use super::FunctionCall; - /// Will be renamed to `AsyncCall` and `AsyncCall` to `AsyncCallLegacy` when the promises end up on the mainnet. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] #[must_use] pub struct AsyncCallPromises where diff --git a/framework/base/src/types/interaction/contract_call_convert.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs similarity index 97% rename from framework/base/src/types/interaction/contract_call_convert.rs rename to framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs index c7e4301c2c..fe4225d9a4 100644 --- a/framework/base/src/types/interaction/contract_call_convert.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_convert.rs @@ -38,7 +38,7 @@ where function_call: self .basic .function_call - .convert_to_single_transfer_fungible_call(payment), + .convert_to_single_transfer_fungible_call(payment.as_refs()), explicit_gas_limit: self.basic.explicit_gas_limit, _return_type: PhantomData, }, @@ -55,7 +55,7 @@ where function_call: self .basic .function_call - .convert_to_single_transfer_nft_call(&self.basic.to, payment), + .convert_to_single_transfer_nft_call(&self.basic.to, payment.as_refs()), explicit_gas_limit: self.basic.explicit_gas_limit, _return_type: PhantomData, }, @@ -78,7 +78,7 @@ where function_call: self .basic .function_call - .convert_to_multi_transfer_esdt_call(&self.basic.to, payments), + .convert_to_multi_transfer_esdt_call(&self.basic.to, &payments), explicit_gas_limit: self.basic.explicit_gas_limit, _return_type: PhantomData, }, diff --git a/framework/base/src/types/interaction/contract_call_exec.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs similarity index 79% rename from framework/base/src/types/interaction/contract_call_exec.rs rename to framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs index 260897e1a6..427218f1c8 100644 --- a/framework/base/src/types/interaction/contract_call_exec.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs @@ -1,30 +1,17 @@ use crate::{ - api::{use_raw_handle, StaticVarApiImpl}, + api::{use_raw_handle, BlockchainApiImpl, CallTypeApi, StaticVarApiImpl, StorageWriteApi}, codec::TopDecodeMulti, -}; - -use crate::{ - api::{BlockchainApiImpl, CallTypeApi}, contract_base::SendRawWrapper, formatter::SCLowerHex, - io::{ArgErrorHandler, ArgId, ManagedResultArgLoader}, types::{ - BigUint, EsdtTokenPayment, ManagedBuffer, ManagedBufferCachedBuilder, ManagedType, - ManagedVec, + decode_result, AsyncCall, AsyncCallPromises, BigUint, EsdtTokenPayment, ManagedBuffer, + ManagedBufferBuilder, ManagedType, ManagedVec, Tx, TRANSFER_EXECUTE_DEFAULT_LEFTOVER, }, }; -use super::{AsyncCall, ContractCallNoPayment, ContractCallWithEgld}; +use super::{ContractCallNoPayment, ContractCallWithEgld, UNSPECIFIED_GAS_LIMIT}; use crate::api::managed_types::handles::HandleConstraints; -/// Using max u64 to represent maximum possible gas, -/// so that the value zero is not reserved and can be specified explicitly. -/// Leaving the gas limit unspecified will replace it with `api.get_gas_left()`. -pub(super) const UNSPECIFIED_GAS_LIMIT: u64 = u64::MAX; - -/// In case of `transfer_execute`, we leave by default a little gas for the calling transaction to finish. -pub(super) const TRANSFER_EXECUTE_DEFAULT_LEFTOVER: u64 = 100_000; - impl ContractCallWithEgld where SA: CallTypeApi + 'static, @@ -56,7 +43,7 @@ where } pub fn to_call_data_string(&self) -> ManagedBuffer { - let mut result = ManagedBufferCachedBuilder::default(); + let mut result = ManagedBufferBuilder::default(); result.append_managed_buffer(&self.basic.function_call.function_name); for arg in self.basic.function_call.arg_buffer.raw_arg_iter() { result.append_bytes(b"@"); @@ -64,18 +51,27 @@ where } result.into_managed_buffer() } +} - pub(super) fn async_call(self) -> AsyncCall { - AsyncCall { - to: self.basic.to, - egld_payment: self.egld_payment, - function_call: self.basic.function_call, - callback_call: None, - } +impl ContractCallWithEgld +where + SA: CallTypeApi + StorageWriteApi + 'static, +{ + pub(super) fn build_async_call(self) -> AsyncCall { + Tx::new_tx_from_sc() + .to(self.basic.to) + .egld(self.egld_payment) + .raw_data(self.basic.function_call) + .callback(None) } +} - pub(super) fn async_call_promise(self) -> super::AsyncCallPromises { - super::AsyncCallPromises { +impl ContractCallWithEgld +where + SA: CallTypeApi + 'static, +{ + pub(super) fn build_async_call_promise(self) -> AsyncCallPromises { + AsyncCallPromises { to: self.basic.to, egld_payment: self.egld_payment, function_call: self.basic.function_call, @@ -215,17 +211,3 @@ where } } } - -fn decode_result( - raw_result: ManagedVec>, -) -> RequestedResult -where - SA: CallTypeApi + 'static, - RequestedResult: TopDecodeMulti, -{ - let mut loader = ManagedResultArgLoader::new(raw_result); - let arg_id = ArgId::from(&b"sync result"[..]); - let h: ArgErrorHandler = ArgErrorHandler::::from(arg_id); - let Ok(result) = RequestedResult::multi_decode_or_handle_err(&mut loader, h); - result -} diff --git a/framework/base/src/types/interaction/contract_call_no_payment.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_no_payment.rs similarity index 86% rename from framework/base/src/types/interaction/contract_call_no_payment.rs rename to framework/base/src/types/interaction/contract_call_legacy/contract_call_no_payment.rs index 7198f71cd1..2a067c761b 100644 --- a/framework/base/src/types/interaction/contract_call_no_payment.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_no_payment.rs @@ -6,14 +6,15 @@ use crate::{ api::CallTypeApi, types::{ BigUint, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, - EsdtTokenPayment, ManagedAddress, ManagedBuffer, ManagedVec, TokenIdentifier, + EsdtTokenPayment, FunctionCall, ManagedAddress, ManagedArgBuffer, ManagedBuffer, + ManagedVec, TokenIdentifier, Tx, TxScEnv, }, }; use super::{ - contract_call_exec::UNSPECIFIED_GAS_LIMIT, contract_call_with_egld::ContractCallWithEgld, + contract_call_trait::ContractCallBase, contract_call_with_egld::ContractCallWithEgld, contract_call_with_multi_esdt::ContractCallWithMultiEsdt, ContractCall, - ContractCallWithAnyPayment, ContractCallWithEgldOrSingleEsdt, FunctionCall, ManagedArgBuffer, + ContractCallWithAnyPayment, ContractCallWithEgldOrSingleEsdt, UNSPECIFIED_GAS_LIMIT, }; /// Holds metadata for calling another contract, without payments. @@ -22,19 +23,23 @@ use super::{ /// (unless there are payment arguments in the endpoint - but these are mostly obsolete now). /// /// It is also the basis for all other contract call types, all of them contain this one. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] #[must_use] pub struct ContractCallNoPayment where SA: CallTypeApi + 'static, { - pub(super) _phantom: PhantomData, + pub(crate) _phantom: PhantomData, pub to: ManagedAddress, pub function_call: FunctionCall, pub explicit_gas_limit: u64, - pub(super) _return_type: PhantomData, + pub(crate) _return_type: PhantomData, } -impl ContractCall for ContractCallNoPayment +impl ContractCallBase for ContractCallNoPayment where SA: CallTypeApi + 'static, OriginalResult: TopEncodeMulti, @@ -48,7 +53,13 @@ where egld_payment: BigUint::zero(), } } +} +impl ContractCall for ContractCallNoPayment +where + SA: CallTypeApi + 'static, + OriginalResult: TopEncodeMulti, +{ #[inline] fn get_mut_basic(&mut self) -> &mut ContractCallNoPayment { self @@ -166,4 +177,8 @@ where pub fn into_function_call(self) -> FunctionCall { self.function_call } + + pub fn tx(self) -> Tx, (), (), (), (), FunctionCall, ()> { + Tx::new_tx_from_sc().raw_data(self.function_call) + } } diff --git a/framework/base/src/types/interaction/contract_call_trait.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_trait.rs similarity index 88% rename from framework/base/src/types/interaction/contract_call_trait.rs rename to framework/base/src/types/interaction/contract_call_legacy/contract_call_trait.rs index 073dae603d..70c5faaac3 100644 --- a/framework/base/src/types/interaction/contract_call_trait.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_trait.rs @@ -1,15 +1,17 @@ use crate::{ api::CallTypeApi, codec::{multi_types::IgnoreValue, TopDecodeMulti, TopEncodeMulti}, - types::ManagedBuffer, + types::{AsyncCall, AsyncCallPromises, BackTransfers, ManagedArgBuffer, ManagedBuffer}, }; -use super::{AsyncCall, ContractCallNoPayment, ContractCallWithEgld, ManagedArgBuffer}; +use super::{ContractCallNoPayment, ContractCallWithEgld}; -/// Defines a contract call object, which is the basis for all calls to other contracts. -/// -/// Its implementations differ on the type of payment that gets sent with the call. -pub trait ContractCall: Sized +/// Converts into a legacy contract call. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] +pub trait ContractCallBase where SA: CallTypeApi + 'static, { @@ -19,7 +21,15 @@ where /// thus reducing it to a simple transaction with optional EGLD value. #[doc(hidden)] fn into_normalized(self) -> ContractCallWithEgld; +} +/// Defines a contract call object, which is the basis for all calls to other contracts. +/// +/// Its implementations differ on the type of payment that gets sent with the call. +pub trait ContractCall: ContractCallBase + Sized +where + SA: CallTypeApi + 'static, +{ /// Mutable access to the common base. #[doc(hidden)] fn get_mut_basic(&mut self) -> &mut ContractCallNoPayment; @@ -75,13 +85,13 @@ where /// Converts to a legacy async call. #[inline] fn async_call(self) -> AsyncCall { - self.into_normalized().async_call() + self.into_normalized().build_async_call() } /// Converts to an async promise. #[inline] - fn async_call_promise(self) -> super::AsyncCallPromises { - self.into_normalized().async_call_promise() + fn async_call_promise(self) -> AsyncCallPromises { + self.into_normalized().build_async_call_promise() } /// Executes immediately, synchronously, and returns contract call result. @@ -99,7 +109,7 @@ where #[inline] fn execute_on_dest_context_with_back_transfers( self, - ) -> (RequestedResult, super::BackTransfers) + ) -> (RequestedResult, BackTransfers) where RequestedResult: TopDecodeMulti, { diff --git a/framework/base/src/types/interaction/contract_call_with_any_payment.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_with_any_payment.rs similarity index 83% rename from framework/base/src/types/interaction/contract_call_with_any_payment.rs rename to framework/base/src/types/interaction/contract_call_legacy/contract_call_with_any_payment.rs index 07f468a671..2a8a4262f0 100644 --- a/framework/base/src/types/interaction/contract_call_with_any_payment.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_with_any_payment.rs @@ -5,11 +5,18 @@ use crate::{ types::{EgldOrMultiEsdtPayment, ManagedAddress, ManagedBuffer}, }; -use super::{contract_call_no_payment::ContractCallNoPayment, ContractCall, ContractCallWithEgld}; +use super::{ + contract_call_no_payment::ContractCallNoPayment, contract_call_trait::ContractCallBase, + ContractCall, ContractCallWithEgld, +}; /// Holds data for calling another contract, with any type of payment: none, EGLD, Multi-ESDT. /// /// Gets created when chaining method `with_any_payment`. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] #[must_use] pub struct ContractCallWithAnyPayment where @@ -19,7 +26,7 @@ where pub payment: EgldOrMultiEsdtPayment, } -impl ContractCall for ContractCallWithAnyPayment +impl ContractCallBase for ContractCallWithAnyPayment where SA: CallTypeApi + 'static, OriginalResult: TopEncodeMulti, @@ -35,7 +42,13 @@ where .convert_to_esdt_transfer_call(multi_esdt_payment), } } +} +impl ContractCall for ContractCallWithAnyPayment +where + SA: CallTypeApi + 'static, + OriginalResult: TopEncodeMulti, +{ #[inline] fn get_mut_basic(&mut self) -> &mut ContractCallNoPayment { &mut self.basic diff --git a/framework/base/src/types/interaction/contract_call_with_egld.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_with_egld.rs similarity index 83% rename from framework/base/src/types/interaction/contract_call_with_egld.rs rename to framework/base/src/types/interaction/contract_call_legacy/contract_call_with_egld.rs index 9d856cf7b5..47d1fa0c11 100644 --- a/framework/base/src/types/interaction/contract_call_with_egld.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_with_egld.rs @@ -5,7 +5,10 @@ use crate::{ types::{BigUint, ManagedAddress, ManagedBuffer}, }; -use super::{contract_call_no_payment::ContractCallNoPayment, ContractCall}; +use super::{ + contract_call_no_payment::ContractCallNoPayment, contract_call_trait::ContractCallBase, + ContractCall, +}; /// Holds data for calling another contract, with EGLD payment only. /// @@ -15,6 +18,10 @@ use super::{contract_call_no_payment::ContractCallNoPayment, ContractCall}; /// /// It also represents the normalized form of any contract call, since ESDT transfers /// (the only payment not available here) get converted to builtin function calls in normalized form. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] #[must_use] pub struct ContractCallWithEgld where @@ -24,7 +31,7 @@ where pub egld_payment: BigUint, } -impl ContractCall for ContractCallWithEgld +impl ContractCallBase for ContractCallWithEgld where SA: CallTypeApi + 'static, OriginalResult: TopEncodeMulti, @@ -36,7 +43,13 @@ where // no ESDT, no conversion needed self } +} +impl ContractCall for ContractCallWithEgld +where + SA: CallTypeApi + 'static, + OriginalResult: TopEncodeMulti, +{ #[inline] fn get_mut_basic(&mut self) -> &mut ContractCallNoPayment { &mut self.basic diff --git a/framework/base/src/types/interaction/contract_call_with_egld_or_single_esdt.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_with_egld_or_single_esdt.rs similarity index 87% rename from framework/base/src/types/interaction/contract_call_with_egld_or_single_esdt.rs rename to framework/base/src/types/interaction/contract_call_legacy/contract_call_with_egld_or_single_esdt.rs index 66d0b27a41..a6d9a76845 100644 --- a/framework/base/src/types/interaction/contract_call_with_egld_or_single_esdt.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_with_egld_or_single_esdt.rs @@ -7,11 +7,18 @@ use crate::{ }, }; -use super::{contract_call_no_payment::ContractCallNoPayment, ContractCall, ContractCallWithEgld}; +use super::{ + contract_call_no_payment::ContractCallNoPayment, contract_call_trait::ContractCallBase, + ContractCall, ContractCallWithEgld, +}; /// Holds data for calling another contract, with a single payment, either EGLD or a single ESDT token. /// /// Gets created when chaining method `with_egld_or_single_esdt_transfer`. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] #[must_use] pub struct ContractCallWithEgldOrSingleEsdt where @@ -40,7 +47,8 @@ where } } -impl ContractCall for ContractCallWithEgldOrSingleEsdt +impl ContractCallBase + for ContractCallWithEgldOrSingleEsdt where SA: CallTypeApi + 'static, OriginalResult: TopEncodeMulti, @@ -56,7 +64,13 @@ where self.into_normalized_esdt() } } +} +impl ContractCall for ContractCallWithEgldOrSingleEsdt +where + SA: CallTypeApi + 'static, + OriginalResult: TopEncodeMulti, +{ #[inline] fn get_mut_basic(&mut self) -> &mut ContractCallNoPayment { &mut self.basic diff --git a/framework/base/src/types/interaction/contract_call_with_multi_esdt.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_with_multi_esdt.rs similarity index 85% rename from framework/base/src/types/interaction/contract_call_with_multi_esdt.rs rename to framework/base/src/types/interaction/contract_call_legacy/contract_call_with_multi_esdt.rs index 240d4ac270..9064507dbf 100644 --- a/framework/base/src/types/interaction/contract_call_with_multi_esdt.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_with_multi_esdt.rs @@ -7,8 +7,15 @@ use crate::{ }, }; -use super::{contract_call_no_payment::ContractCallNoPayment, ContractCall, ContractCallWithEgld}; +use super::{ + contract_call_no_payment::ContractCallNoPayment, contract_call_trait::ContractCallBase, + ContractCall, ContractCallWithEgld, +}; +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] #[must_use] pub struct ContractCallWithMultiEsdt where @@ -18,7 +25,7 @@ where pub esdt_payments: ManagedVec>, } -impl ContractCall for ContractCallWithMultiEsdt +impl ContractCallBase for ContractCallWithMultiEsdt where SA: CallTypeApi + 'static, OriginalResult: TopEncodeMulti, @@ -30,7 +37,13 @@ where .into_normalized() .convert_to_esdt_transfer_call(self.esdt_payments) } +} +impl ContractCall for ContractCallWithMultiEsdt +where + SA: CallTypeApi + 'static, + OriginalResult: TopEncodeMulti, +{ #[inline] fn get_mut_basic(&mut self) -> &mut ContractCallNoPayment { &mut self.basic diff --git a/framework/base/src/types/interaction/contract_deploy.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs similarity index 84% rename from framework/base/src/types/interaction/contract_deploy.rs rename to framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs index 1c61b7c977..6b19010e3d 100644 --- a/framework/base/src/types/interaction/contract_deploy.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_deploy.rs @@ -1,33 +1,38 @@ use core::marker::PhantomData; -use crate::codec::{CodecFrom, TopEncodeMulti}; +use multiversx_sc_codec::TopDecodeMulti; +use unwrap_infallible::UnwrapInfallible; + +use crate::{abi::TypeAbiFrom, codec::TopEncodeMulti}; use crate::{ api::{BlockchainApiImpl, CallTypeApi}, contract_base::{ExitCodecErrorHandler, SendRawWrapper}, err_msg, io::{ArgErrorHandler, ArgId, ManagedResultArgLoader}, - types::{BigUint, CodeMetadata, ManagedAddress, ManagedBuffer, ManagedOption, ManagedVec}, + types::{ + BigUint, CodeMetadata, ManagedAddress, ManagedArgBuffer, ManagedBuffer, ManagedOption, + ManagedVec, + }, }; -use super::ManagedArgBuffer; - -/// Using max u64 to represent maximum possible gas, -/// so that the value zero is not reserved and can be specified explicitly. -/// Leaving the gas limit unspecified will replace it with `api.get_gas_left()`. -const UNSPECIFIED_GAS_LIMIT: u64 = u64::MAX; +use super::UNSPECIFIED_GAS_LIMIT; +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] #[must_use] pub struct ContractDeploy where SA: CallTypeApi + 'static, { - _phantom: PhantomData, + pub(crate) _phantom: PhantomData, pub to: ManagedOption>, // only used for Upgrade, ignored for Deploy pub egld_payment: BigUint, pub explicit_gas_limit: u64, pub arg_buffer: ManagedArgBuffer, - _return_type: PhantomData, + pub(crate) _return_type: PhantomData, } /// Syntactical sugar to help macros to generate code easier. @@ -82,7 +87,9 @@ where pub fn push_endpoint_arg(&mut self, endpoint_arg: &T) { let h = ExitCodecErrorHandler::::from(err_msg::CONTRACT_CALL_ENCODE_ERROR); - let Ok(()) = endpoint_arg.multi_encode_or_handle_err(&mut self.arg_buffer, h); + endpoint_arg + .multi_encode_or_handle_err(&mut self.arg_buffer, h) + .unwrap_infallible() } fn resolve_gas_limit(&self) -> u64 { @@ -103,13 +110,12 @@ where raw_result: ManagedVec>, ) -> RequestedResult where - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { let mut loader = ManagedResultArgLoader::new(raw_result); let arg_id = ArgId::from(&b"init result"[..]); let h = ArgErrorHandler::::from(arg_id); - let Ok(result) = RequestedResult::multi_decode_or_handle_err(&mut loader, h); - result + RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible() } /// Executes immediately, synchronously, and returns Some(Address) of the deployed contract. @@ -120,7 +126,7 @@ where code_metadata: CodeMetadata, ) -> (ManagedAddress, RequestedResult) where - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { let (address, raw_result) = SendRawWrapper::::new().deploy_contract( self.resolve_gas_limit(), @@ -141,7 +147,7 @@ where code_metadata: CodeMetadata, ) -> (ManagedAddress, RequestedResult) where - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { let (address, raw_result) = SendRawWrapper::::new().deploy_from_source_contract( self.resolve_gas_limit(), diff --git a/framework/base/src/types/interaction/contract_call_legacy/typed_function_call.rs b/framework/base/src/types/interaction/contract_call_legacy/typed_function_call.rs new file mode 100644 index 0000000000..8589a0dc28 --- /dev/null +++ b/framework/base/src/types/interaction/contract_call_legacy/typed_function_call.rs @@ -0,0 +1,28 @@ +use core::marker::PhantomData; + +use crate::{api::ManagedTypeApi, types::FunctionCall}; + +/// Old attempt at grouping FunctionCall + OriginalTypeMarker. +#[deprecated( + since = "0.49.0", + note = "Not clear if it still used anywhere, will delete soon." +)] +pub struct TypedFunctionCall +where + Api: ManagedTypeApi, +{ + pub function_call: FunctionCall, + _return_type: PhantomData, +} + +impl From> for TypedFunctionCall +where + Api: ManagedTypeApi, +{ + fn from(function_call: FunctionCall) -> Self { + TypedFunctionCall { + function_call, + _return_type: PhantomData, + } + } +} diff --git a/framework/base/src/types/interaction/expr.rs b/framework/base/src/types/interaction/expr.rs new file mode 100644 index 0000000000..9ecbd18112 --- /dev/null +++ b/framework/base/src/types/interaction/expr.rs @@ -0,0 +1,7 @@ +mod test_address; +mod test_sc_address; +mod test_token_identifier; + +pub use test_address::TestAddress; +pub use test_sc_address::TestSCAddress; +pub use test_token_identifier::TestTokenIdentifier; diff --git a/framework/base/src/types/interaction/expr/test_address.rs b/framework/base/src/types/interaction/expr/test_address.rs new file mode 100644 index 0000000000..88799c06d2 --- /dev/null +++ b/framework/base/src/types/interaction/expr/test_address.rs @@ -0,0 +1,113 @@ +use core::ptr; + +use multiversx_sc_codec::{EncodeErrorHandler, TopEncode, TopEncodeOutput}; + +use crate::{ + abi::TypeAbiFrom, + api::ManagedTypeApi, + types::{ + AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom, TxFromSpecified, TxTo, + TxToSpecified, + }, +}; + +const ADDRESS_PREFIX: &str = "address:"; + +/// Encodes a dummy address, to be used for tests. +/// +/// It is designed to be usable from contracts (especiall test contracts), with a minimal footprint. +/// For this reason, its inner structure is subject to change. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct TestAddress<'a> { + name: &'a str, +} + +impl<'a> TestAddress<'a> { + pub const fn new(name: &'a str) -> Self { + TestAddress { name } + } + + pub fn eval_to_array(&self) -> [u8; 32] { + let result = [b'_'; 32]; + let expr_bytes = self.name.as_bytes(); + let mut len = expr_bytes.len(); + if len > 32 { + len = 32; + } + unsafe { + ptr::copy_nonoverlapping(expr_bytes.as_ptr(), result.as_ptr() as *mut u8, len); + } + result + } + + #[cfg(feature = "alloc")] + pub fn eval_to_expr(&self) -> alloc::string::String { + alloc::format!("{ADDRESS_PREFIX}{}", self.name) + } +} + +impl<'a, Env> AnnotatedValue> for TestAddress<'a> +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + let mut result = ManagedBuffer::new_from_bytes(ADDRESS_PREFIX.as_bytes()); + result.append_bytes(self.name.as_bytes()); + result + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + let expr: [u8; 32] = self.eval_to_array(); + expr.into() + } +} + +impl<'a, Env> TxFrom for TestAddress<'a> +where + Env: TxEnv, +{ + fn resolve_address(&self, _env: &Env) -> ManagedAddress { + let expr: [u8; 32] = self.eval_to_array(); + expr.into() + } +} +impl<'a, Env> TxFromSpecified for TestAddress<'a> where Env: TxEnv {} +impl<'a, Env> TxTo for TestAddress<'a> where Env: TxEnv {} +impl<'a, Env> TxToSpecified for TestAddress<'a> where Env: TxEnv {} + +impl<'a> TopEncode for TestAddress<'a> { + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + self.eval_to_array().top_encode_or_handle_err(output, h) + } +} + +impl<'a, Api> TypeAbiFrom> for ManagedAddress where Api: ManagedTypeApi {} + +#[cfg(test)] +pub mod tests { + use super::*; + + fn assert_eq_eval(expr: &'static str, expected: &[u8; 32]) { + assert_eq!(&TestAddress::new(expr).eval_to_array(), expected); + } + + #[test] + fn test_address_value() { + assert_eq_eval("", b"________________________________"); + assert_eq_eval("a", b"a_______________________________"); + assert_eq_eval("a\x05", b"a\x05______________________________"); + assert_eq_eval("an_address", b"an_address______________________"); + assert_eq_eval( + "12345678901234567890123456789012", + b"12345678901234567890123456789012", + ); + assert_eq_eval( + "123456789012345678901234567890123", + b"12345678901234567890123456789012", + ); + } +} diff --git a/framework/base/src/types/interaction/expr/test_sc_address.rs b/framework/base/src/types/interaction/expr/test_sc_address.rs new file mode 100644 index 0000000000..bf01de38bf --- /dev/null +++ b/framework/base/src/types/interaction/expr/test_sc_address.rs @@ -0,0 +1,133 @@ +use core::ptr; + +use multiversx_sc_codec::{EncodeErrorHandler, TopEncode, TopEncodeOutput}; + +use crate::{ + abi::TypeAbiFrom, + api::ManagedTypeApi, + types::{ + heap::Address, AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom, + TxFromSpecified, TxTo, TxToSpecified, + }, +}; + +const SC_PREFIX: &str = "sc:"; +const VM_TYPE_LEN: usize = 2; +const DEFAULT_VM_TYPE: &[u8] = &[5, 0]; + +/// Encodes a dummy SC address, to be used for tests. +/// +/// It is designed to be usable from contracts (especiall test contracts), with a minimal footprint. +/// For this reason, its inner structure is subject to change. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct TestSCAddress<'a> { + name: &'a str, +} + +impl<'a> TestSCAddress<'a> { + pub const fn new(name: &'a str) -> Self { + TestSCAddress { name } + } +} + +impl<'a, Env> AnnotatedValue> for TestSCAddress<'a> +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + let mut result = ManagedBuffer::new_from_bytes(SC_PREFIX.as_bytes()); + result.append_bytes(self.name.as_bytes()); + result + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + let expr: [u8; 32] = self.eval_to_array(); + expr.into() + } +} + +impl<'a> TestSCAddress<'a> { + pub fn to_address(&self) -> Address { + let expr: [u8; 32] = self.eval_to_array(); + expr.into() + } +} + +impl<'a, Env> TxFrom for TestSCAddress<'a> +where + Env: TxEnv, +{ + fn resolve_address(&self, _env: &Env) -> ManagedAddress { + let expr: [u8; 32] = self.eval_to_array(); + expr.into() + } +} +impl<'a, Env> TxFromSpecified for TestSCAddress<'a> where Env: TxEnv {} +impl<'a, Env> TxTo for TestSCAddress<'a> where Env: TxEnv {} +impl<'a, Env> TxToSpecified for TestSCAddress<'a> where Env: TxEnv {} + +impl<'a> TestSCAddress<'a> { + pub fn eval_to_array(&self) -> [u8; 32] { + let result = *b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00______________________"; + let expr_bytes = self.name.as_bytes(); + let mut len = expr_bytes.len(); + if len > 22 { + len = 22; + } + unsafe { + ptr::copy_nonoverlapping( + DEFAULT_VM_TYPE.as_ptr(), + result.as_ptr().offset(8) as *mut u8, + VM_TYPE_LEN, + ); + ptr::copy_nonoverlapping( + expr_bytes.as_ptr(), + result.as_ptr().offset(10) as *mut u8, + len, + ); + } + result + } + + #[cfg(feature = "alloc")] + pub fn eval_to_expr(&self) -> alloc::string::String { + alloc::format!("{SC_PREFIX}{}", self.name) + } +} + +impl<'a> TopEncode for TestSCAddress<'a> { + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + self.eval_to_array().top_encode_or_handle_err(output, h) + } +} + +impl<'a, Api> TypeAbiFrom> for ManagedAddress where Api: ManagedTypeApi {} + +#[cfg(test)] +pub mod tests { + use super::*; + + fn assert_eq_eval(expr: &'static str, expected: &[u8; 32]) { + assert_eq!(&TestSCAddress::new(expr).eval_to_array(), expected); + } + + #[test] + fn test_address_value() { + assert_eq_eval( + "", + b"\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00______________________", + ); + assert_eq_eval( + "a", + b"\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00a_____________________", + ); + assert_eq_eval( + "12345678901234567890120s", + b"\x00\x00\x00\x00\x00\x00\x00\x00\x05\x001234567890123456789012", + ); + } +} diff --git a/framework/base/src/types/interaction/expr/test_token_identifier.rs b/framework/base/src/types/interaction/expr/test_token_identifier.rs new file mode 100644 index 0000000000..47568b37ba --- /dev/null +++ b/framework/base/src/types/interaction/expr/test_token_identifier.rs @@ -0,0 +1,66 @@ +use multiversx_sc_codec::{EncodeErrorHandler, TopEncode, TopEncodeOutput}; + +use crate::{ + abi::TypeAbiFrom, + api::ManagedTypeApi, + types::{AnnotatedValue, ManagedBuffer, TokenIdentifier, TxEnv}, +}; + +const STR_PREFIX: &str = "str:"; + +/// Encodes a dummy address, to be used for tests. +/// +/// It is designed to be usable from contracts (especiall test contracts), with a minimal footprint. +/// For this reason, its inner structure is subject to change. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct TestTokenIdentifier<'a> { + name: &'a str, +} + +impl<'a> TestTokenIdentifier<'a> { + pub const fn new(name: &'a str) -> Self { + TestTokenIdentifier { name } + } + + #[cfg(feature = "alloc")] + pub fn eval_to_expr(&self) -> alloc::string::String { + alloc::format!("{STR_PREFIX}{}", self.name) + } +} + +impl<'a, Env> AnnotatedValue> for TestTokenIdentifier<'a> +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + let mut result = ManagedBuffer::new_from_bytes(STR_PREFIX.as_bytes()); + result.append_bytes(self.name.as_bytes()); + result + } + + fn to_value(&self, _env: &Env) -> TokenIdentifier { + self.name.into() + } +} + +impl<'a, Api> From> for TokenIdentifier +where + Api: ManagedTypeApi, +{ + fn from(value: TestTokenIdentifier<'a>) -> Self { + TokenIdentifier::from_esdt_bytes(value.name) + } +} + +impl<'a> TopEncode for TestTokenIdentifier<'a> { + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + self.name.top_encode_or_handle_err(output, h) + } +} + +impl<'a, Api> TypeAbiFrom> for TokenIdentifier where Api: ManagedTypeApi +{} diff --git a/framework/base/src/types/interaction/managed_arg_buffer.rs b/framework/base/src/types/interaction/managed_arg_buffer.rs index b0cee5db30..c6dae76afd 100644 --- a/framework/base/src/types/interaction/managed_arg_buffer.rs +++ b/framework/base/src/types/interaction/managed_arg_buffer.rs @@ -1,5 +1,5 @@ use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ErrorApi, ManagedTypeApi}, codec::{ DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, @@ -15,6 +15,7 @@ use crate::{ }; use alloc::vec::Vec; use multiversx_sc_codec::TopEncodeMulti; +use unwrap_infallible::UnwrapInfallible; #[derive(Debug, Default, Clone)] #[repr(transparent)] @@ -172,6 +173,10 @@ where pub fn into_vec_of_buffers(self) -> ManagedVec> { self.data } + + pub fn iter_buffers(&self) -> ManagedVecRefIterator> { + ManagedVecRefIterator::new(&self.data) + } } impl ManagedArgBuffer @@ -180,16 +185,17 @@ where { pub fn push_arg(&mut self, arg: T) { let mut encoded_buffer = ManagedBuffer::new(); - let Ok(()) = arg.top_encode_or_handle_err( + arg.top_encode_or_handle_err( &mut encoded_buffer, ExitCodecErrorHandler::::from(err_msg::CONTRACT_CALL_ENCODE_ERROR), - ); + ) + .unwrap_infallible(); self.push_arg_raw(encoded_buffer); } pub fn push_multi_arg(&mut self, arg: &T) { let h = ExitCodecErrorHandler::::from(err_msg::CONTRACT_CALL_ENCODE_ERROR); - let Ok(()) = arg.multi_encode_or_handle_err(self, h); + arg.multi_encode_or_handle_err(self, h).unwrap_infallible(); } } @@ -279,7 +285,7 @@ where pub fn serialize_overwrite(&self, dest: &mut ManagedBuffer) { dest.overwrite(&[]); let h = ExitCodecErrorHandler::::from(err_msg::SERIALIZER_ENCODE_ERROR); - let Ok(()) = self.top_encode_or_handle_err(dest, h); + self.top_encode_or_handle_err(dest, h).unwrap_infallible() } /// Deserializes self from a managed buffer in-place, without creating a new handle. @@ -289,18 +295,30 @@ where self.clear(); let mut nested_de_input = ManagedBufferNestedDecodeInput::new(source); while nested_de_input.remaining_len() > 0 { - let Ok(item) = ManagedBuffer::dep_decode_or_handle_err(&mut nested_de_input, h); + let item = ManagedBuffer::dep_decode_or_handle_err(&mut nested_de_input, h) + .unwrap_infallible(); self.push_arg_raw(item); } } } +impl TypeAbiFrom> for ArgBuffer where M: ManagedTypeApi {} + +impl TypeAbiFrom for ManagedArgBuffer where M: ManagedTypeApi {} +impl TypeAbiFrom<&Self> for ManagedArgBuffer where M: ManagedTypeApi {} + impl TypeAbi for ManagedArgBuffer where M: ManagedTypeApi, { + type Unmanaged = ArgBuffer; + /// It is semantically equivalent to any list of `T`. fn type_name() -> TypeName { <&[ManagedBuffer] as TypeAbi>::type_name() } + + fn type_name_rust() -> TypeName { + "ManagedArgBuffer<$API>".into() + } } diff --git a/framework/base/src/types/interaction/markers.rs b/framework/base/src/types/interaction/markers.rs new file mode 100644 index 0000000000..4ebce757cc --- /dev/null +++ b/framework/base/src/types/interaction/markers.rs @@ -0,0 +1,9 @@ +mod esdt_system_sc_address; +mod gas_left; +mod to_caller; +mod to_self; + +pub use esdt_system_sc_address::ESDTSystemSCAddress; +pub use gas_left::GasLeft; +pub use to_caller::ToCaller; +pub use to_self::ToSelf; diff --git a/framework/base/src/types/interaction/markers/esdt_system_sc_address.rs b/framework/base/src/types/interaction/markers/esdt_system_sc_address.rs new file mode 100644 index 0000000000..b7b646ae16 --- /dev/null +++ b/framework/base/src/types/interaction/markers/esdt_system_sc_address.rs @@ -0,0 +1,70 @@ +use hex_literal::hex; +use multiversx_sc_codec::{EncodeErrorHandler, TopEncode, TopEncodeOutput}; + +use crate::{ + abi::TypeAbiFrom, + api::{CallTypeApi, ManagedTypeApi}, + types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxScEnv, TxTo, TxToSpecified}, +}; + +/// Address of the system smart contract that manages ESDT. +const SYSTEM_SC_ADDRESS_BYTES: [u8; 32] = + hex!("000000000000000000010000000000000000000000000000000000000002ffff"); +const SYSTEM_SC_ADDRESS_BECH32: &str = + "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"; +const SYSTEM_SC_ADDRESS_ANNOTATION: &str = + "bech32:erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"; + +/// Indicates the system SC address, which is the same on any MultiversX blockchain. +pub struct ESDTSystemSCAddress; + +impl ESDTSystemSCAddress { + pub fn to_managed_address(self) -> ManagedAddress + where + Api: ManagedTypeApi, + { + ManagedAddress::from(SYSTEM_SC_ADDRESS_BYTES) + } + + pub fn to_bech32_str(&self) -> &str { + SYSTEM_SC_ADDRESS_BECH32 + } + + pub fn to_bech32_string(&self) -> alloc::string::String { + SYSTEM_SC_ADDRESS_BECH32.into() + } +} + +impl AnnotatedValue, ManagedAddress> for ESDTSystemSCAddress +where + Api: CallTypeApi, +{ + fn annotation(&self, _env: &TxScEnv) -> ManagedBuffer { + ManagedBuffer::from(SYSTEM_SC_ADDRESS_ANNOTATION) + } + + fn to_value(&self, _env: &TxScEnv) -> ManagedAddress { + ESDTSystemSCAddress.to_managed_address() + } +} + +impl TxTo> for ESDTSystemSCAddress where Api: CallTypeApi {} +impl TxToSpecified> for ESDTSystemSCAddress where Api: CallTypeApi {} + +impl TopEncode for ESDTSystemSCAddress { + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + SYSTEM_SC_ADDRESS_BYTES.top_encode_or_handle_err(output, h) + } +} + +impl TypeAbiFrom for ManagedAddress where M: ManagedTypeApi {} + +impl core::fmt::Display for ESDTSystemSCAddress { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(SYSTEM_SC_ADDRESS_BECH32) + } +} diff --git a/framework/base/src/types/interaction/markers/gas_left.rs b/framework/base/src/types/interaction/markers/gas_left.rs new file mode 100644 index 0000000000..d30209b3d1 --- /dev/null +++ b/framework/base/src/types/interaction/markers/gas_left.rs @@ -0,0 +1,24 @@ +use crate::{ + api::{BlockchainApi, BlockchainApiImpl}, + types::{interaction::display_u64, AnnotatedValue, ManagedBuffer, TxEnv, TxGasValue}, +}; + +/// Indicates that all remaining gas should be sent to a transaction. +/// +/// Usually unwise, other than for synchronous calls, you always want to have some gas left in the contract after the call. +pub struct GasLeft; + +impl AnnotatedValue for GasLeft +where + Env: TxEnv, +{ + fn annotation(&self, env: &Env) -> ManagedBuffer { + display_u64(self.to_value(env)) + } + + fn to_value(&self, _env: &Env) -> u64 { + Env::Api::blockchain_api_impl().get_gas_left() + } +} + +impl TxGasValue for GasLeft where Env: TxEnv {} diff --git a/framework/base/src/types/interaction/markers/to_caller.rs b/framework/base/src/types/interaction/markers/to_caller.rs new file mode 100644 index 0000000000..f24191ce9f --- /dev/null +++ b/framework/base/src/types/interaction/markers/to_caller.rs @@ -0,0 +1,35 @@ +use crate::{ + api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi}, + contract_base::BlockchainWrapper, + types::{ + AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv, TxTo, TxToSpecified, + }, +}; + +/// Indicates that transaction should be sent to the caller (the sender of the current transaction). +pub struct ToCaller; + +impl AnnotatedValue, ManagedAddress> for ToCaller +where + Api: CallTypeApi + BlockchainApi, +{ + fn annotation(&self, env: &TxScEnv) -> ManagedBuffer { + self.with_address_ref(env, |addr_ref| addr_ref.hex_expr()) + } + + fn to_value(&self, _env: &TxScEnv) -> ManagedAddress { + BlockchainWrapper::::new().get_caller() + } + + fn with_value_ref(&self, _env: &TxScEnv, f: F) -> R + where + F: FnOnce(&ManagedAddress) -> R, + { + let caller_handle: Api::ManagedBufferHandle = use_raw_handle(const_handles::ADDRESS_CALLER); + Api::blockchain_api_impl().load_caller_managed(caller_handle.clone()); + f(&ManagedAddress::from_handle(caller_handle)) + } +} + +impl TxTo> for ToCaller where Api: CallTypeApi + BlockchainApi {} +impl TxToSpecified> for ToCaller where Api: CallTypeApi + BlockchainApi {} diff --git a/framework/base/src/types/interaction/markers/to_self.rs b/framework/base/src/types/interaction/markers/to_self.rs new file mode 100644 index 0000000000..f339a448e2 --- /dev/null +++ b/framework/base/src/types/interaction/markers/to_self.rs @@ -0,0 +1,37 @@ +use crate::{ + api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi}, + contract_base::BlockchainWrapper, + types::{ + AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv, TxTo, TxToSpecified, + }, +}; + +/// Indicates that transaction should be sent to itself. +pub struct ToSelf; + +impl AnnotatedValue, ManagedAddress> for ToSelf +where + Api: CallTypeApi + BlockchainApi, +{ + fn annotation(&self, env: &TxScEnv) -> ManagedBuffer { + self.with_address_ref(env, |addr_ref| addr_ref.hex_expr()) + } + + #[inline] + fn to_value(&self, _env: &TxScEnv) -> ManagedAddress { + BlockchainWrapper::::new().get_sc_address() + } + + fn with_value_ref(&self, _env: &TxScEnv, f: F) -> R + where + F: FnOnce(&ManagedAddress) -> R, + { + let sc_address_handle: Api::ManagedBufferHandle = + use_raw_handle(const_handles::ADDRESS_CALLER); + Api::blockchain_api_impl().load_sc_address_managed(sc_address_handle.clone()); + f(&ManagedAddress::from_handle(sc_address_handle)) + } +} + +impl TxTo> for ToSelf where Api: CallTypeApi + BlockchainApi {} +impl TxToSpecified> for ToSelf where Api: CallTypeApi + BlockchainApi {} diff --git a/framework/base/src/types/interaction/result_handlers.rs b/framework/base/src/types/interaction/result_handlers.rs new file mode 100644 index 0000000000..dd3a334e2c --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers.rs @@ -0,0 +1,23 @@ +mod returns_bt; +mod returns_new_address; +mod returns_new_managed_address; +mod returns_raw_result; +mod returns_result; +mod returns_result_as; +mod returns_result_unmanaged; +mod with_new_address; +mod with_raw_result; +mod with_result; +mod with_result_as; + +pub use returns_bt::*; +pub use returns_new_address::*; +pub use returns_new_managed_address::*; +pub use returns_raw_result::*; +pub use returns_result::*; +pub use returns_result_as::*; +pub use returns_result_unmanaged::ReturnsResultUnmanaged; +pub use with_new_address::*; +pub use with_raw_result::WithRawResult; +pub use with_result::WithResult; +pub use with_result_as::*; diff --git a/framework/base/src/types/interaction/result_handlers/returns_bt.rs b/framework/base/src/types/interaction/result_handlers/returns_bt.rs new file mode 100644 index 0000000000..e61abf256d --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/returns_bt.rs @@ -0,0 +1,23 @@ +use crate::{ + contract_base::BlockchainWrapper, + types::{BackTransfers, RHListItem, RHListItemExec, TxEnv}, +}; + +/// Indicates that back-transfers will be returned. +pub struct ReturnsBackTransfers; + +impl RHListItem for ReturnsBackTransfers +where + Env: TxEnv, +{ + type Returns = BackTransfers; +} + +impl RHListItemExec for ReturnsBackTransfers +where + Env: TxEnv, +{ + fn item_process_result(self, _raw_result: &RawResult) -> Self::Returns { + BlockchainWrapper::::new().get_back_transfers() + } +} diff --git a/framework/base/src/types/interaction/result_handlers/returns_new_address.rs b/framework/base/src/types/interaction/result_handlers/returns_new_address.rs new file mode 100644 index 0000000000..eaa523828b --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/returns_new_address.rs @@ -0,0 +1,20 @@ +use crate::types::{heap::Address, DeployRawResult, RHListItem, RHListItemExec, TxEnv}; + +/// Indicates that the newly deployed address will be returned after a deploy. +pub struct ReturnsNewAddress; + +impl RHListItem for ReturnsNewAddress +where + Env: TxEnv, +{ + type Returns = Address; +} + +impl RHListItemExec, Env, Original> for ReturnsNewAddress +where + Env: TxEnv, +{ + fn item_process_result(self, raw_result: &DeployRawResult) -> Self::Returns { + raw_result.new_address.to_address() + } +} diff --git a/framework/base/src/types/interaction/result_handlers/returns_new_managed_address.rs b/framework/base/src/types/interaction/result_handlers/returns_new_managed_address.rs new file mode 100644 index 0000000000..15ed220dc4 --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/returns_new_managed_address.rs @@ -0,0 +1,21 @@ +use crate::types::{DeployRawResult, ManagedAddress, RHListItem, RHListItemExec, TxEnv}; + +/// Indicates that the newly deployed address will be returned after a deploy as a ManagedAddress. +pub struct ReturnsNewManagedAddress; + +impl RHListItem for ReturnsNewManagedAddress +where + Env: TxEnv, +{ + type Returns = ManagedAddress; +} + +impl RHListItemExec, Env, Original> + for ReturnsNewManagedAddress +where + Env: TxEnv, +{ + fn item_process_result(self, raw_result: &DeployRawResult) -> Self::Returns { + raw_result.new_address.clone() + } +} diff --git a/framework/base/src/types/interaction/result_handlers/returns_raw_result.rs b/framework/base/src/types/interaction/result_handlers/returns_raw_result.rs new file mode 100644 index 0000000000..807ce5cf82 --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/returns_raw_result.rs @@ -0,0 +1,32 @@ +use crate::types::{ + DeployRawResult, ManagedBuffer, ManagedVec, RHListItem, RHListItemExec, SyncCallRawResult, + TxEnv, +}; + +/// Indicates that the raw result data will be returned. +pub struct ReturnsRawResult; + +impl RHListItem for ReturnsRawResult +where + Env: TxEnv, +{ + type Returns = ManagedVec>; +} + +impl RHListItemExec, Env, Original> for ReturnsRawResult +where + Env: TxEnv, +{ + fn item_process_result(self, raw_result: &SyncCallRawResult) -> Self::Returns { + raw_result.0.clone() + } +} + +impl RHListItemExec, Env, Original> for ReturnsRawResult +where + Env: TxEnv, +{ + fn item_process_result(self, raw_result: &DeployRawResult) -> Self::Returns { + raw_result.raw_results.clone() + } +} diff --git a/framework/base/src/types/interaction/result_handlers/returns_result.rs b/framework/base/src/types/interaction/result_handlers/returns_result.rs new file mode 100644 index 0000000000..b5c4a5c491 --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/returns_result.rs @@ -0,0 +1,38 @@ +use multiversx_sc_codec::TopDecodeMulti; + +use crate::types::{ + interaction::decode_result, DeployRawResult, RHListItem, RHListItemExec, SyncCallRawResult, + TxEnv, +}; + +/// Indicates that result will be returned. +/// +/// Value will be decoded according to the type defined in the smart contract. +pub struct ReturnsResult; + +impl RHListItem for ReturnsResult +where + Env: TxEnv, +{ + type Returns = Original; +} + +impl RHListItemExec, Env, Original> for ReturnsResult +where + Env: TxEnv, + Original: TopDecodeMulti, +{ + fn item_process_result(self, raw_result: &SyncCallRawResult) -> Original { + decode_result::(raw_result.0.clone()) + } +} + +impl RHListItemExec, Env, Original> for ReturnsResult +where + Env: TxEnv, + Original: TopDecodeMulti, +{ + fn item_process_result(self, raw_result: &DeployRawResult) -> Original { + decode_result::(raw_result.raw_results.clone()) + } +} diff --git a/framework/base/src/types/interaction/result_handlers/returns_result_as.rs b/framework/base/src/types/interaction/result_handlers/returns_result_as.rs new file mode 100644 index 0000000000..842ae01eb8 --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/returns_result_as.rs @@ -0,0 +1,48 @@ +use core::marker::PhantomData; + +use multiversx_sc_codec::TopDecodeMulti; + +use crate::{ + abi::TypeAbiFrom, + types::{interaction::decode_result, RHListItem, RHListItemExec, SyncCallRawResult, TxEnv}, +}; + +/// Indicates that result will be returned. +/// +/// Value will be converted to type `T`, which should be compatible with the original type. +pub struct ReturnsResultAs { + _phantom: PhantomData, +} + +impl Default for ReturnsResultAs { + fn default() -> Self { + Self { + _phantom: Default::default(), + } + } +} + +impl ReturnsResultAs { + pub fn new() -> Self { + Self::default() + } +} + +impl RHListItem for ReturnsResultAs +where + Env: TxEnv, + T: TopDecodeMulti + TypeAbiFrom, +{ + type Returns = T; +} + +impl RHListItemExec, Env, Original> + for ReturnsResultAs +where + Env: TxEnv, + T: TopDecodeMulti + TypeAbiFrom, +{ + fn item_process_result(self, raw_result: &SyncCallRawResult) -> Self::Returns { + decode_result::(raw_result.0.clone()) + } +} diff --git a/framework/base/src/types/interaction/result_handlers/returns_result_unmanaged.rs b/framework/base/src/types/interaction/result_handlers/returns_result_unmanaged.rs new file mode 100644 index 0000000000..4785aef50a --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/returns_result_unmanaged.rs @@ -0,0 +1,30 @@ +use multiversx_sc_codec::TopDecodeMulti; + +use crate::{ + abi::TypeAbi, + types::{interaction::decode_result, RHListItem, RHListItemExec, SyncCallRawResult, TxEnv}, +}; + +/// Indicates that the unmanaged version of the result will be returned. +pub struct ReturnsResultUnmanaged; + +impl RHListItem for ReturnsResultUnmanaged +where + Env: TxEnv, + Original: TypeAbi, + Original::Unmanaged: TopDecodeMulti, +{ + type Returns = Original::Unmanaged; +} + +impl RHListItemExec, Env, Original> + for ReturnsResultUnmanaged +where + Env: TxEnv, + Original: TypeAbi, + Original::Unmanaged: TopDecodeMulti, +{ + fn item_process_result(self, raw_result: &SyncCallRawResult) -> Self::Returns { + decode_result::(raw_result.0.clone()) + } +} diff --git a/framework/base/src/types/interaction/result_handlers/with_new_address.rs b/framework/base/src/types/interaction/result_handlers/with_new_address.rs new file mode 100644 index 0000000000..f26d12983c --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/with_new_address.rs @@ -0,0 +1,45 @@ +use core::marker::PhantomData; + +use crate::types::{DeployRawResult, ManagedAddress, RHListItem, RHListItemExec, TxEnv}; + +/// Defines a lambda function to be called on the newly deployed address, after a deploy. +pub struct WithNewAddress +where + Env: TxEnv, + F: FnOnce(&ManagedAddress), +{ + _phantom: PhantomData, + pub f: F, +} + +impl WithNewAddress +where + Env: TxEnv, + F: FnOnce(&ManagedAddress), +{ + pub fn new(f: F) -> Self { + WithNewAddress { + _phantom: PhantomData, + f, + } + } +} + +impl RHListItem for WithNewAddress +where + Env: TxEnv, + F: FnOnce(&ManagedAddress), +{ + type Returns = (); +} + +impl RHListItemExec, Env, Original> + for WithNewAddress +where + Env: TxEnv, + F: FnOnce(&ManagedAddress), +{ + fn item_process_result(self, raw_result: &DeployRawResult) -> Self::Returns { + (self.f)(&raw_result.new_address); + } +} diff --git a/framework/base/src/types/interaction/result_handlers/with_raw_result.rs b/framework/base/src/types/interaction/result_handlers/with_raw_result.rs new file mode 100644 index 0000000000..f2d1457f07 --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/with_raw_result.rs @@ -0,0 +1,47 @@ +use core::marker::PhantomData; + +use crate::types::{ + ManagedBuffer, ManagedVec, RHListItem, RHListItemExec, SyncCallRawResult, TxEnv, +}; + +/// Defines a lambda function to be called on the raw result of the transaction. +pub struct WithRawResult +where + Env: TxEnv, + F: FnOnce(&ManagedVec>), +{ + _phantom: PhantomData, + f: F, +} + +impl WithRawResult +where + Env: TxEnv, + F: FnOnce(&ManagedVec>), +{ + pub fn new(f: F) -> Self { + WithRawResult { + _phantom: PhantomData, + f, + } + } +} + +impl RHListItem for WithRawResult +where + Env: TxEnv, + F: FnOnce(&ManagedVec>), +{ + type Returns = (); +} + +impl RHListItemExec, Env, Original> + for WithRawResult +where + Env: TxEnv, + F: FnOnce(&ManagedVec>), +{ + fn item_process_result(self, raw_result: &SyncCallRawResult) -> Self::Returns { + (self.f)(&raw_result.0) + } +} diff --git a/framework/base/src/types/interaction/result_handlers/with_result.rs b/framework/base/src/types/interaction/result_handlers/with_result.rs new file mode 100644 index 0000000000..ad4daea57d --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/with_result.rs @@ -0,0 +1,51 @@ +use core::marker::PhantomData; + +use multiversx_sc_codec::TopDecodeMulti; + +use crate::types::{ + interaction::decode_result, RHListItem, RHListItemExec, SyncCallRawResult, TxEnv, +}; + +/// Defines a lambda function to be called on the decoded result. +/// +/// Value will be decoded according to the type defined in the smart contract. +pub struct WithResult +where + F: FnOnce(T), +{ + _phantom: PhantomData, + f: F, +} + +impl WithResult +where + F: FnOnce(T), +{ + pub fn new(f: F) -> Self { + WithResult { + _phantom: PhantomData, + f, + } + } +} + +impl RHListItem for WithResult +where + Env: TxEnv, + F: FnOnce(Original), +{ + type Returns = (); +} + +impl RHListItemExec, Env, Original> + for WithResult +where + Env: TxEnv, + Original: TopDecodeMulti, + F: FnOnce(Original), +{ + fn item_process_result(self, raw_result: &SyncCallRawResult) -> Self::Returns { + let t = decode_result::(raw_result.0.clone()); + (self.f)(t) + } +} diff --git a/framework/base/src/types/interaction/result_handlers/with_result_as.rs b/framework/base/src/types/interaction/result_handlers/with_result_as.rs new file mode 100644 index 0000000000..4a2aed8f35 --- /dev/null +++ b/framework/base/src/types/interaction/result_handlers/with_result_as.rs @@ -0,0 +1,53 @@ +use core::marker::PhantomData; + +use multiversx_sc_codec::TopDecodeMulti; + +use crate::{ + abi::TypeAbiFrom, + types::{interaction::decode_result, RHListItem, RHListItemExec, SyncCallRawResult, TxEnv}, +}; + +/// Defines a lambda function to be called on the decoded result. +/// +/// Value will be converted to type `T`, which should be compatible with the original type. +pub struct WithResultAs +where + F: FnOnce(T), +{ + _phantom: PhantomData, + pub f: F, +} + +impl WithResultAs +where + F: FnOnce(T), +{ + pub fn new(f: F) -> Self { + WithResultAs { + _phantom: PhantomData, + f, + } + } +} + +impl RHListItem for WithResultAs +where + Env: TxEnv, + T: TopDecodeMulti + TypeAbiFrom, + F: FnOnce(T), +{ + type Returns = (); +} + +impl RHListItemExec, Env, Original> + for WithResultAs +where + Env: TxEnv, + T: TopDecodeMulti + TypeAbiFrom, + F: FnOnce(T), +{ + fn item_process_result(self, raw_result: &SyncCallRawResult) -> Self::Returns { + let t = decode_result::(raw_result.0.clone()); + (self.f)(t) + } +} diff --git a/framework/base/src/types/interaction/system_proxy.rs b/framework/base/src/types/interaction/system_proxy.rs new file mode 100644 index 0000000000..3b1fb836d6 --- /dev/null +++ b/framework/base/src/types/interaction/system_proxy.rs @@ -0,0 +1,10 @@ +pub mod builtin_func_names; +mod builtin_func_proxy; +mod esdt_system_sc_proxy; +mod legacy_system_sc_proxy; +pub(crate) mod token_properties; + +pub use builtin_func_proxy::*; +pub use esdt_system_sc_proxy::{ESDTSystemSCProxy, ESDTSystemSCProxyMethods, IssueCall}; +pub use legacy_system_sc_proxy::ESDTSystemSmartContractProxy; +pub use token_properties::*; diff --git a/framework/base/src/api/builtin_function_names.rs b/framework/base/src/types/interaction/system_proxy/builtin_func_names.rs similarity index 100% rename from framework/base/src/api/builtin_function_names.rs rename to framework/base/src/types/interaction/system_proxy/builtin_func_names.rs diff --git a/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs new file mode 100644 index 0000000000..7b5e2fefb2 --- /dev/null +++ b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs @@ -0,0 +1,204 @@ +use multiversx_sc_codec::{Empty, TopEncode}; + +use crate::types::{ + BigUint, ManagedAddress, ManagedBuffer, ManagedVec, NotPayable, ProxyArg, TokenIdentifier, Tx, + TxEnv, TxFrom, TxGas, TxProxyTrait, TxTo, TxTypedCall, +}; + +use super::builtin_func_names::{ + CHANGE_OWNER_BUILTIN_FUNC_NAME, CLAIM_DEVELOPER_REWARDS_FUNC_NAME, DELETE_USERNAME_FUNC_NAME, + ESDT_LOCAL_BURN_FUNC_NAME, ESDT_LOCAL_MINT_FUNC_NAME, ESDT_NFT_ADD_QUANTITY_FUNC_NAME, + ESDT_NFT_ADD_URI_FUNC_NAME, ESDT_NFT_BURN_FUNC_NAME, ESDT_NFT_CREATE_FUNC_NAME, + ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME, SET_USERNAME_FUNC_NAME, +}; + +/// Proxy describing the user builtin function signatures. +pub struct UserBuiltinProxy; + +impl TxProxyTrait for UserBuiltinProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = UserBuiltinProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + UserBuiltinProxyMethods { wrapped_tx: tx } + } +} + +pub struct UserBuiltinProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +impl UserBuiltinProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn set_user_name>>( + self, + name: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call(SET_USERNAME_FUNC_NAME) + .argument(&name) + .original_result() + } + + pub fn delete_user_name(self) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call(DELETE_USERNAME_FUNC_NAME) + .original_result() + } + + pub fn claim_developer_rewards(self) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call(CLAIM_DEVELOPER_REWARDS_FUNC_NAME) + .original_result() + } + + pub fn change_owner_address( + self, + new_owner: &ManagedAddress, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call(CHANGE_OWNER_BUILTIN_FUNC_NAME) + .argument(new_owner) + .original_result() + } + + pub fn esdt_local_burn( + self, + token: &TokenIdentifier, + nonce: u64, + amount: &BigUint, + ) -> TxTypedCall { + if nonce == 0 { + return self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_LOCAL_BURN_FUNC_NAME) + .argument(token) + .argument(amount) + .original_result(); + } + + self.wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_NFT_BURN_FUNC_NAME) + .argument(token) + .argument(&nonce) + .argument(amount) + .original_result() + } + + pub fn esdt_local_mint( + self, + token: &TokenIdentifier, + nonce: u64, + amount: &BigUint, + ) -> TxTypedCall { + if nonce == 0 { + return self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_LOCAL_MINT_FUNC_NAME) + .argument(token) + .argument(amount) + .original_result(); + } + self.wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_NFT_ADD_QUANTITY_FUNC_NAME) + .argument(token) + .argument(&nonce) + .argument(amount) + .original_result() + } + + pub fn nft_add_multiple_uri( + self, + token_id: &TokenIdentifier, + nft_nonce: u64, + new_uris: &ManagedVec>, + ) -> TxTypedCall { + let mut tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_NFT_ADD_URI_FUNC_NAME) + .argument(token_id) + .argument(&nft_nonce); + + for uri in new_uris { + tx = tx.argument(&uri); + } + + tx.original_result() + } + + pub fn nft_update_attributes( + self, + token_id: &TokenIdentifier, + nft_nonce: u64, + new_attributes: &T, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME) + .argument(token_id) + .argument(&nft_nonce) + .argument(new_attributes) + .original_result() + } + + #[allow(clippy::too_many_arguments)] + pub fn esdt_nft_create( + self, + token: &TokenIdentifier, + amount: &BigUint, + name: &ManagedBuffer, + royalties: &BigUint, + hash: &ManagedBuffer, + attributes: &T, + uris: &ManagedVec>, + ) -> TxTypedCall { + let mut tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call(ESDT_NFT_CREATE_FUNC_NAME) + .argument(token) + .argument(amount) + .argument(name) + .argument(royalties) + .argument(hash) + .argument(attributes); + + if uris.is_empty() { + // at least one URI is required, so we push an empty one + tx = tx.argument(&Empty); + } else { + // The API function has the last argument as variadic, + // so we top-encode each and send as separate argument + for uri in uris { + tx = tx.argument(&uri); + } + } + + tx.original_result() + } +} diff --git a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs new file mode 100644 index 0000000000..50325ed78d --- /dev/null +++ b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs @@ -0,0 +1,598 @@ +use super::token_properties::*; + +use crate::{ + api::CallTypeApi, + types::{ + BigUint, EgldPayment, EsdtLocalRole, EsdtTokenType, FunctionCall, ManagedAddress, + ManagedBuffer, NotPayable, OriginalResultMarker, TokenIdentifier, Tx, TxEnv, TxFrom, TxGas, + TxProxyTrait, TxTo, TxTypedCall, + }, +}; + +const ISSUE_FUNGIBLE_ENDPOINT_NAME: &str = "issue"; +const ISSUE_NON_FUNGIBLE_ENDPOINT_NAME: &str = "issueNonFungible"; +const ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME: &str = "issueSemiFungible"; +const REGISTER_META_ESDT_ENDPOINT_NAME: &str = "registerMetaESDT"; +const ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME: &str = "registerAndSetAllRoles"; + +/// The specific `Tx` type produces by the issue operations of the ESDTSystemSCProxy. +pub type IssueCall = Tx< + Env, + From, + To, + EgldPayment<::Api>, + Gas, + FunctionCall<::Api>, + OriginalResultMarker::Api>>, +>; + +/// Proxy for the ESDT system smart contract. +pub struct ESDTSystemSCProxy; + +impl TxProxyTrait for ESDTSystemSCProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = ESDTSystemSCProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + ESDTSystemSCProxyMethods { wrapped_tx: tx } + } +} + +/// Method container of the ESDT system smart contract proxy. +pub struct ESDTSystemSCProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +impl ESDTSystemSCProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + /// Produces a contract call to the ESDT system SC, + /// which causes it to issue a new fungible ESDT token. + pub fn issue_fungible( + self, + issue_cost: BigUint, + token_display_name: &ManagedBuffer, + token_ticker: &ManagedBuffer, + initial_supply: &BigUint, + properties: FungibleTokenProperties, + ) -> IssueCall { + self.issue( + issue_cost, + EsdtTokenType::Fungible, + token_display_name, + token_ticker, + initial_supply, + TokenProperties { + num_decimals: properties.num_decimals, + can_freeze: properties.can_freeze, + can_wipe: properties.can_wipe, + can_pause: properties.can_pause, + can_transfer_create_role: false, + can_mint: properties.can_mint, + can_burn: properties.can_burn, + can_change_owner: properties.can_change_owner, + can_upgrade: properties.can_upgrade, + can_add_special_roles: properties.can_add_special_roles, + }, + ) + } + + /// Produces a contract call to the ESDT system SC, + /// which causes it to issue a new non-fungible ESDT token. + pub fn issue_non_fungible( + self, + issue_cost: BigUint, + token_display_name: &ManagedBuffer, + token_ticker: &ManagedBuffer, + properties: NonFungibleTokenProperties, + ) -> IssueCall { + let zero = BigUint::zero_ref(); + self.issue( + issue_cost, + EsdtTokenType::NonFungible, + token_display_name, + token_ticker, + &zero, + TokenProperties { + num_decimals: 0, + can_freeze: properties.can_freeze, + can_wipe: properties.can_wipe, + can_pause: properties.can_pause, + can_transfer_create_role: properties.can_transfer_create_role, + can_mint: false, + can_burn: false, + can_change_owner: properties.can_change_owner, + can_upgrade: properties.can_upgrade, + can_add_special_roles: properties.can_add_special_roles, + }, + ) + } + + /// Produces a contract call to the ESDT system SC, + /// which causes it to issue a new semi-fungible ESDT token. + pub fn issue_semi_fungible( + self, + issue_cost: BigUint, + token_display_name: &ManagedBuffer, + token_ticker: &ManagedBuffer, + properties: SemiFungibleTokenProperties, + ) -> IssueCall { + let zero = BigUint::zero(); + self.issue( + issue_cost, + EsdtTokenType::SemiFungible, + token_display_name, + token_ticker, + &zero, + TokenProperties { + num_decimals: 0, + can_freeze: properties.can_freeze, + can_wipe: properties.can_wipe, + can_pause: properties.can_pause, + can_transfer_create_role: properties.can_transfer_create_role, + can_mint: false, + can_burn: false, + can_change_owner: properties.can_change_owner, + can_upgrade: properties.can_upgrade, + can_add_special_roles: properties.can_add_special_roles, + }, + ) + } + + /// Produces a contract call to the ESDT system SC, + /// which causes it to register a new Meta ESDT token. + pub fn register_meta_esdt( + self, + issue_cost: BigUint, + token_display_name: &ManagedBuffer, + token_ticker: &ManagedBuffer, + properties: MetaTokenProperties, + ) -> IssueCall { + let zero = BigUint::zero(); + self.issue( + issue_cost, + EsdtTokenType::Meta, + token_display_name, + token_ticker, + &zero, + TokenProperties { + num_decimals: properties.num_decimals, + can_freeze: properties.can_freeze, + can_wipe: properties.can_wipe, + can_pause: properties.can_pause, + can_transfer_create_role: properties.can_transfer_create_role, + can_mint: false, + can_burn: false, + can_change_owner: properties.can_change_owner, + can_upgrade: properties.can_upgrade, + can_add_special_roles: properties.can_add_special_roles, + }, + ) + } + + pub fn issue_and_set_all_roles( + self, + issue_cost: BigUint, + token_display_name: ManagedBuffer, + token_ticker: ManagedBuffer, + token_type: EsdtTokenType, + num_decimals: usize, + ) -> IssueCall { + let token_type_name = match token_type { + EsdtTokenType::Fungible => "FNG", + EsdtTokenType::NonFungible => "NFT", + EsdtTokenType::SemiFungible => "SFT", + EsdtTokenType::Meta => "META", + EsdtTokenType::Invalid => "", + }; + + self.wrapped_tx + .raw_call(ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME) + .egld(issue_cost) + .argument(&token_display_name) + .argument(&token_ticker) + .argument(&token_type_name) + .argument(&num_decimals) + .original_result() + } + + /// Deduplicates code from all the possible issue functions + fn issue( + self, + issue_cost: BigUint, + token_type: EsdtTokenType, + token_display_name: &ManagedBuffer, + token_ticker: &ManagedBuffer, + initial_supply: &BigUint, + properties: TokenProperties, + ) -> IssueCall { + let endpoint_name = match token_type { + EsdtTokenType::Fungible => ISSUE_FUNGIBLE_ENDPOINT_NAME, + EsdtTokenType::NonFungible => ISSUE_NON_FUNGIBLE_ENDPOINT_NAME, + EsdtTokenType::SemiFungible => ISSUE_SEMI_FUNGIBLE_ENDPOINT_NAME, + EsdtTokenType::Meta => REGISTER_META_ESDT_ENDPOINT_NAME, + EsdtTokenType::Invalid => "", + }; + + let mut tx = self + .wrapped_tx + .raw_call(endpoint_name) + .egld(issue_cost) + .argument(token_display_name) + .argument(token_ticker); + + if token_type == EsdtTokenType::Fungible { + tx = tx.argument(initial_supply); + tx = tx.argument(&properties.num_decimals); + } else if token_type == EsdtTokenType::Meta { + tx = tx.argument(&properties.num_decimals); + } + + let mut token_prop_args = TokenPropertyArguments { + can_freeze: Some(properties.can_freeze), + can_wipe: Some(properties.can_wipe), + can_pause: Some(properties.can_pause), + can_change_owner: Some(properties.can_change_owner), + can_upgrade: Some(properties.can_upgrade), + can_add_special_roles: Some(properties.can_add_special_roles), + ..TokenPropertyArguments::default() + }; + + if token_type == EsdtTokenType::Fungible { + token_prop_args.can_mint = Some(properties.can_mint); + token_prop_args.can_burn = Some(properties.can_burn); + } else { + token_prop_args.can_transfer_create_role = Some(properties.can_transfer_create_role); + } + + append_token_property_arguments(&mut tx.data, &token_prop_args); + + tx.original_result() + } + + /// Produces a contract call to the ESDT system SC, + /// which causes it to mint more fungible ESDT tokens. + /// It will fail if the SC is not the owner of the token. + pub fn mint( + self, + token_identifier: &TokenIdentifier, + amount: &BigUint, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("mint") + .argument(token_identifier) + .argument(amount) + .original_result() + } + + /// Produces a contract call to the ESDT system SC, + /// which causes it to burn fungible ESDT tokens owned by the SC. + pub fn burn( + self, + token_identifier: &TokenIdentifier, + amount: &BigUint, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("ESDTBurn") + .argument(token_identifier) + .argument(amount) + .original_result() + } + + /// The manager of an ESDT token may choose to suspend all transactions of the token, + /// except minting, freezing/unfreezing and wiping. + pub fn pause( + self, + token_identifier: &TokenIdentifier, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("pause") + .argument(token_identifier) + .original_result() + } + + /// The reverse operation of `pause`. + pub fn unpause( + self, + token_identifier: &TokenIdentifier, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unPause") + .argument(token_identifier) + .original_result() + } + + /// The manager of an ESDT token may freeze the tokens held by a specific account. + /// As a consequence, no tokens may be transferred to or from the frozen account. + /// Freezing and unfreezing the tokens of an account are operations designed to help token managers to comply with regulations. + pub fn freeze( + self, + token_identifier: &TokenIdentifier, + address: &ManagedAddress, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("freeze") + .argument(token_identifier) + .argument(address) + .original_result() + } + + /// The reverse operation of `freeze`, unfreezing, will allow further transfers to and from the account. + pub fn unfreeze( + self, + token_identifier: &TokenIdentifier, + address: &ManagedAddress, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unFreeze") + .argument(token_identifier) + .argument(address) + .original_result() + } + + /// The manager of an ESDT token may wipe out all the tokens held by a frozen account. + /// This operation is similar to burning the tokens, but the account must have been frozen beforehand, + /// and it must be done by the token manager. + /// Wiping the tokens of an account is an operation designed to help token managers to comply with regulations. + pub fn wipe( + self, + token_identifier: &TokenIdentifier, + address: &ManagedAddress, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("wipe") + .argument(token_identifier) + .argument(address) + .original_result() + } + + /// The manager of an ESDT token may freeze the NFT held by a specific Account. + /// As a consequence, no NFT can be transferred to or from the frozen Account. + /// Freezing and unfreezing a single NFT of an Account are operations designed to help token managers to comply with regulations. + pub fn freeze_nft( + self, + token_identifier: &TokenIdentifier, + nft_nonce: u64, + address: &ManagedAddress, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("freezeSingleNFT") + .argument(token_identifier) + .argument(&nft_nonce) + .argument(address) + .original_result() + } + + /// The reverse operation of `freeze`, unfreezing, will allow further transfers to and from the account. + pub fn unfreeze_nft( + self, + token_identifier: &TokenIdentifier, + nft_nonce: u64, + address: &ManagedAddress, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("unFreezeSingleNFT") + .argument(token_identifier) + .argument(&nft_nonce) + .argument(address) + .original_result() + } + + /// The manager of an ESDT token may wipe out a single NFT held by a frozen Account. + /// This operation is similar to burning the quantity, but the Account must have been frozen beforehand, + /// and it must be done by the token manager. + /// Wiping the tokens of an Account is an operation designed to help token managers to comply with regulations. + pub fn wipe_nft( + self, + token_identifier: &TokenIdentifier, + nft_nonce: u64, + address: &ManagedAddress, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("wipeSingleNFT") + .argument(token_identifier) + .argument(&nft_nonce) + .argument(address) + .original_result() + } + + /// This function converts an SFT to a metaESDT by adding decimals to its structure in the metachain ESDT System SC. + /// This function as almost all in case of ESDT can be called only by the owner. + pub fn change_sft_to_meta_esdt( + self, + token_identifier: &TokenIdentifier, + num_decimals: usize, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("changeSFTToMetaESDT") + .argument(&token_identifier) + .argument(&num_decimals) + .original_result() + } + + /// This function can be called only if canSetSpecialRoles was set to true. + /// The metachain system SC will evaluate the arguments and call “ESDTSetRole@tokenId@listOfRoles” for the given address. + /// This will be actually a cross shard call. + /// This function as almost all in case of ESDT can be called only by the owner. + pub fn set_special_roles>( + self, + address: &ManagedAddress, + token_identifier: &TokenIdentifier, + roles_iter: RoleIter, + ) -> TxTypedCall { + let mut tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call("setSpecialRole") + .argument(token_identifier) + .argument(address); + for role in roles_iter { + if role != EsdtLocalRole::None { + tx = tx.argument(&role.as_role_name()); + } + } + + tx.original_result() + } + + /// This function can be called only if canSetSpecialRoles was set to true. + /// The metachain system SC will evaluate the arguments and call “ESDTUnsetRole@tokenId@listOfRoles” for the given address. + /// This will be actually a cross shard call. + /// This function as almost all in case of ESDT can be called only by the owner. + pub fn unset_special_roles>( + self, + address: &ManagedAddress, + token_identifier: &TokenIdentifier, + roles_iter: RoleIter, + ) -> TxTypedCall { + let mut tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call("unSetSpecialRole") + .argument(token_identifier) + .argument(address); + for role in roles_iter { + if role != EsdtLocalRole::None { + tx = tx.argument(&role.as_role_name()); + } + } + + tx.original_result() + } + + pub fn transfer_ownership( + self, + token_identifier: &TokenIdentifier, + new_owner: &ManagedAddress, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transferOwnership") + .argument(token_identifier) + .argument(new_owner) + .original_result() + } + + pub fn transfer_nft_create_role( + self, + token_identifier: &TokenIdentifier, + old_creator: &ManagedAddress, + new_creator: &ManagedAddress, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transferNFTCreateRole") + .argument(token_identifier) + .argument(old_creator) + .argument(new_creator) + .original_result() + } + + pub fn control_changes( + self, + token_identifier: &TokenIdentifier, + property_arguments: &TokenPropertyArguments, + ) -> TxTypedCall { + let mut tx = self + .wrapped_tx + .payment(NotPayable) + .raw_call("controlChanges") + .argument(token_identifier); + append_token_property_arguments(&mut tx.data, property_arguments); + tx.original_result() + } +} + +const TRUE_STR: &str = "true"; +const FALSE_STR: &str = "false"; + +fn bool_name_bytes(b: bool) -> &'static str { + if b { + TRUE_STR + } else { + FALSE_STR + } +} + +fn set_token_property(contract_call: &mut FunctionCall, name: &str, value: bool) +where + Api: CallTypeApi, +{ + contract_call.arg_buffer.push_multi_arg(&name); + contract_call + .arg_buffer + .push_multi_arg(&bool_name_bytes(value)); +} + +fn append_token_property_arguments( + contract_call: &mut FunctionCall, + token_prop_args: &TokenPropertyArguments, +) where + Api: CallTypeApi, +{ + if let Some(can_freeze) = token_prop_args.can_freeze { + set_token_property(contract_call, "canFreeze", can_freeze); + } + + if let Some(can_wipe) = token_prop_args.can_wipe { + set_token_property(contract_call, "canWipe", can_wipe); + } + + if let Some(can_pause) = token_prop_args.can_pause { + set_token_property(contract_call, "canPause", can_pause); + } + + if let Some(can_transfer_create_role) = token_prop_args.can_transfer_create_role { + set_token_property( + contract_call, + "canTransferNFTCreateRole", + can_transfer_create_role, + ); + } + + if let Some(can_mint) = token_prop_args.can_mint { + set_token_property(contract_call, "canMint", can_mint); + } + + if let Some(can_burn) = token_prop_args.can_burn { + set_token_property(contract_call, "canBurn", can_burn); + } + + if let Some(can_change_owner) = token_prop_args.can_change_owner { + set_token_property(contract_call, "canChangeOwner", can_change_owner); + } + + if let Some(can_upgrade) = token_prop_args.can_upgrade { + set_token_property(contract_call, "canUpgrade", can_upgrade); + } + + if let Some(can_add_special_roles) = token_prop_args.can_add_special_roles { + set_token_property(contract_call, "canAddSpecialRoles", can_add_special_roles); + } +} diff --git a/framework/base/src/esdt/system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs similarity index 97% rename from framework/base/src/esdt/system_sc_proxy.rs rename to framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs index 62182eeb1a..6f74b80812 100644 --- a/framework/base/src/esdt/system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/legacy_system_sc_proxy.rs @@ -1,20 +1,16 @@ use core::marker::PhantomData; -use super::properties::*; -use hex_literal::hex; +// use super::properties::*; use crate::{ api::{CallTypeApi, SendApi}, types::{ - BigUint, ContractCall, ContractCallNoPayment, ContractCallWithEgld, EsdtLocalRole, - EsdtTokenType, ManagedAddress, ManagedBuffer, TokenIdentifier, + BigUint, ContractCall, ContractCallNoPayment, ContractCallWithEgld, ESDTSystemSCAddress, + EsdtLocalRole, EsdtTokenType, ManagedAddress, ManagedBuffer, TokenIdentifier, }, }; -/// Address of the system smart contract that manages ESDT. -/// Bech32: erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u -pub const ESDT_SYSTEM_SC_ADDRESS_ARRAY: [u8; 32] = - hex!("000000000000000000010000000000000000000000000000000000000002ffff"); +use super::token_properties::*; const ISSUE_FUNGIBLE_ENDPOINT_NAME: &str = "issue"; const ISSUE_NON_FUNGIBLE_ENDPOINT_NAME: &str = "issueNonFungible"; @@ -25,6 +21,10 @@ const ISSUE_AND_SET_ALL_ROLES_ENDPOINT_NAME: &str = "registerAndSetAllRoles"; /// Proxy for the ESDT system smart contract. /// Unlike other contract proxies, this one has a fixed address, /// so the proxy object doesn't really contain any data, it is more of a placeholder. +#[deprecated( + since = "0.49.0", + note = "There is a new `ESDTSystemSCProxy`, which uses the new proxy model." +)] pub struct ESDTSystemSmartContractProxy where SA: SendApi + 'static, @@ -470,7 +470,7 @@ where } pub fn esdt_system_sc_address(&self) -> ManagedAddress { - ManagedAddress::new_from_bytes(&ESDT_SYSTEM_SC_ADDRESS_ARRAY) + ESDTSystemSCAddress.to_managed_address() } fn esdt_system_sc_call_no_args( diff --git a/framework/base/src/esdt/properties.rs b/framework/base/src/types/interaction/system_proxy/token_properties.rs similarity index 100% rename from framework/base/src/esdt/properties.rs rename to framework/base/src/types/interaction/system_proxy/token_properties.rs diff --git a/framework/base/src/types/interaction/tx.rs b/framework/base/src/types/interaction/tx.rs new file mode 100644 index 0000000000..905b9af8fc --- /dev/null +++ b/framework/base/src/types/interaction/tx.rs @@ -0,0 +1,1007 @@ +use crate::{ + api::CallTypeApi, + types::{ + heap::H256, BigUint, CodeMetadata, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, + EgldOrEsdtTokenPaymentRefs, EgldOrMultiEsdtPayment, EsdtTokenPayment, EsdtTokenPaymentRefs, + ManagedAddress, ManagedBuffer, ManagedOption, ManagedVec, MultiEsdtPayment, + TokenIdentifier, + }, +}; + +use multiversx_sc_codec::TopEncodeMulti; + +use super::{ + AnnotatedValue, Code, ContractCallBase, ContractCallNoPayment, ContractCallWithEgld, + ContractDeploy, DeployCall, Egld, EgldPayment, ExplicitGas, FromSource, FunctionCall, + ManagedArgBuffer, OriginalResultMarker, RHList, RHListAppendNoRet, RHListAppendRet, RHListItem, + TxCodeSource, TxCodeValue, TxData, TxDataFunctionCall, TxEgldValue, TxEnv, + TxEnvMockDeployAddress, TxEnvWithTxHash, TxFrom, TxFromSourceValue, TxFromSpecified, TxGas, + TxGasValue, TxPayment, TxPaymentEgldOnly, TxProxyTrait, TxResultHandler, TxScEnv, TxTo, + TxToSpecified, UpgradeCall, UNSPECIFIED_GAS_LIMIT, +}; + +/// Universal representation of a blockchain transaction. +/// +/// Uses 7 generic type arguments to encode all aspects of the transaction. +/// +/// It is future-like, does nothing by itself, it needs a specialized method call to actually run or send it. +/// +/// Rationale: https://twitter.com/andreimmarinica/status/1777157322155966601 +#[must_use] +pub struct Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPayment, + Gas: TxGas, + Data: TxData, + RH: TxResultHandler, +{ + pub env: Env, + pub from: From, + pub to: To, + pub payment: Payment, + pub gas: Gas, + pub data: Data, + pub result_handler: RH, +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPayment, + Gas: TxGas, + Data: TxDataFunctionCall, + RH: TxResultHandler, +{ + /// Converts object to a MultiversX transaction data field string. + pub fn to_call_data_string(&self) -> ManagedBuffer { + self.data.to_call_data_string() + } +} + +pub type TxBaseWithEnv = Tx; + +impl TxBaseWithEnv +where + Env: TxEnv, +{ + /// Constructor, needs to take an environment object. + #[inline] + pub fn new_with_env(env: Env) -> Self { + Tx { + env, + from: (), + to: (), + payment: (), + gas: (), + data: (), + result_handler: (), + } + } +} + +impl Tx +where + Env: TxEnv, + To: TxTo, + Payment: TxPayment, + Gas: TxGas, + Data: TxData, + RH: TxResultHandler, +{ + /// Specifies transaction sender. + pub fn from(self, from: From) -> Tx + where + From: TxFrom, + { + Tx { + env: self.env, + from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data, + result_handler: self.result_handler, + } + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + Payment: TxPayment, + Gas: TxGas, + Data: TxData, + RH: TxResultHandler, +{ + /// Specifies the recipient of the transaction. + /// + /// Allows argument to also be `()`. + pub fn to(self, to: To) -> Tx + where + To: TxTo, + { + Tx { + env: self.env, + from: self.from, + to, + payment: self.payment, + gas: self.gas, + data: self.data, + result_handler: self.result_handler, + } + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, + Data: TxData, + RH: TxResultHandler, +{ + /// Adds any payment to a transaction, if no payment has been added before. + pub fn payment(self, payment: Payment) -> Tx + where + Payment: TxPayment, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment, + gas: self.gas, + data: self.data, + result_handler: self.result_handler, + } + } + + /// Adds EGLD value to a transaction. + /// + /// Accepts any type that can represent and EGLD amount: BigUint, &BigUint, etc. + pub fn egld( + self, + egld_value: EgldValue, + ) -> Tx, Gas, Data, RH> + where + EgldValue: TxEgldValue, + { + self.payment(Egld(egld_value)) + } + + /// Backwards compatibility. Use method `egld` instead. + pub fn with_egld_transfer( + self, + egld_amount: BigUint, + ) -> Tx, Gas, Data, RH> { + self.egld(egld_amount) + } + + /// Adds the first single, owned ESDT token payment to a transaction. + /// + /// Since this is the first ESDT payment, a single payment tx is produced. + /// + /// Can subsequently be called again for multiple payments. + pub fn esdt>>( + self, + payment: P, + ) -> Tx, Gas, Data, RH> { + self.payment(payment.into()) + } + + /// Sets a single token payment, with the token identifier and amount kept as references. + /// + /// This is handy whem we only want one ESDT transfer and we want to avoid unnecessary object clones. + pub fn single_esdt<'a>( + self, + token_identifier: &'a TokenIdentifier, + token_nonce: u64, + amount: &'a BigUint, + ) -> Tx, Gas, Data, RH> { + self.payment(EsdtTokenPaymentRefs { + token_identifier, + token_nonce, + amount, + }) + } + + /// Syntactic sugar for `self.payment(EgldOrEsdtTokenPaymentRefs::new(...)`. Takes references. + pub fn egld_or_single_esdt<'a>( + self, + token_identifier: &'a EgldOrEsdtTokenIdentifier, + token_nonce: u64, + amount: &'a BigUint, + ) -> Tx, Gas, Data, RH> { + self.payment(EgldOrEsdtTokenPaymentRefs::new( + token_identifier, + token_nonce, + amount, + )) + } + + /// Sets a collection of ESDT transfers as the payment of the transaction. + /// + /// Can be formed from single ESDT payments, but the result will always be a collection. + /// + /// Always converts the argument into an owned collection of ESDT payments. For work with references, use `.payment(&p)` instead. + pub fn multi_esdt( + self, + payments: IntoMulti, + ) -> Tx, Gas, Data, RH> + where + IntoMulti: Into>, + { + self.payment(payments.into()) + } + + /// Backwards compatibility. + pub fn with_esdt_transfer>>( + self, + payment: P, + ) -> Tx, Gas, Data, RH> { + self.payment(MultiEsdtPayment::new()) + .with_esdt_transfer(payment) + } + + /// Backwards compatibility. + pub fn with_multi_token_transfer( + self, + payments: MultiEsdtPayment, + ) -> Tx, Gas, Data, RH> { + self.multi_esdt(payments) + } + + /// Backwards compatibility. + pub fn with_egld_or_single_esdt_transfer>>( + self, + payment: P, + ) -> Tx, Gas, Data, RH> { + self.payment(payment.into()) + } + + /// Converts argument to `EgldOrMultiEsdtPayment`, then sets it as payment. + /// + /// In most cases, `payment` should be used instead. + pub fn egld_or_multi_esdt>>( + self, + payment: P, + ) -> Tx, Gas, Data, RH> { + self.payment(payment.into()) + } +} + +impl Tx, Gas, Data, RH> +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, + Data: TxData, + RH: TxResultHandler, +{ + /// Adds the second ESDT token transfer to a contract call. + /// + /// Can be called multiple times on the same call. + /// + /// When the Tx already contains a single (owned) ESDT payment, + /// adding the second one will convert it to a list. + pub fn esdt>>( + self, + payment: P, + ) -> Tx, Gas, Data, RH> { + let mut payments = ManagedVec::new(); + payments.push(self.payment); + payments.push(payment.into()); + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: payments, + gas: self.gas, + data: self.data, + result_handler: self.result_handler, + } + } +} + +impl Tx, Gas, Data, RH> +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, + Data: TxData, + RH: TxResultHandler, +{ + /// Adds a single ESDT token transfer to a contract call. + /// + /// Can be called multiple times on the same call. + pub fn esdt>>( + mut self, + payment: P, + ) -> Tx, Gas, Data, RH> { + self.payment.push(payment.into()); + self + } + + /// When the Tx already contains an owned collection of ESDT payments, + /// calling `multi_esdt` is equivalent to `esdt`, it just adds another payment to the list. + /// + /// Can be called multiple times. + pub fn multi_esdt>>( + self, + payment: P, + ) -> Tx, Gas, Data, RH> { + self.esdt(payment) + } + + /// Backwards compatibility. + pub fn with_esdt_transfer>>( + self, + payment: P, + ) -> Tx, Gas, Data, RH> { + self.multi_esdt(payment) + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPayment, + Data: TxData, + RH: TxResultHandler, +{ + /// Sets an explicit gas limit to the call. + #[inline] + pub fn gas( + self, + gas_value: GasValue, + ) -> Tx, Data, RH> + where + GasValue: TxGasValue, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: ExplicitGas(gas_value), + data: self.data, + result_handler: self.result_handler, + } + } + + /// Backwards compatibility. + #[inline] + pub fn with_gas_limit( + self, + gas_limit: u64, + ) -> Tx, Data, RH> { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: ExplicitGas(gas_limit), + data: self.data, + result_handler: self.result_handler, + } + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPayment, + Gas: TxGas, + RH: TxResultHandler, +{ + /// Sets the data field. Do not use directly. + #[inline] + #[doc(hidden)] + pub fn raw_data(self, data: Data) -> Tx + where + Data: TxData, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data, + result_handler: self.result_handler, + } + } + + /// Starts a contract call, serialized by hand. + /// + /// Whenever possible, should use proxies instead, since manual serialization is not type-safe. + #[inline] + pub fn raw_call>>( + self, + function_name: N, + ) -> Tx, RH> { + self.raw_data(FunctionCall::new(function_name)) + } +} + +impl Tx, RH> +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPayment, + Gas: TxGas, + RH: TxResultHandler, +{ + /// Converts tx to a simple FunctionCall, to be used as argument or data in contracts. + pub fn into_function_call(self) -> FunctionCall { + self.data + } +} + +impl Tx, RH> +where + Env: TxEnv, + From: TxFrom, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, + RH: TxResultHandler, +{ + /// Produces the normalized function call, i.e. with builtin function calls for ESDT transfers. + /// + /// The resulting transaction can differ from the input in several ways: + /// - the recipient is changed (some builtin functions are called with recipient = sender), + /// - the function call becomes a builtin function call. + /// + /// ## Important + /// + /// Do not call this before sending transactions! Normalization is don automatically whenever necessary. + /// Only use when you need the normalized data, e.g. for a multisig. + /// + /// ## Warning + /// + /// To produce owned values, some clones are performed. + /// It is not optimized for contracts, but can be used nonetheless. + #[allow(clippy::type_complexity)] + pub fn normalize( + self, + ) -> Tx< + Env, + From, + ManagedAddress, + EgldPayment, + Gas, + FunctionCall, + RH, + > { + let (norm_to, norm_egld, norm_fc) = self.payment.with_normalized( + &self.env, + &self.from, + self.to, + self.data, + |norm_to, norm_egld, norm_fc| (norm_to.clone(), norm_egld.clone(), norm_fc), + ); + + Tx { + env: self.env, + from: self.from, + to: norm_to, + payment: Egld(norm_egld), + gas: self.gas, + data: norm_fc, + result_handler: self.result_handler, + } + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + Payment: TxPayment, + Gas: TxGas, +{ + /// Merges the argument data into the current tx. + /// Used for function calls originating in legacy proxies. + /// + /// Different environment in the argument allowed because of compatibility with old proxies. + /// + /// Method still subject to considerable change. + pub fn legacy_proxy_call( + self, + call: Tx, OriginalResultMarker>, + ) -> Tx, OriginalResultMarker> + where + Env2: TxEnv, + To: TxTo + TxTo, + { + Tx { + env: self.env, + from: self.from, + to: call.to, + payment: self.payment, + gas: self.gas, + data: call.data, + result_handler: call.result_handler, + } + } +} + +impl Tx, RH> +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPayment, + Gas: TxGas, + RH: TxResultHandler, +{ + /// Adds argument to function call. + /// + /// Whenever possible, use proxies instead. + /// + /// It serializes the value, but does not enforce type safety. + #[inline] + pub fn argument(mut self, arg: &T) -> Self { + self.data = self.data.argument(arg); + self + } + + /// Adds serialized argument to function call. + /// + /// Whenever possible, use proxies instead. + /// + /// Doesa not serialize, does not enforce type safety. + #[inline] + pub fn arguments_raw(mut self, raw: ManagedArgBuffer) -> Self { + self.data.arg_buffer = raw; + self + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPayment, + Gas: TxGas, + Data: TxData, +{ + /// Type marker to set the original contract or VM function return type. + /// + /// Only the compile-time type annotation is given. + #[inline] + pub fn original_result( + self, + ) -> Tx> { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data, + result_handler: OriginalResultMarker::new(), + } + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + /// Starts a proxy call, deploy, or upgrade. + /// + /// The proxy object will be given, the subsequent call will be from a proxy context, containing all the contract endpoint names. + pub fn typed(self, proxy: Proxy) -> Proxy::TxProxyMethods + where + Proxy: TxProxyTrait, + { + proxy.proxy_methods(self) + } +} + +impl + Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPayment, + Gas: TxGas, + Data: TxData, + ResultList: RHList, +{ + /// Adds a result handler that doesn't return anything. + #[inline] + pub fn with_result( + self, + result_handler: ResultHandler, + ) -> Tx + where + ResultHandler: RHListItem, + ResultList: RHListAppendNoRet, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data, + result_handler: self.result_handler.append_no_ret(result_handler), + } + } + + /// Adds a result handler that can also return processed data. + #[inline] + pub fn returns( + self, + item: RH, + ) -> Tx + where + RH: RHListItem, + ResultList: RHListAppendRet, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data, + result_handler: self.result_handler.append_ret(item), + } + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPaymentEgldOnly, + Gas: TxGas, + RH: TxResultHandler, +{ + /// Starts a contract deploy call, serialized by hand. + /// + /// Whenever possible, should use proxies instead, since manual serialization is not type-safe. + pub fn raw_deploy(self) -> Tx, RH> { + self.raw_data(DeployCall::default()) + } +} + +impl Tx, RH> +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPaymentEgldOnly, + Gas: TxGas, + RH: TxResultHandler, +{ + /// Sets upgrade code source as explicit code bytes. + pub fn code( + self, + code: CodeValue, + ) -> Tx>, RH> + where + CodeValue: TxCodeValue, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data.code_source(Code(code)), + result_handler: self.result_handler, + } + } + + /// Sets upgrade code source as another deployed contract code. + pub fn from_source( + self, + source_address: FromSourceValue, + ) -> Tx>, RH> + where + FromSourceValue: TxFromSourceValue, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data.code_source(FromSource(source_address)), + result_handler: self.result_handler, + } + } +} + +impl Tx, RH> +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPaymentEgldOnly, + Gas: TxGas, + RH: TxResultHandler, +{ + /// Sets deploy code source as explicit code bytes. + pub fn code( + self, + code: CodeValue, + ) -> Tx>, RH> + where + CodeValue: TxCodeValue, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data.code_source(Code(code)), + result_handler: self.result_handler, + } + } + + /// Sets deploy code source as another deployed contract code. + pub fn from_source( + self, + source_address: FromSourceValue, + ) -> Tx>, RH> + where + FromSourceValue: TxFromSourceValue, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data.code_source(FromSource(source_address)), + result_handler: self.result_handler, + } + } +} + +impl + Tx, RH> +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPaymentEgldOnly, + Gas: TxGas, + CodeSource: TxCodeSource, + RH: TxResultHandler, +{ + /// Sets code metadata to deploy. + pub fn code_metadata(mut self, code_metadata: CodeMetadata) -> Self { + self.data = self.data.code_metadata(code_metadata); + self + } + + /// Adds argument to a contract deploy. + /// + /// Whenever possible, use proxies instead. + /// + /// It serializes the value, but does not enforce type safety. + #[inline] + pub fn argument(mut self, arg: &T) -> Self { + self.data = self.data.argument(arg); + self + } + + /// Adds serialized argument to a contract deploy. + /// + /// Whenever possible, use proxies instead. + /// + /// Does not serialize, does not enforce type safety. + #[inline] + pub fn arguments_raw(mut self, raw: ManagedArgBuffer) -> Self { + self.data.arg_buffer = raw; + self + } +} + +impl + Tx, RH> +where + Env: TxEnvMockDeployAddress, + From: TxFromSpecified, + To: TxTo, + Payment: TxPaymentEgldOnly, + Gas: TxGas, + CodeSource: TxCodeSource, + RH: TxResultHandler, +{ + /// Sets the new mock address to be used for the newly deployed contract. + /// + /// Only allowed in tests. + pub fn new_address(mut self, new_address: NA) -> Self + where + NA: AnnotatedValue>, + { + self.env.mock_deploy_new_address(&self.from, new_address); + self + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPaymentEgldOnly, + Gas: TxGas, + RH: TxResultHandler, +{ + /// Starts a contract deploy upgrade, serialized by hand. + /// + /// Whenever possible, should use proxies instead, since manual serialization is not type-safe. + pub fn raw_upgrade(self) -> Tx, RH> { + self.raw_data(UpgradeCall::default()) + } +} + +impl + Tx, RH> +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPaymentEgldOnly, + Gas: TxGas, + CodeSource: TxCodeSource, + RH: TxResultHandler, +{ + pub fn code_metadata(mut self, code_metadata: CodeMetadata) -> Self { + self.data = self.data.code_metadata(code_metadata); + self + } + + /// Adds argument to upgrade call. + /// + /// Whenever possible, use proxies instead. + /// + /// It serializes the value, but does not enforce type safety. + #[inline] + pub fn argument(mut self, arg: &T) -> Self { + self.data = self.data.argument(arg); + self + } + + /// Adds serialized argument to an upgrade call. + /// + /// Whenever possible, use proxies instead. + /// + /// Doesa not serialize, does not enforce type safety. + #[inline] + pub fn arguments_raw(mut self, raw: ManagedArgBuffer) -> Self { + self.data.arg_buffer = raw; + self + } +} + +impl Tx +where + Env: TxEnvWithTxHash, + From: TxFromSpecified, + To: TxTo, + Payment: TxPaymentEgldOnly, + Gas: TxGas, + Data: TxDataFunctionCall, + RH: TxResultHandler, +{ + /// Sets the mock transaction hash to be used in a test. + /// + /// Only allowed in tests. + pub fn tx_hash(mut self, tx_hash: H) -> Self + where + H256: core::convert::From, + { + self.env.set_tx_hash(H256::from(tx_hash)); + self + } +} + +impl + From< + Tx< + TxScEnv, + (), + To, + Payment, + (), + DeployCall, ()>, + OriginalResultMarker, + >, + > for ContractDeploy +where + Api: CallTypeApi + 'static, + To: TxTo>, + Payment: TxPaymentEgldOnly>, + OriginalResult: TopEncodeMulti, +{ + fn from( + value: Tx< + TxScEnv, + (), + To, + Payment, + (), + DeployCall, ()>, + OriginalResultMarker, + >, + ) -> Self { + ContractDeploy { + _phantom: core::marker::PhantomData, + to: ManagedOption::none(), + egld_payment: value.payment.into_egld_payment(&value.env), + explicit_gas_limit: UNSPECIFIED_GAS_LIMIT, + arg_buffer: value.data.arg_buffer, + _return_type: core::marker::PhantomData, + } + } +} + +// Conversion from new syntax to old syntax. +impl ContractCallBase + for Tx< + TxScEnv, + (), + To, + Payment, + (), + FunctionCall, + OriginalResultMarker, + > +where + Api: CallTypeApi + 'static, + To: TxToSpecified>, + Payment: TxPayment>, + OriginalResult: TopEncodeMulti, +{ + type OriginalResult = OriginalResult; + + fn into_normalized(self) -> ContractCallWithEgld { + self.payment.with_normalized( + &self.env, + &self.from, + self.to, + self.data, + |norm_to, norm_egld, norm_fc| ContractCallWithEgld { + basic: ContractCallNoPayment { + _phantom: core::marker::PhantomData, + to: norm_to.clone(), + function_call: norm_fc.clone(), + explicit_gas_limit: UNSPECIFIED_GAS_LIMIT, + _return_type: core::marker::PhantomData, + }, + egld_payment: norm_egld.clone(), + }, + ) + } +} diff --git a/framework/base/src/types/interaction/tx_data.rs b/framework/base/src/types/interaction/tx_data.rs new file mode 100644 index 0000000000..ddab631b1a --- /dev/null +++ b/framework/base/src/types/interaction/tx_data.rs @@ -0,0 +1,69 @@ +mod deploy_call; +mod function_call; +mod tx_code_source; +mod upgrade_call; + +pub use deploy_call::DeployCall; +pub use function_call::FunctionCall; +pub use tx_code_source::*; +pub use upgrade_call::UpgradeCall; + +use crate::{ + formatter::SCLowerHex, + types::{ManagedBuffer, ManagedBufferBuilder}, +}; + +use super::TxEnv; + +/// Marks the data field of a transaction in `Tx`. +/// +/// Can be nothing, deploy data, call data, etc. +pub trait TxData +where + Env: TxEnv, +{ + fn is_no_call(&self) -> bool; + + fn to_call_data_string(&self) -> ManagedBuffer; +} + +pub trait TxDataFunctionCall: TxData + Into> +where + Env: TxEnv, +{ +} + +impl TxData for () +where + Env: TxEnv, +{ + fn is_no_call(&self) -> bool { + true + } + + fn to_call_data_string(&self) -> ManagedBuffer { + ManagedBuffer::new() + } +} + +impl TxDataFunctionCall for () where Env: TxEnv {} + +impl TxData for FunctionCall +where + Env: TxEnv, +{ + fn is_no_call(&self) -> bool { + self.is_empty() + } + + fn to_call_data_string(&self) -> ManagedBuffer { + let mut result = ManagedBufferBuilder::default(); + result.append_managed_buffer(&self.function_name); + for arg in self.arg_buffer.raw_arg_iter() { + result.append_bytes(b"@"); + SCLowerHex::fmt(&*arg, &mut result); + } + result.into_managed_buffer() + } +} +impl TxDataFunctionCall for FunctionCall where Env: TxEnv {} diff --git a/framework/base/src/types/interaction/tx_data/deploy_call.rs b/framework/base/src/types/interaction/tx_data/deploy_call.rs new file mode 100644 index 0000000000..a742901736 --- /dev/null +++ b/framework/base/src/types/interaction/tx_data/deploy_call.rs @@ -0,0 +1,90 @@ +use multiversx_sc_codec::TopEncodeMulti; + +use crate::types::{CodeMetadata, ManagedArgBuffer, ManagedBuffer, ManagedBufferCachedBuilder}; + +use super::{TxCodeSource, TxData, TxEnv}; + +/// Holds deploy data: code, code metadata, and arguments. +pub struct DeployCall +where + Env: TxEnv, + CodeSource: TxCodeSource, +{ + pub code_source: CodeSource, + pub code_metadata: CodeMetadata, + pub arg_buffer: ManagedArgBuffer, +} + +impl Default for DeployCall +where + Env: TxEnv, +{ + fn default() -> DeployCall { + DeployCall { + code_source: (), + code_metadata: CodeMetadata::DEFAULT, + arg_buffer: ManagedArgBuffer::new(), + } + } +} + +impl TxData for DeployCall +where + Env: TxEnv, + CodeSource: TxCodeSource, +{ + fn is_no_call(&self) -> bool { + false + } + + fn to_call_data_string(&self) -> ManagedBuffer { + // Implement as needed for deployment-specific data + let result = ManagedBufferCachedBuilder::default(); + // result.append_managed_buffer(&self.code); + // Add other fields as needed + result.into_managed_buffer() + } +} + +impl DeployCall +where + Env: TxEnv, +{ + pub fn code_source(self, code_source: CodeSource) -> DeployCall + where + CodeSource: TxCodeSource, + { + DeployCall { + code_source, + code_metadata: self.code_metadata, + arg_buffer: self.arg_buffer, + } + } +} + +impl DeployCall +where + Env: TxEnv, + CodeSource: TxCodeSource, +{ + pub fn code_metadata(mut self, code_metadata: CodeMetadata) -> Self + where + CodeSource: TxCodeSource, + { + self.code_metadata = code_metadata; + self + } + + /// Adds an argument of any serializable type. + /// + /// Multi-values are accepted. No type checking performed. + pub fn argument(mut self, arg: &T) -> Self { + self.arg_buffer.push_multi_arg(arg); + self + } + + pub fn arguments_raw(mut self, raw: ManagedArgBuffer) -> Self { + self.arg_buffer = raw; + self + } +} diff --git a/framework/base/src/types/interaction/function_call.rs b/framework/base/src/types/interaction/tx_data/function_call.rs similarity index 75% rename from framework/base/src/types/interaction/function_call.rs rename to framework/base/src/types/interaction/tx_data/function_call.rs index a2140f14fa..7ebf20dd1a 100644 --- a/framework/base/src/types/interaction/function_call.rs +++ b/framework/base/src/types/interaction/tx_data/function_call.rs @@ -4,23 +4,21 @@ use multiversx_sc_codec::{ }; use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ - ManagedTypeApi, ESDT_MULTI_TRANSFER_FUNC_NAME, ESDT_NFT_TRANSFER_FUNC_NAME, + CallTypeApi, ManagedTypeApi, ESDT_MULTI_TRANSFER_FUNC_NAME, ESDT_NFT_TRANSFER_FUNC_NAME, ESDT_TRANSFER_FUNC_NAME, }, - formatter::SCLowerHex, types::{ - EsdtTokenPayment, ManagedAddress, ManagedBuffer, ManagedBufferCachedBuilder, ManagedVec, - MultiValueEncoded, + ContractCallNoPayment, EsdtTokenPayment, EsdtTokenPaymentRefs, ManagedAddress, + ManagedArgBuffer, ManagedBuffer, ManagedVec, MultiValueEncoded, TypedFunctionCall, }, }; -use super::ManagedArgBuffer; - /// Encodes a function call on the blockchain, composed of a function name and its encoded arguments. /// /// Can be used as a multi-argument, to embed a call within a call. +#[derive(Clone)] pub struct FunctionCall where Api: ManagedTypeApi, @@ -63,14 +61,34 @@ where self } - pub fn to_call_data_string(&self) -> ManagedBuffer { - let mut result = ManagedBufferCachedBuilder::default(); - result.append_managed_buffer(&self.function_name); - for arg in self.arg_buffer.raw_arg_iter() { - result.append_bytes(b"@"); - SCLowerHex::fmt(&*arg, &mut result); - } - result.into_managed_buffer() + pub fn arguments_raw(mut self, raw: ManagedArgBuffer) -> Self { + self.arg_buffer = raw; + self + } + + pub fn typed_result(self) -> TypedFunctionCall + where + R: TopEncodeMulti + TopDecodeMulti, + { + self.into() + } +} + +impl From<()> for FunctionCall +where + Api: ManagedTypeApi, +{ + fn from(_: ()) -> Self { + FunctionCall::empty() + } +} + +impl From> for FunctionCall +where + Api: CallTypeApi, +{ + fn from(ccnp: ContractCallNoPayment) -> Self { + ccnp.function_call } } @@ -118,14 +136,22 @@ where } } +impl TypeAbiFrom for FunctionCall where Api: ManagedTypeApi {} + impl TypeAbi for FunctionCall where Api: ManagedTypeApi, { + type Unmanaged = Self; + fn type_name() -> TypeName { crate::abi::type_name_variadic::>() } + fn type_name_rust() -> TypeName { + "FunctionCall<$API>".into() + } + fn is_variadic() -> bool { true } @@ -136,9 +162,9 @@ where Api: ManagedTypeApi, { /// Constructs `ESDTTransfer` builtin function call. - pub(super) fn convert_to_single_transfer_fungible_call( + pub(crate) fn convert_to_single_transfer_fungible_call( self, - payment: EsdtTokenPayment, + payment: EsdtTokenPaymentRefs<'_, Api>, ) -> FunctionCall { FunctionCall::new(ESDT_TRANSFER_FUNC_NAME) .argument(&payment.token_identifier) @@ -153,10 +179,10 @@ where /// arg1 - nonce /// arg2 - quantity to transfer /// arg3 - destination address - pub(super) fn convert_to_single_transfer_nft_call( + pub(crate) fn convert_to_single_transfer_nft_call( self, to: &ManagedAddress, - payment: EsdtTokenPayment, + payment: EsdtTokenPaymentRefs<'_, Api>, ) -> FunctionCall { FunctionCall::new(ESDT_NFT_TRANSFER_FUNC_NAME) .argument(&payment.token_identifier) @@ -167,16 +193,16 @@ where } /// Constructs `MultiESDTNFTTransfer` builtin function call. - pub(super) fn convert_to_multi_transfer_esdt_call( + pub(crate) fn convert_to_multi_transfer_esdt_call( self, to: &ManagedAddress, - payments: ManagedVec>, + payments: &ManagedVec>, ) -> FunctionCall { let mut result = FunctionCall::new(ESDT_MULTI_TRANSFER_FUNC_NAME) .argument(&to) .argument(&payments.len()); - for payment in payments.into_iter() { + for payment in payments { result = result .argument(&payment.token_identifier) .argument(&payment.token_nonce) diff --git a/framework/base/src/types/interaction/tx_data/tx_code_source.rs b/framework/base/src/types/interaction/tx_data/tx_code_source.rs new file mode 100644 index 0000000000..0d3c180e16 --- /dev/null +++ b/framework/base/src/types/interaction/tx_data/tx_code_source.rs @@ -0,0 +1,75 @@ +use crate::types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv}; + +pub trait TxCodeSource +where + Env: TxEnv, +{ +} + +impl TxCodeSource for () where Env: TxEnv {} + +pub trait TxCodeSourceSpecified: TxCodeSource +where + Env: TxEnv, +{ +} + +#[diagnostic::on_unimplemented( + message = "Type `{Self}` cannot be used as code (does not implement `TxCodeValue<{Env}>`)", + label = "not a valid smart contract byte code", + note = "there are multiple ways to specify SC byte code, but `{Self}` is not one of them" +)] +pub trait TxCodeValue: AnnotatedValue> +where + Env: TxEnv, +{ +} + +impl TxCodeValue for ManagedBuffer where Env: TxEnv {} + +/// Contains code for a deploy or upgrade. +pub struct Code(pub CodeValue); + +impl TxCodeSource for Code +where + Env: TxEnv, + CodeValue: TxCodeValue, +{ +} + +impl TxCodeSourceSpecified for Code +where + Env: TxEnv, + CodeValue: TxCodeValue, +{ +} + +#[diagnostic::on_unimplemented( + message = "Type `{Self}` cannot be used as code source value (does not implement `TxFromSourceValue<{Env}>`)", + label = "not an address from where to copy the code", + note = "there are multiple ways to specify a code source address, but `{Self}` is not one of them" +)] +pub trait TxFromSourceValue: AnnotatedValue> +where + Env: TxEnv, +{ +} + +impl TxFromSourceValue for ManagedAddress where Env: TxEnv {} + +/// Indicates the source of a "deploy from source" or "upgrade from source". +pub struct FromSource(pub FromSourceValue); + +impl TxCodeSource for FromSource +where + Env: TxEnv, + FromSourceValue: TxFromSourceValue, +{ +} + +impl TxCodeSourceSpecified for FromSource +where + Env: TxEnv, + FromSourceValue: TxFromSourceValue, +{ +} diff --git a/framework/base/src/types/interaction/tx_data/upgrade_call.rs b/framework/base/src/types/interaction/tx_data/upgrade_call.rs new file mode 100644 index 0000000000..591e8accb5 --- /dev/null +++ b/framework/base/src/types/interaction/tx_data/upgrade_call.rs @@ -0,0 +1,91 @@ +use multiversx_sc_codec::TopEncodeMulti; + +use crate::types::{ + CodeMetadata, ManagedArgBuffer, ManagedBuffer, ManagedBufferCachedBuilder, TxCodeSource, + TxData, TxEnv, +}; + +/// Holds deploy data: code, code metadata, and arguments. +pub struct UpgradeCall +where + Env: TxEnv, + CodeSource: TxCodeSource, +{ + pub code_source: CodeSource, + pub code_metadata: CodeMetadata, + pub arg_buffer: ManagedArgBuffer, +} + +impl Default for UpgradeCall +where + Env: TxEnv, +{ + fn default() -> UpgradeCall { + UpgradeCall { + code_source: (), + code_metadata: CodeMetadata::DEFAULT, + arg_buffer: ManagedArgBuffer::new(), + } + } +} + +impl TxData for UpgradeCall +where + Env: TxEnv, + CodeSource: TxCodeSource, +{ + fn is_no_call(&self) -> bool { + false + } + + fn to_call_data_string(&self) -> ManagedBuffer { + // Implement as needed for deployment-specific data + let result = ManagedBufferCachedBuilder::default(); + // result.append_managed_buffer(&self.code); + // Add other fields as needed + result.into_managed_buffer() + } +} + +impl UpgradeCall +where + Env: TxEnv, +{ + pub fn code_source(self, code_source: CodeSource) -> UpgradeCall + where + CodeSource: TxCodeSource, + { + UpgradeCall { + code_source, + code_metadata: self.code_metadata, + arg_buffer: self.arg_buffer, + } + } +} + +impl UpgradeCall +where + Env: TxEnv, + CodeSource: TxCodeSource, +{ + pub fn code_metadata(mut self, code_metadata: CodeMetadata) -> Self + where + CodeSource: TxCodeSource, + { + self.code_metadata = code_metadata; + self + } + + /// Adds an argument of any serializable type. + /// + /// Multi-values are accepted. No type checking performed. + pub fn argument(mut self, arg: &T) -> Self { + self.arg_buffer.push_multi_arg(arg); + self + } + + pub fn arguments_raw(mut self, raw: ManagedArgBuffer) -> Self { + self.arg_buffer = raw; + self + } +} diff --git a/framework/base/src/types/interaction/tx_env.rs b/framework/base/src/types/interaction/tx_env.rs new file mode 100644 index 0000000000..37e18d7dec --- /dev/null +++ b/framework/base/src/types/interaction/tx_env.rs @@ -0,0 +1,30 @@ +use crate::{ + api::CallTypeApi, + types::{heap::H256, ManagedAddress, ManagedBuffer}, +}; + +use super::{AnnotatedValue, TxFromSpecified}; + +pub trait TxEnv: Sized { + type Api: CallTypeApi; + + /// Type built by result handlers that translates into the "expect" section in scenarios. + type RHExpect: Default; + + fn resolve_sender_address(&self) -> ManagedAddress; + + fn default_gas_annotation(&self) -> ManagedBuffer; + + fn default_gas_value(&self) -> u64; +} + +pub trait TxEnvMockDeployAddress: TxEnv { + fn mock_deploy_new_address(&mut self, from: &From, new_address: NA) + where + From: TxFromSpecified, + NA: AnnotatedValue>; +} + +pub trait TxEnvWithTxHash: TxEnv { + fn set_tx_hash(&mut self, tx_hash: H256); +} diff --git a/framework/base/src/types/interaction/tx_exec.rs b/framework/base/src/types/interaction/tx_exec.rs new file mode 100644 index 0000000000..0c200df330 --- /dev/null +++ b/framework/base/src/types/interaction/tx_exec.rs @@ -0,0 +1,37 @@ +mod tx_env_sc; +mod tx_exec_async; +mod tx_exec_async_promises; +mod tx_exec_deploy; +mod tx_exec_sync; +mod tx_exec_te; +mod tx_exec_upgrade; + +pub use tx_env_sc::*; +pub use tx_exec_async::*; +pub use tx_exec_async_promises::*; +pub use tx_exec_deploy::*; +pub use tx_exec_sync::*; +use unwrap_infallible::UnwrapInfallible; + +use crate::{ + api::CallTypeApi, + io::{ArgErrorHandler, ArgId, ManagedResultArgLoader}, + types::{ManagedBuffer, ManagedVec}, +}; +use multiversx_sc_codec::TopDecodeMulti; + +/// In case of `transfer_execute`, we leave by default a little gas for the calling transaction to finish. +pub(crate) const TRANSFER_EXECUTE_DEFAULT_LEFTOVER: u64 = 100_000; + +pub(crate) fn decode_result( + raw_result: ManagedVec>, +) -> RequestedResult +where + SA: CallTypeApi + 'static, + RequestedResult: TopDecodeMulti, +{ + let mut loader = ManagedResultArgLoader::new(raw_result); + let arg_id = ArgId::from(&b"sync result"[..]); + let h: ArgErrorHandler = ArgErrorHandler::::from(arg_id); + RequestedResult::multi_decode_or_handle_err(&mut loader, h).unwrap_infallible() +} diff --git a/framework/base/src/types/interaction/tx_exec/tx_env_sc.rs b/framework/base/src/types/interaction/tx_exec/tx_env_sc.rs new file mode 100644 index 0000000000..249d74c2bc --- /dev/null +++ b/framework/base/src/types/interaction/tx_exec/tx_env_sc.rs @@ -0,0 +1,65 @@ +use core::marker::PhantomData; + +use crate::{ + api::{BlockchainApiImpl, CallTypeApi}, + contract_base::BlockchainWrapper, + types::{ + interaction::display_u64, ManagedAddress, ManagedBuffer, Tx, TxBaseWithEnv, TxEnv, + TRANSFER_EXECUTE_DEFAULT_LEFTOVER, + }, +}; + +/// The transaction environment used in calls launched from a SC. +/// +/// Contains no data, just a generic type for the (also zero-sized) API. +pub struct TxScEnv +where + Api: CallTypeApi, +{ + _phantom: PhantomData, +} + +impl Default for TxScEnv +where + Api: CallTypeApi, +{ + fn default() -> Self { + Self { + _phantom: PhantomData, + } + } +} + +impl TxBaseWithEnv> +where + Api: CallTypeApi, +{ + pub fn new_tx_from_sc() -> Self { + Tx::new_with_env(TxScEnv::default()) + } +} + +impl TxEnv for TxScEnv +where + Api: CallTypeApi, +{ + type Api = Api; + + type RHExpect = (); + + fn resolve_sender_address(&self) -> ManagedAddress { + BlockchainWrapper::::new().get_sc_address() + } + + fn default_gas_annotation(&self) -> ManagedBuffer { + display_u64(self.default_gas_value()) + } + + fn default_gas_value(&self) -> u64 { + let mut gas_left = Api::blockchain_api_impl().get_gas_left(); + if gas_left > TRANSFER_EXECUTE_DEFAULT_LEFTOVER { + gas_left -= TRANSFER_EXECUTE_DEFAULT_LEFTOVER; + } + gas_left + } +} diff --git a/framework/base/src/types/interaction/tx_exec/tx_exec_async.rs b/framework/base/src/types/interaction/tx_exec/tx_exec_async.rs new file mode 100644 index 0000000000..fbe098e559 --- /dev/null +++ b/framework/base/src/types/interaction/tx_exec/tx_exec_async.rs @@ -0,0 +1,176 @@ +use crate::{ + api::{CallTypeApi, StorageWriteApi}, + contract_base::SendRawWrapper, + types::{ + CallbackClosure, OriginalResultMarker, Tx, TxData, TxDataFunctionCall, + TxEmptyResultHandler, TxEnv, TxFrom, TxGas, TxPayment, TxResultHandler, TxScEnv, TxTo, + TxToSpecified, + }, +}; + +pub trait TxAsyncCallCallback: TxResultHandler> +where + Api: CallTypeApi, +{ + fn save_callback_closure_to_storage(&self); +} + +impl TxAsyncCallCallback for () +where + Api: CallTypeApi, +{ + fn save_callback_closure_to_storage(&self) {} +} + +impl TxAsyncCallCallback for OriginalResultMarker +where + Api: CallTypeApi, +{ + fn save_callback_closure_to_storage(&self) {} +} + +impl TxResultHandler> for CallbackClosure +where + Api: CallTypeApi, +{ + type OriginalResult = (); +} + +impl TxAsyncCallCallback for CallbackClosure +where + Api: CallTypeApi + StorageWriteApi, +{ + fn save_callback_closure_to_storage(&self) { + self.save_to_storage::(); + } +} + +impl TxResultHandler> for Option> +where + Api: CallTypeApi, +{ + type OriginalResult = (); +} + +impl TxAsyncCallCallback for Option> +where + Api: CallTypeApi + StorageWriteApi, +{ + fn save_callback_closure_to_storage(&self) { + if let Some(closure) = self { + closure.save_callback_closure_to_storage(); + } + } +} + +impl Tx, (), To, Payment, Gas, Data, EmptyRH> +where + Api: CallTypeApi, + To: TxTo>, + Payment: TxPayment>, + Gas: TxGas>, + Data: TxData>, + EmptyRH: TxEmptyResultHandler>, +{ + #[inline] + pub fn callback(self, callback: RH) -> Tx, (), To, Payment, Gas, Data, RH> + where + RH: TxAsyncCallCallback, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data, + result_handler: callback, + } + } +} + +impl Tx, (), To, Payment, Gas, FC, EmptyRH> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + Gas: TxGas>, + FC: TxDataFunctionCall>, + EmptyRH: TxEmptyResultHandler>, +{ + /// Backwards compatibility. + pub fn with_callback(self, callback: RH) -> Tx, (), To, Payment, Gas, FC, RH> + where + RH: TxAsyncCallCallback, + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data, + result_handler: callback, + } + } +} + +impl Tx, (), To, Payment, (), FC, RH> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + FC: TxDataFunctionCall>, + RH: TxAsyncCallCallback, +{ + pub fn async_call_and_exit(self) -> ! { + self.result_handler.save_callback_closure_to_storage(); + self.payment.with_normalized( + &self.env, + &self.from, + self.to, + self.data.into(), + |norm_to, norm_egld, norm_fc| { + SendRawWrapper::::new().async_call_raw( + norm_to, + norm_egld, + &norm_fc.function_name, + &norm_fc.arg_buffer, + ) + }, + ) + } + + pub fn call_and_exit(self) -> ! { + self.async_call_and_exit() + } +} + +impl Tx +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Payment: TxPayment, + Gas: TxGas, + Data: TxData, + RH: TxResultHandler, +{ + /// Backwards compatibility only. + #[deprecated( + since = "0.50.2", + note = "Backwards compatibility only, does nothing. Just delete. Use `async_call_and_exit` to launch asynchronous calls." + )] + #[inline] + pub fn async_call(self) -> Tx { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data, + result_handler: self.result_handler, + } + } +} diff --git a/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs b/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs new file mode 100644 index 0000000000..38e38fcbcd --- /dev/null +++ b/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs @@ -0,0 +1,271 @@ +use crate::{ + api::{const_handles, CallTypeApi}, + contract_base::{ErrorHelper, SendRawWrapper}, + types::{ + interaction::callback_closure::CallbackClosureWithGas, CallbackClosure, ExplicitGas, + FunctionCall, ManagedBuffer, ManagedType, OriginalResultMarker, Tx, TxGas, TxGasValue, + TxPayment, TxResultHandler, TxScEnv, TxToSpecified, + }, +}; + +pub trait TxPromisesCallback: TxResultHandler> +where + Api: CallTypeApi, +{ + fn callback_name(&self) -> &'static str; + + fn overwrite_with_serialized_args(&self, cb_closure_args_serialized: &mut ManagedBuffer); + + fn gas_for_callback(&self) -> u64; +} + +impl TxPromisesCallback for () +where + Api: CallTypeApi, +{ + fn callback_name(&self) -> &'static str { + "" + } + + fn overwrite_with_serialized_args(&self, cb_closure_args_serialized: &mut ManagedBuffer) { + cb_closure_args_serialized.overwrite(&[]); + } + + fn gas_for_callback(&self) -> u64 { + 0 + } +} + +impl TxPromisesCallback for OriginalResultMarker +where + Api: CallTypeApi, +{ + fn callback_name(&self) -> &'static str { + "" + } + + fn overwrite_with_serialized_args(&self, cb_closure_args_serialized: &mut ManagedBuffer) { + cb_closure_args_serialized.overwrite(&[]); + } + + fn gas_for_callback(&self) -> u64 { + 0 + } +} + +impl TxPromisesCallback for CallbackClosure +where + Api: CallTypeApi, +{ + fn callback_name(&self) -> &'static str { + self.callback_name + } + + fn overwrite_with_serialized_args(&self, cb_closure_args_serialized: &mut ManagedBuffer) { + self.closure_args + .serialize_overwrite(cb_closure_args_serialized); + } + + fn gas_for_callback(&self) -> u64 { + 0u64 + } +} + +impl TxResultHandler> for CallbackClosureWithGas +where + Api: CallTypeApi, +{ + type OriginalResult = (); +} + +impl TxPromisesCallback for CallbackClosureWithGas +where + Api: CallTypeApi, +{ + fn callback_name(&self) -> &'static str { + self.closure.callback_name + } + + fn overwrite_with_serialized_args(&self, cb_closure_args_serialized: &mut ManagedBuffer) { + self.closure + .closure_args + .serialize_overwrite(cb_closure_args_serialized); + } + + fn gas_for_callback(&self) -> u64 { + self.gas_for_callback + } +} + +impl + Tx, (), To, Payment, Gas, FunctionCall, CallbackClosure> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + Gas: TxGas>, +{ + pub fn gas_for_callback( + self, + gas: u64, + ) -> Tx, (), To, Payment, Gas, FunctionCall, CallbackClosureWithGas> + { + Tx { + env: self.env, + from: self.from, + to: self.to, + payment: self.payment, + gas: self.gas, + data: self.data, + result_handler: CallbackClosureWithGas { + closure: self.result_handler, + gas_for_callback: gas, + }, + } + } + + /// Backwards compatibility. + pub fn with_extra_gas_for_callback( + self, + gas: u64, + ) -> Tx, (), To, Payment, Gas, FunctionCall, CallbackClosureWithGas> + { + self.gas_for_callback(gas) + } +} + +impl + Tx, (), To, Payment, ExplicitGas, FunctionCall, Callback> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + GasValue: TxGasValue>, + Callback: TxPromisesCallback, +{ + /// Launches a transaction as an asynchronous promise (async v2 mechanism). + /// + /// Several such transactions can be launched from a single transaction. + /// + /// Must set: + /// - to + /// - gas + /// - a function call, ideally via a proxy. + /// + /// Value-only promises are not supported. + /// + /// Optionally, can add: + /// - any payment + /// - a promise callback, which also needs explicit gas for callback. + pub fn register_promise(self) { + let callback_name = self.result_handler.callback_name(); + let mut cb_closure_args_serialized = + ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); + self.result_handler + .overwrite_with_serialized_args(&mut cb_closure_args_serialized); + let extra_gas_for_callback = self.result_handler.gas_for_callback(); + let gas = self.gas.gas_value(&self.env); + + self.payment.with_normalized( + &self.env, + &self.from, + self.to, + self.data, + |norm_to, norm_egld, norm_fc| { + SendRawWrapper::::new().create_async_call_raw( + norm_to, + norm_egld, + &norm_fc.function_name, + &norm_fc.arg_buffer, + callback_name, + callback_name, + gas, + extra_gas_for_callback, + &cb_closure_args_serialized, + ) + }, + ) + } +} + +impl Tx, (), To, Payment, (), FunctionCall, Callback> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + Callback: TxPromisesCallback, +{ + /// ## Incorrect call + /// + /// Must set **gas** in order to call `register_promise`. + /// + /// ## Safety + /// + /// This version of the method must never be called. It is only here to provide a more readable error. + pub unsafe fn register_promise(self) { + ErrorHelper::::signal_error_with_message("register_promise requires explicit gas"); + } +} + +impl Tx, (), To, Payment, (), (), Callback> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + Callback: TxPromisesCallback, +{ + /// ## Incorrect call + /// + /// Must set **gas** and **function call** in order to call `register_promise`. + /// + /// ## Safety + /// + /// This version of the method must never be called. It is only here to provide a more readable error. + pub unsafe fn register_promise(self) { + ErrorHelper::::signal_error_with_message( + "register_promise requires explicit gas and function call", + ); + } +} + +impl + Tx, (), To, Payment, ExplicitGas, (), Callback> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + GasValue: TxGasValue>, + Callback: TxPromisesCallback, +{ + /// ## Incorrect call + /// + /// Must set **function call** in order to call `register_promise`. + /// + /// ## Safety + /// + /// This version of the method must never be called. It is only here to provide a more readable error. + pub unsafe fn register_promise(self) { + ErrorHelper::::signal_error_with_message("register_promise requires function call"); + } +} + +impl + Tx, (), To, Payment, Gas, FunctionCall, Callback> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + Gas: TxGas>, + Payment: TxPayment>, + Callback: TxPromisesCallback, +{ + /// Backwards compatibility only. + #[deprecated( + since = "0.50.2", + note = "Backwards compatibility only, does nothing. Just delete. Use `register_promise` to launch asynchronous calls." + )] + #[inline] + pub fn async_call_promise(self) -> Self { + self + } +} diff --git a/framework/base/src/types/interaction/tx_exec/tx_exec_deploy.rs b/framework/base/src/types/interaction/tx_exec/tx_exec_deploy.rs new file mode 100644 index 0000000000..ac93f909e8 --- /dev/null +++ b/framework/base/src/types/interaction/tx_exec/tx_exec_deploy.rs @@ -0,0 +1,283 @@ +use multiversx_sc_codec::{TopDecodeMulti, TopEncodeMulti}; + +use crate::{ + abi::TypeAbiFrom, + api::CallTypeApi, + contract_base::SendRawWrapper, + tuple_util::NestedTupleFlatten, + types::{ + decode_result, Code, CodeMetadata, DeployCall, FromSource, ManagedAddress, ManagedBuffer, + ManagedVec, OriginalResultMarker, RHListExec, Tx, TxCodeValue, TxFromSourceValue, TxGas, + TxPaymentEgldOnly, TxResultHandler, TxScEnv, + }, +}; + +pub struct DeployRawResult +where + Api: CallTypeApi, +{ + pub new_address: ManagedAddress, + pub raw_results: ManagedVec>, +} + +impl + Tx, (), (), Payment, Gas, DeployCall, Code>, RH> +where + Api: CallTypeApi, + Payment: TxPaymentEgldOnly>, + Gas: TxGas>, + CodeValue: TxCodeValue>, + RH: TxResultHandler>, +{ + fn execute_deploy_raw(self) -> (ManagedAddress, ManagedVec>, RH) { + let gas_limit = self.gas.gas_value(&self.env); + + let (new_address, raw_results) = self.payment.with_egld_value(&self.env, |egld_value| { + SendRawWrapper::::new().deploy_contract( + gas_limit, + egld_value, + &self.data.code_source.0.into_value(&self.env), + self.data.code_metadata, + &self.data.arg_buffer, + ) + }); + + SendRawWrapper::::new().clean_return_data(); + + (new_address, raw_results, self.result_handler) + } +} + +impl + Tx< + TxScEnv, + (), + (), + Payment, + Gas, + DeployCall, FromSource>, + RH, + > +where + Api: CallTypeApi, + Payment: TxPaymentEgldOnly>, + Gas: TxGas>, + FromSourceValue: TxFromSourceValue>, + RH: TxResultHandler>, +{ + fn execute_deploy_from_source_raw( + self, + ) -> (ManagedAddress, ManagedVec>, RH) { + let gas_limit = self.gas.gas_value(&self.env); + + let (new_address, raw_results) = self.payment.with_egld_value(&self.env, |egld_value| { + SendRawWrapper::::new().deploy_from_source_contract( + gas_limit, + egld_value, + &self.data.code_source.0.into_value(&self.env), + self.data.code_metadata, + &self.data.arg_buffer, + ) + }); + + SendRawWrapper::::new().clean_return_data(); + + (new_address, raw_results, self.result_handler) + } +} + +impl + Tx, (), (), Payment, Gas, DeployCall, Code>, RH> +where + Api: CallTypeApi, + Payment: TxPaymentEgldOnly>, + Gas: TxGas>, + CodeValue: TxCodeValue>, + RH: RHListExec, TxScEnv>, + RH::ListReturns: NestedTupleFlatten, +{ + /// Synchronously deploys a contract. + pub fn sync_call(self) -> ::Unpacked { + let (new_address, raw_results, result_handler) = self.execute_deploy_raw(); + + let deploy_raw_result = DeployRawResult { + new_address, + raw_results, + }; + let tuple_result = result_handler.list_process_result(&deploy_raw_result); + tuple_result.flatten_unpack() + } +} + +impl + Tx< + TxScEnv, + (), + (), + Payment, + Gas, + DeployCall, FromSource>, + RH, + > +where + Api: CallTypeApi, + Payment: TxPaymentEgldOnly>, + Gas: TxGas>, + FromSourceValue: TxFromSourceValue>, + RH: RHListExec, TxScEnv>, + RH::ListReturns: NestedTupleFlatten, +{ + /// Synchronously deploys a contract from source. + pub fn sync_call(self) -> ::Unpacked { + let (new_address, raw_results, result_handler) = self.execute_deploy_from_source_raw(); + + let deploy_raw_result = DeployRawResult { + new_address, + raw_results, + }; + let tuple_result = result_handler.list_process_result(&deploy_raw_result); + tuple_result.flatten_unpack() + } +} + +impl + Tx< + TxScEnv, + (), + (), + Payment, + Gas, + DeployCall, ()>, + OriginalResultMarker, + > +where + Api: CallTypeApi, + Payment: TxPaymentEgldOnly>, + Gas: TxGas>, + OriginalResult: TopEncodeMulti, +{ + /// Backwards compatibility, immitates the old API. + /// + /// Note that the data type (the `DeployCall`) doesn't have the code set. + /// This is because the old API was passing it as paramter, so we use it from the `code` argument. + /// + /// Also note that the code metadata is taken from the `code_metadata` argument. + /// If another one was previously set in the `Tx` object, that one will be ignored. + pub fn deploy_contract( + self, + code: &ManagedBuffer, + code_metadata: CodeMetadata, + ) -> (ManagedAddress, RequestedResult) + where + RequestedResult: TopDecodeMulti + TypeAbiFrom, + { + let (new_address, raw_results, _) = self + .code(code.clone()) + .code_metadata(code_metadata) + .execute_deploy_raw(); + + (new_address, decode_result(raw_results)) + } + + /// Backwards compatibility, immitates the old API. + /// + /// Note that the data type (the `DeployCall`) doesn't have the code set. + /// This is because the old API was passing it as paramter, so we use it from the `code` argument. + /// + /// Also note that the code metadata is taken from the `code_metadata` argument. + /// If another one was previously set in the `Tx` object, that one will be ignored. + pub fn deploy_from_source( + self, + source_address: &ManagedAddress, + code_metadata: CodeMetadata, + ) -> (ManagedAddress, RequestedResult) + where + RequestedResult: TopDecodeMulti + TypeAbiFrom, + { + let (new_address, raw_results, _) = self + .from_source(source_address.clone()) + .code_metadata(code_metadata) + .execute_deploy_from_source_raw(); + + (new_address, decode_result(raw_results)) + } +} + +impl + Tx< + TxScEnv, + (), + ManagedAddress, + Payment, + Gas, + DeployCall, ()>, + OriginalResultMarker, + > +where + Api: CallTypeApi, + Payment: TxPaymentEgldOnly>, + Gas: TxGas>, + OriginalResult: TopEncodeMulti, +{ + /// Backwards compatibility, immitates the old API. + /// + /// Should no longer be used, which is why unlike all the rest of the old syntax, was deprecated. + /// + /// Uses a `DeployCall` instead of the correct `UpgradeCall`, because the old syntax did not know about upgrades. + /// + /// Note that the data type (the `DeployCall`) doesn't have the code set. + /// This is because the old API was passing it as paramter, so we use it from the `code` argument. + /// + /// Also note that the code metadata is taken from the `code_metadata` argument. + /// If another one was previously set in the `Tx` object, that one will be ignored. + #[deprecated( + since = "0.49.0", + note = "The legacy upgrade method does not correctly take the upgrade constructor into account. Please switch to the new syntax." + )] + pub fn upgrade_contract(self, code: &ManagedBuffer, code_metadata: CodeMetadata) { + let gas = self.gas.explicit_or_gas_left(&self.env); + self.payment.with_egld_value(&self.env, |egld_value| { + SendRawWrapper::::new().upgrade_contract( + &self.to, + gas, + egld_value, + code, + code_metadata, + &self.data.arg_buffer, + ); + }); + } + + /// Backwards compatibility, immitates the old API. + /// + /// Should no longer be used, which is why unlike all the rest of the old syntax, was deprecated. + /// + /// Uses a `DeployCall` instead of the correct `UpgradeCall`, because the old syntax did not know about upgrades. + /// + /// Note that the data type (the `DeployCall`) doesn't have the code set. + /// This is because the old API was passing it as paramter, so we use it from the `code` argument. + /// + /// Also note that the code metadata is taken from the `code_metadata` argument. + /// If another one was previously set in the `Tx` object, that one will be ignored. + #[deprecated( + since = "0.49.0", + note = "The legacy upgrade method does not correctly take the upgrade constructor into account. Please switch to the new syntax." + )] + pub fn upgrade_from_source( + self, + source_address: &ManagedAddress, + code_metadata: CodeMetadata, + ) { + let gas = self.gas.explicit_or_gas_left(&self.env); + self.payment.with_egld_value(&self.env, |egld_value| { + SendRawWrapper::::new().upgrade_from_source_contract( + &self.to, + gas, + egld_value, + source_address, + code_metadata, + &self.data.arg_buffer, + ); + }); + } +} diff --git a/framework/base/src/types/interaction/tx_exec/tx_exec_sync.rs b/framework/base/src/types/interaction/tx_exec/tx_exec_sync.rs new file mode 100644 index 0000000000..4ab9c29759 --- /dev/null +++ b/framework/base/src/types/interaction/tx_exec/tx_exec_sync.rs @@ -0,0 +1,165 @@ +use multiversx_sc_codec::TopDecodeMulti; + +use crate::{ + api::CallTypeApi, + contract_base::SendRawWrapper, + tuple_util::NestedTupleFlatten, + types::{ + decode_result, BackTransfers, ManagedBuffer, ManagedVec, OriginalResultMarker, RHListExec, + Tx, TxDataFunctionCall, TxGas, TxPayment, TxScEnv, TxToSpecified, + }, +}; + +pub struct SyncCallRawResult(pub ManagedVec>) +where + Api: CallTypeApi; + +impl Tx, (), To, Payment, Gas, FC, RH> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + Gas: TxGas>, + FC: TxDataFunctionCall>, + RH: RHListExec, TxScEnv>, + RH::ListReturns: NestedTupleFlatten, +{ + fn execute_sync_call_raw(self) -> (ManagedVec>, RH) { + let gas_limit = self.gas.gas_value(&self.env); + + let raw_result = self.payment.with_normalized( + &self.env, + &self.from, + self.to, + self.data.into(), + |norm_to, norm_egld, norm_fc| { + SendRawWrapper::::new().execute_on_dest_context_raw( + gas_limit, + norm_to, + norm_egld, + &norm_fc.function_name, + &norm_fc.arg_buffer, + ) + }, + ); + + SendRawWrapper::::new().clean_return_data(); + + (raw_result, self.result_handler) + } + + /// Executes transaction synchronously. + /// + /// Only works with contracts from the same shard. + pub fn sync_call(self) -> ::Unpacked { + let (raw_result, result_handler) = self.execute_sync_call_raw(); + let sync_raw_result = SyncCallRawResult(raw_result); + let tuple_result = result_handler.list_process_result(&sync_raw_result); + tuple_result.flatten_unpack() + } + + fn execute_sync_call_same_context_raw(self) -> (ManagedVec>, RH) { + let gas_limit = self.gas.gas_value(&self.env); + + let raw_result = self.payment.with_normalized( + &self.env, + &self.from, + self.to, + self.data.into(), + |norm_to, norm_egld, norm_fc| { + SendRawWrapper::::new().execute_on_same_context_raw( + gas_limit, + norm_to, + norm_egld, + &norm_fc.function_name, + &norm_fc.arg_buffer, + ) + }, + ); + + SendRawWrapper::::new().clean_return_data(); + + (raw_result, self.result_handler) + } + + /// Executes transaction synchronously, in the same context (performed in the name of the caller). + /// + /// Only works with contracts from the same shard. + pub fn sync_call_same_context(self) -> ::Unpacked { + let (raw_result, result_handler) = self.execute_sync_call_same_context_raw(); + let sync_raw_result = SyncCallRawResult(raw_result); + let tuple_result = result_handler.list_process_result(&sync_raw_result); + tuple_result.flatten_unpack() + } +} + +impl Tx, (), To, (), Gas, FC, RH> +where + Api: CallTypeApi, + To: TxToSpecified>, + Gas: TxGas>, + FC: TxDataFunctionCall>, + RH: RHListExec, TxScEnv>, + RH::ListReturns: NestedTupleFlatten, +{ + fn execute_sync_call_readonly_raw(self) -> (ManagedVec>, RH) { + let gas_limit = self.gas.gas_value(&self.env); + let function_call = self.data.into(); + + let raw_result = self.to.with_value_ref(&self.env, |to| { + SendRawWrapper::::new().execute_on_dest_context_readonly_raw( + gas_limit, + to, + &function_call.function_name, + &function_call.arg_buffer, + ) + }); + + SendRawWrapper::::new().clean_return_data(); + + (raw_result, self.result_handler) + } + + /// Executes transaction synchronously, in readonly mode (target contract cannot have its state altered). + /// + /// Only works with contracts from the same shard. + pub fn sync_call_readonly(self) -> ::Unpacked { + let (raw_result, result_handler) = self.execute_sync_call_readonly_raw(); + let sync_raw_result = SyncCallRawResult(raw_result); + let tuple_result = result_handler.list_process_result(&sync_raw_result); + tuple_result.flatten_unpack() + } +} + +impl + Tx, (), To, Payment, Gas, FC, OriginalResultMarker> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPayment>, + Gas: TxGas>, + FC: TxDataFunctionCall>, +{ + /// Backwards compatibility. + pub fn execute_on_dest_context(self) -> RequestedResult + where + RequestedResult: TopDecodeMulti, + { + let (raw_result, _) = self.execute_sync_call_raw(); + decode_result(raw_result) + } + + /// Backwards compatibility. + pub fn execute_on_dest_context_with_back_transfers( + self, + ) -> (RequestedResult, BackTransfers) + where + RequestedResult: TopDecodeMulti, + { + let result = self.execute_on_dest_context(); + let back_transfers = + crate::contract_base::BlockchainWrapper::::new().get_back_transfers(); + + (result, back_transfers) + } +} diff --git a/framework/base/src/types/interaction/tx_exec/tx_exec_te.rs b/framework/base/src/types/interaction/tx_exec/tx_exec_te.rs new file mode 100644 index 0000000000..b9db7539b9 --- /dev/null +++ b/framework/base/src/types/interaction/tx_exec/tx_exec_te.rs @@ -0,0 +1,64 @@ +use crate::api::CallTypeApi; + +use crate::types::{ + FunctionCall, Tx, TxData, TxEmptyResultHandler, TxFrom, TxGas, TxPayment, TxScEnv, + TxToSpecified, +}; + +impl Tx, From, To, Payment, Gas, FC, RH> +where + Api: CallTypeApi, + From: TxFrom>, + To: TxToSpecified>, + Payment: TxPayment>, + Gas: TxGas>, + FC: TxData> + Into>, + RH: TxEmptyResultHandler>, +{ + fn transfer_execute_with_gas(self, gas_limit: u64) { + self.to.with_address_ref(&self.env, |to| { + self.payment + .perform_transfer_execute(&self.env, to, gas_limit, self.data.into()); + }); + } + + /// Sends transaction asynchronously, and doesn't wait for callback ("fire and forget".) + pub fn transfer_execute(self) { + let gas_limit: u64; + if self.data.is_no_call() { + if self.payment.is_no_payment(&self.env) { + return; + } else { + gas_limit = 0; + } + } else { + gas_limit = self.gas.gas_value(&self.env); + } + + self.transfer_execute_with_gas(gas_limit); + } +} + +impl Tx, From, To, Payment, (), (), ()> +where + Api: CallTypeApi, + From: TxFrom>, + To: TxToSpecified>, + Payment: TxPayment>, +{ + /// Only allowed for simple transfers. + pub fn transfer(self) { + self.transfer_execute_with_gas(0) + } + + /// Transfers funds, if amount is greater than zero. Does nothing otherwise. + /// + /// Can only used for simple transfers. + pub fn transfer_if_not_empty(self) { + if self.payment.is_no_payment(&self.env) { + return; + } + + self.transfer(); + } +} diff --git a/framework/base/src/types/interaction/tx_exec/tx_exec_upgrade.rs b/framework/base/src/types/interaction/tx_exec/tx_exec_upgrade.rs new file mode 100644 index 0000000000..3222f39356 --- /dev/null +++ b/framework/base/src/types/interaction/tx_exec/tx_exec_upgrade.rs @@ -0,0 +1,147 @@ +use crate::{ + api::CallTypeApi, + contract_base::SendRawWrapper, + proxy_imports::TxToSpecified, + types::{ + Code, CodeMetadata, FromSource, ManagedAddress, ManagedBuffer, Tx, TxCodeValue, + TxEmptyResultHandler, TxFromSourceValue, TxGas, TxPaymentEgldOnly, TxScEnv, UpgradeCall, + }, +}; + +impl + Tx< + TxScEnv, + (), + ManagedAddress, + Payment, + Gas, + UpgradeCall, Code>, + RH, + > +where + Api: CallTypeApi, + Payment: TxPaymentEgldOnly>, + Gas: TxGas>, + CodeValue: TxCodeValue>, + RH: TxEmptyResultHandler>, +{ + /// Launches the upgrade async call. + /// + /// TODO: change return type to `!`. + pub fn upgrade_async_call_and_exit(self) { + let gas = self.gas.explicit_or_gas_left(&self.env); + self.payment.with_egld_value(&self.env, |egld_value| { + SendRawWrapper::::new().upgrade_contract( + &self.to, + gas, + egld_value, + &self.data.code_source.0.into_value(&self.env), + self.data.code_metadata, + &self.data.arg_buffer, + ); + }); + } +} + +impl + Tx< + TxScEnv, + (), + ManagedAddress, + Payment, + Gas, + UpgradeCall, FromSource>, + RH, + > +where + Api: CallTypeApi, + Payment: TxPaymentEgldOnly>, + Gas: TxGas>, + FromSourceValue: TxFromSourceValue>, + RH: TxEmptyResultHandler>, +{ + /// Launches the upgrade from source async call. + /// + /// TODO: change return type to `!`. + pub fn upgrade_async_call_and_exit(self) { + let gas = self.gas.explicit_or_gas_left(&self.env); + self.payment.with_egld_value(&self.env, |egld_value| { + SendRawWrapper::::new().upgrade_from_source_contract( + &self.to, + gas, + egld_value, + &self.data.code_source.0.into_value(&self.env), + self.data.code_metadata, + &self.data.arg_buffer, + ); + }); + } +} + +impl + Tx, (), To, Payment, Gas, UpgradeCall, ()>, RH> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxPaymentEgldOnly>, + Gas: TxGas>, + RH: TxEmptyResultHandler>, +{ + /// Transition syntax, immitates the old API. + /// + /// Note that the data type (the `UpgradeCall`) doesn't have the code set. + /// This is because the old API was passing it as paramter, so we use it from the `code` argument. + /// + /// Also note that the code metadata is taken from the `code_metadata` argument. + /// If another one was previously set in the `Tx` object, that one will be ignored. + #[deprecated( + since = "0.49.0", + note = "This is a transition syntax, it would not have been reachable before 0.49.0. Use [upgrade_async_call_and_exit] instead." + )] + pub fn upgrade_contract(self, code: &ManagedBuffer, code_metadata: CodeMetadata) { + let gas = self.gas.explicit_or_gas_left(&self.env); + self.payment.with_egld_value(&self.env, |egld_value| { + self.to.with_value_ref(&self.env, |to| { + SendRawWrapper::::new().upgrade_contract( + to, + gas, + egld_value, + code, + code_metadata, + &self.data.arg_buffer, + ); + }); + }); + } + + /// Transition syntax, immitates the old API. + /// + /// Note that the data type (the `UpgradeCall`) doesn't have the code set. + /// This is because the old API was passing it as paramter, so we use it from the `code` argument. + /// + /// Also note that the code metadata is taken from the `code_metadata` argument. + /// If another one was previously set in the `Tx` object, that one will be ignored. + #[deprecated( + since = "0.49.0", + note = "This is a transition syntax, it would not have been reachable before 0.49.0. Use [upgrade_async_call_and_exit] instead." + )] + pub fn upgrade_from_source( + self, + source_address: &ManagedAddress, + code_metadata: CodeMetadata, + ) { + let gas = self.gas.explicit_or_gas_left(&self.env); + self.payment.with_egld_value(&self.env, |egld_value| { + self.to.with_value_ref(&self.env, |to| { + SendRawWrapper::::new().upgrade_from_source_contract( + to, + gas, + egld_value, + source_address, + code_metadata, + &self.data.arg_buffer, + ); + }); + }); + } +} diff --git a/framework/base/src/types/interaction/tx_from.rs b/framework/base/src/types/interaction/tx_from.rs new file mode 100644 index 0000000000..674796e64f --- /dev/null +++ b/framework/base/src/types/interaction/tx_from.rs @@ -0,0 +1,77 @@ +use crate::types::{heap::Address, ManagedAddress}; + +use super::{AnnotatedValue, TxEnv}; + +/// Marks the sender of any transaction. +pub trait TxFrom +where + Env: TxEnv, +{ + fn resolve_address(&self, env: &Env) -> ManagedAddress; +} + +/// Marks the non-empty sender of a transaction. +/// +/// Enforces the reciipent to be explicitly specified. +#[diagnostic::on_unimplemented( + message = "Type `{Self}` cannot be used as a sender value (does not implement `TxFromSpecified<{Env}>`)", + label = "sender needs to be explicit", + note = "there are multiple ways to specify the sender value for a transaction, but `{Self}` is not one of them" +)] +pub trait TxFromSpecified: + TxFrom + AnnotatedValue> +where + Env: TxEnv, +{ +} + +impl TxFrom for () +where + Env: TxEnv, +{ + fn resolve_address(&self, env: &Env) -> ManagedAddress { + env.resolve_sender_address() + } +} + +impl TxFrom for ManagedAddress +where + Env: TxEnv, +{ + fn resolve_address(&self, _env: &Env) -> ManagedAddress { + self.clone() + } +} +impl TxFromSpecified for ManagedAddress where Env: TxEnv {} + +impl TxFrom for &ManagedAddress +where + Env: TxEnv, +{ + fn resolve_address(&self, _env: &Env) -> ManagedAddress { + (*self).clone() + } +} +impl TxFromSpecified for &ManagedAddress where Env: TxEnv {} + +impl TxFrom for Address +where + Env: TxEnv, +{ + fn resolve_address(&self, _env: &Env) -> ManagedAddress { + self.into() + } +} + +impl TxFromSpecified for Address where Env: TxEnv {} + +impl TxFrom for &Address +where + Env: TxEnv, +{ + fn resolve_address(&self, _env: &Env) -> ManagedAddress { + ManagedAddress::from_address(self) + } +} + +impl TxFromSpecified for &Address where Env: TxEnv {} diff --git a/framework/base/src/types/interaction/tx_gas.rs b/framework/base/src/types/interaction/tx_gas.rs new file mode 100644 index 0000000000..2e03cc1470 --- /dev/null +++ b/framework/base/src/types/interaction/tx_gas.rs @@ -0,0 +1,67 @@ +use super::{AnnotatedValue, TxEnv}; +use crate::{ + api::{BlockchainApi, BlockchainApiImpl}, + types::ManagedBuffer, +}; + +/// All typed that populate the gas field of a transaction need to implement this trait. +pub trait TxGas +where + Env: TxEnv, +{ + fn gas_annotation(&self, env: &Env) -> ManagedBuffer; + + fn gas_value(&self, env: &Env) -> u64; + + fn explicit_or_gas_left(&self, env: &Env) -> u64; +} + +impl TxGas for () +where + Env: TxEnv, +{ + fn gas_annotation(&self, env: &Env) -> ManagedBuffer<::Api> { + env.default_gas_annotation() + } + + fn gas_value(&self, env: &Env) -> u64 { + env.default_gas_value() + } + + fn explicit_or_gas_left(&self, _env: &Env) -> u64 { + Env::Api::blockchain_api_impl().get_gas_left() + } +} + +#[diagnostic::on_unimplemented( + message = "Type `{Self}` cannot be used as gas value (does not implement `TxGasValue<{Env}>`)", + label = "not a valid value for gas", + note = "there are multiple ways to specify the gas value for a transaction, but `{Self}` is not one of them" +)] +pub trait TxGasValue: AnnotatedValue +where + Env: TxEnv, +{ +} + +impl TxGasValue for u64 where Env: TxEnv {} + +pub struct ExplicitGas(pub GasValue); + +impl TxGas for ExplicitGas +where + Env: TxEnv, + GasValue: TxGasValue, +{ + fn gas_value(&self, env: &Env) -> u64 { + self.0.to_value(env) + } + + fn gas_annotation(&self, env: &Env) -> ManagedBuffer<::Api> { + self.0.annotation(env) + } + + fn explicit_or_gas_left(&self, env: &Env) -> u64 { + self.gas_value(env) + } +} diff --git a/framework/base/src/types/interaction/tx_payment.rs b/framework/base/src/types/interaction/tx_payment.rs new file mode 100644 index 0000000000..c5bcc10637 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment.rs @@ -0,0 +1,132 @@ +mod tx_payment_egld; +mod tx_payment_egld_or_esdt; +mod tx_payment_egld_or_esdt_refs; +mod tx_payment_egld_or_multi_esdt; +mod tx_payment_egld_or_multi_esdt_ref; +mod tx_payment_egld_value; +mod tx_payment_multi_esdt; +mod tx_payment_none; +mod tx_payment_not_payable; +mod tx_payment_single_esdt; +mod tx_payment_single_esdt_ref; +mod tx_payment_single_esdt_triple; + +pub use tx_payment_egld::{Egld, EgldPayment}; +pub use tx_payment_egld_value::TxEgldValue; +pub use tx_payment_multi_esdt::TxPaymentMultiEsdt; +pub use tx_payment_not_payable::NotPayable; + +use crate::{ + api::ManagedTypeApi, + types::{BigUint, ManagedAddress, ManagedBuffer, MultiEsdtPayment}, +}; + +use super::{AnnotatedValue, FunctionCall, TxEnv, TxFrom, TxToSpecified}; + +/// Describes a payment that is part of a transaction. +#[diagnostic::on_unimplemented( + message = "Type `{Self}` cannot be used as payment (does not implement `TxPayment<{Env}>`)", + label = "not a valid payment type", + note = "there are multiple ways to specify the transaction payment, but `{Self}` is not one of them" +)] +pub trait TxPayment +where + Env: TxEnv, +{ + /// Returns true if payment indicates transfer of either non-zero EGLD or ESDT amounts. + fn is_no_payment(&self, env: &Env) -> bool; + + /// Transfer-execute calls have different APIs for different payments types. + /// This method selects between them. + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ); + + /// Converts an ESDT call to a built-in function call, if necessary. + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R; + + /// Payment data to be used by the testing framework. Will be refactored. + fn into_full_payment_data(self, env: &Env) -> FullPaymentData; +} + +/// Marker trait that indicates that payment field contains no payment. +/// +/// Implemented by `()` and `NotPayable`. +pub trait TxNoPayment: TxPayment +where + Env: TxEnv, +{ +} + +/// Marks a payment object that only contains EGLD or nothing at all. +pub trait TxPaymentEgldOnly: TxPayment + AnnotatedValue> +where + Env: TxEnv, +{ + #[inline] + fn with_egld_value(&self, env: &Env, f: F) -> R + where + F: FnOnce(&BigUint) -> R, + { + self.with_value_ref(env, f) + } + + fn into_egld_payment(self, env: &Env) -> BigUint { + self.into_value(env) + } +} + +#[derive(Clone)] +pub struct AnnotatedEgldPayment +where + Api: ManagedTypeApi, +{ + pub value: BigUint, + pub annotation: ManagedBuffer, +} + +impl AnnotatedEgldPayment +where + Api: ManagedTypeApi, +{ + pub fn new_egld(value: BigUint) -> Self { + let annotation = value.to_display(); + AnnotatedEgldPayment { value, annotation } + } +} + +#[derive(Clone)] +pub struct FullPaymentData +where + Api: ManagedTypeApi, +{ + pub egld: Option>, + pub multi_esdt: MultiEsdtPayment, +} + +impl Default for FullPaymentData +where + Api: ManagedTypeApi, +{ + fn default() -> Self { + Self { + egld: None, + multi_esdt: Default::default(), + } + } +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld.rs new file mode 100644 index 0000000000..28ebea24ac --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld.rs @@ -0,0 +1,112 @@ +use crate::{ + contract_base::SendRawWrapper, + types::{ + AnnotatedValue, BigUint, ManagedAddress, ManagedBuffer, ManagedVec, TxFrom, TxToSpecified, + }, +}; + +use super::{ + AnnotatedEgldPayment, FullPaymentData, FunctionCall, TxEgldValue, TxEnv, TxPayment, + TxPaymentEgldOnly, +}; + +/// Indicates the EGLD payment in a transaction. +pub struct Egld(pub EgldValue); + +pub type EgldPayment = Egld>; + +impl Clone for Egld { + fn clone(&self) -> Self { + Egld(self.0.clone()) + } +} + +impl TxPayment for Egld +where + Env: TxEnv, + EgldValue: TxEgldValue, +{ + fn is_no_payment(&self, env: &Env) -> bool { + self.0.with_value_ref(env, |egld_value| egld_value == &0u32) + } + + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.0.with_value_ref(env, |egld_value| { + let _ = SendRawWrapper::::new().direct_egld_execute( + to, + egld_value, + gas_limit, + &fc.function_name, + &fc.arg_buffer, + ); + }) + } + + #[inline] + fn with_normalized( + self, + env: &Env, + _from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + to.with_address_ref(env, |to_addr| { + self.0 + .with_value_ref(env, |egld_value| f(to_addr, egld_value, fc)) + }) + } + + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + FullPaymentData { + egld: Some(AnnotatedEgldPayment::new_egld(self.0.into_value(env))), + multi_esdt: ManagedVec::new(), + } + } +} + +impl AnnotatedValue> for Egld +where + Env: TxEnv, + EgldValue: TxEgldValue, +{ + fn annotation(&self, env: &Env) -> ManagedBuffer { + self.0.annotation(env) + } + + #[inline] + fn to_value(&self, env: &Env) -> BigUint { + self.0.to_value(env) + } + + #[inline] + fn into_value(self, env: &Env) -> BigUint { + self.0.into_value(env) + } + + #[inline] + fn with_value_ref(&self, env: &Env, f: F) -> R + where + F: FnOnce(&BigUint) -> R, + { + self.0.with_value_ref(env, f) + } +} + +impl TxPaymentEgldOnly for Egld +where + Env: TxEnv, + EgldValue: TxEgldValue, +{ +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt.rs new file mode 100644 index 0000000000..ddff9fcb7e --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt.rs @@ -0,0 +1,103 @@ +use crate::types::{BigUint, Egld, EgldOrEsdtTokenPayment, ManagedAddress, TxFrom, TxToSpecified}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl TxPayment for &EgldOrEsdtTokenPayment +where + Env: TxEnv, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + self.amount == 0u32 + } + + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.map_ref_egld_or_esdt( + (to, fc), + |(to, fc), amount| Egld(amount).perform_transfer_execute(env, to, gas_limit, fc), + |(to, fc), esdt_payment| esdt_payment.perform_transfer_execute(env, to, gas_limit, fc), + ) + } + + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + self.map_ref_egld_or_esdt( + (to, fc, f), + |(to, fc, f), amount| Egld(amount).with_normalized(env, from, to, fc, f), + |(to, fc, f), esdt_payment| esdt_payment.with_normalized(env, from, to, fc, f), + ) + } + + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + self.map_ref_egld_or_esdt( + (), + |(), amount| TxPayment::::into_full_payment_data(Egld(amount), env), + |(), esdt_payment| TxPayment::::into_full_payment_data(esdt_payment, env), + ) + } +} + +impl TxPayment for EgldOrEsdtTokenPayment +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, env: &Env) -> bool { + (&self).is_no_payment(env) + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + (&self).perform_transfer_execute(env, to, gas_limit, fc) + } + + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + self.map_egld_or_esdt( + (to, fc, f), + |(to, fc, f), amount| Egld(amount).with_normalized(env, from, to, fc, f), + |(to, fc, f), esdt_payment| esdt_payment.with_normalized(env, from, to, fc, f), + ) + } + + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + self.map_egld_or_esdt( + (), + |(), amount| TxPayment::::into_full_payment_data(Egld(amount), env), + |(), esdt_payment| TxPayment::::into_full_payment_data(esdt_payment, env), + ) + } +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs new file mode 100644 index 0000000000..14f9058b55 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs @@ -0,0 +1,54 @@ +use crate::types::{BigUint, EgldOrEsdtTokenPaymentRefs, ManagedAddress, TxFrom, TxToSpecified}; + +use super::{Egld, FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl<'a, Env> TxPayment for EgldOrEsdtTokenPaymentRefs<'a, Env::Api> +where + Env: TxEnv, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + self.is_empty() + } + + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.map_egld_or_esdt( + fc, + |fc, amount| Egld(amount).perform_transfer_execute(env, to, gas_limit, fc), + |fc, esdt_payment| esdt_payment.perform_transfer_execute(env, to, gas_limit, fc), + ) + } + + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + self.map_egld_or_esdt( + (to, fc, f), + |(to, fc, f), amount| Egld(amount).with_normalized(env, from, to, fc, f), + |(to, fc, f), esdt_payment| esdt_payment.with_normalized(env, from, to, fc, f), + ) + } + + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + self.map_egld_or_esdt( + (), + |(), amount| TxPayment::::into_full_payment_data(Egld(amount), env), + |(), esdt_payment| TxPayment::::into_full_payment_data(esdt_payment, env), + ) + } +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt.rs new file mode 100644 index 0000000000..24422ab040 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt.rs @@ -0,0 +1,89 @@ +use crate::types::{BigUint, EgldOrMultiEsdtPayment, ManagedAddress, TxFrom, TxToSpecified}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl TxPayment for EgldOrMultiEsdtPayment +where + Env: TxEnv, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + self.is_empty() + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.as_refs() + .perform_transfer_execute(env, to, gas_limit, fc) + } + + #[inline] + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + self.as_refs().with_normalized(env, from, to, fc, f) + } + + #[inline] + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + self.as_refs().into_full_payment_data(env) + } +} + +impl TxPayment for &EgldOrMultiEsdtPayment +where + Env: TxEnv, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + self.is_empty() + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.as_refs() + .perform_transfer_execute(env, to, gas_limit, fc) + } + + #[inline] + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + self.as_refs().with_normalized(env, from, to, fc, f) + } + + #[inline] + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + self.as_refs().into_full_payment_data(env) + } +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt_ref.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt_ref.rs new file mode 100644 index 0000000000..9d4eb6c20a --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_multi_esdt_ref.rs @@ -0,0 +1,63 @@ +use crate::types::{BigUint, EgldOrMultiEsdtPaymentRefs, ManagedAddress, TxFrom, TxToSpecified}; + +use super::{Egld, FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl<'a, Env> TxPayment for EgldOrMultiEsdtPaymentRefs<'a, Env::Api> +where + Env: TxEnv, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + self.is_empty() + } + + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + match self { + EgldOrMultiEsdtPaymentRefs::Egld(egld_amount) => { + Egld(egld_amount).perform_transfer_execute(env, to, gas_limit, fc); + }, + EgldOrMultiEsdtPaymentRefs::MultiEsdt(multi_esdt_payment) => { + multi_esdt_payment.perform_transfer_execute(env, to, gas_limit, fc); + }, + } + } + + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + match self { + EgldOrMultiEsdtPaymentRefs::Egld(egld_amount) => { + Egld(egld_amount).with_normalized(env, from, to, fc, f) + }, + EgldOrMultiEsdtPaymentRefs::MultiEsdt(multi_esdt_payment) => { + multi_esdt_payment.with_normalized(env, from, to, fc, f) + }, + } + } + + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + match self { + EgldOrMultiEsdtPaymentRefs::Egld(egld_amount) => { + Egld(egld_amount).into_full_payment_data(env) + }, + EgldOrMultiEsdtPaymentRefs::MultiEsdt(multi_esdt_payment) => { + multi_esdt_payment.into_full_payment_data(env) + }, + } + } +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_value.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_value.rs new file mode 100644 index 0000000000..99d91b618f --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_value.rs @@ -0,0 +1,14 @@ +use crate::types::{AnnotatedValue, BigUint, ManagedRef}; + +use super::TxEnv; + +pub trait TxEgldValue: AnnotatedValue> +where + Env: TxEnv, +{ +} + +impl TxEgldValue for BigUint where Env: TxEnv {} +impl TxEgldValue for &BigUint where Env: TxEnv {} +impl<'a, Env> TxEgldValue for ManagedRef<'a, Env::Api, BigUint> where Env: TxEnv {} +impl TxEgldValue for u64 where Env: TxEnv {} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_multi_esdt.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_esdt.rs new file mode 100644 index 0000000000..c0afc2055c --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_multi_esdt.rs @@ -0,0 +1,165 @@ +use core::ops::Deref; + +use crate::{ + contract_base::SendRawWrapper, + types::{BigUint, ManagedAddress, ManagedRef, MultiEsdtPayment, TxFrom, TxToSpecified}, +}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +/// Indicates that a payment object contains a multi-ESDT payment. +pub trait TxPaymentMultiEsdt: TxPayment +where + Env: TxEnv, +{ +} + +impl TxPaymentMultiEsdt for MultiEsdtPayment where Env: TxEnv {} +impl TxPaymentMultiEsdt for &MultiEsdtPayment where Env: TxEnv {} +impl<'a, Env> TxPaymentMultiEsdt for ManagedRef<'a, Env::Api, MultiEsdtPayment> where + Env: TxEnv +{ +} + +impl TxPayment for &MultiEsdtPayment +where + Env: TxEnv, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + self.is_empty() + } + + fn perform_transfer_execute( + self, + _env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + let _ = SendRawWrapper::::new().multi_esdt_transfer_execute( + to, + self, + gas_limit, + &fc.function_name, + &fc.arg_buffer, + ); + } + + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + match self.len() { + 0 => ().with_normalized(env, from, to, fc, f), + 1 => self.get(0).as_refs().with_normalized(env, from, to, fc, f), + _ => to.with_address_ref(env, |to_addr| { + let fc_conv = fc.convert_to_multi_transfer_esdt_call(to_addr, self); + f(&from.resolve_address(env), &*BigUint::zero_ref(), fc_conv) + }), + } + } + + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { + FullPaymentData { + egld: None, + multi_esdt: self.clone(), + } + } +} + +impl<'a, Env> TxPayment for ManagedRef<'a, Env::Api, MultiEsdtPayment> +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + self.deref().is_empty() + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.deref() + .perform_transfer_execute(env, to, gas_limit, fc) + } + + #[inline] + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + self.deref().with_normalized(env, from, to, fc, f) + } + + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + self.deref().into_full_payment_data(env) + } +} + +impl TxPayment for MultiEsdtPayment +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + self.is_empty() + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + (&self).perform_transfer_execute(env, to, gas_limit, fc); + } + + #[inline] + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + (&self).with_normalized(env, from, to, fc, f) + } + + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { + FullPaymentData { + egld: None, + multi_esdt: self, + } + } +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_none.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_none.rs new file mode 100644 index 0000000000..f16cde1a26 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_none.rs @@ -0,0 +1,51 @@ +use crate::types::{BigUint, ManagedAddress, TxFrom, TxToSpecified}; + +use super::{ + Egld, FullPaymentData, FunctionCall, TxEnv, TxNoPayment, TxPayment, TxPaymentEgldOnly, +}; + +impl TxPayment for () +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + true + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + Egld(BigUint::zero_ref()).perform_transfer_execute(env, to, gas_limit, fc); + } + + #[inline] + fn with_normalized( + self, + env: &Env, + _from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + to.with_address_ref(env, |to_addr| f(to_addr, &*BigUint::zero_ref(), fc)) + } + + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { + FullPaymentData::default() + } +} + +impl TxNoPayment for () where Env: TxEnv {} + +impl TxPaymentEgldOnly for () where Env: TxEnv {} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_not_payable.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_not_payable.rs new file mode 100644 index 0000000000..a198a50c98 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_not_payable.rs @@ -0,0 +1,57 @@ +use crate::types::{BigUint, ManagedAddress, TxFrom, TxToSpecified}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxNoPayment, TxPayment, TxPaymentEgldOnly}; + +/// Transaction marker, which indicates that a transaction should never have any payment added to it. +/// +/// The implementation is completely identical to the empty payment `()`, +/// the only difference is that the payment methods in `Tx` can only be called on top of `()` payment, not `NotPayable`. +/// +/// So basically, `NotPayable` acts as a seal, preventing further payments to be added. +pub struct NotPayable; + +impl TxPayment for NotPayable +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + true + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + ().perform_transfer_execute(env, to, gas_limit, fc); + } + + #[inline] + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + ().with_normalized(env, from, to, fc, f) + } + + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { + FullPaymentData::default() + } +} + +impl TxNoPayment for NotPayable where Env: TxEnv {} + +impl TxPaymentEgldOnly for NotPayable where Env: TxEnv {} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt.rs new file mode 100644 index 0000000000..9ace787df2 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt.rs @@ -0,0 +1,97 @@ +use crate::types::{ + BigUint, EsdtTokenPayment, ManagedAddress, MultiEsdtPayment, TxFrom, TxToSpecified, +}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl TxPayment for EsdtTokenPayment +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + self.amount == 0u32 + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.as_refs() + .perform_transfer_execute(env, to, gas_limit, fc); + } + + #[inline] + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + self.as_refs().with_normalized(env, from, to, fc, f) + } + + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { + FullPaymentData { + egld: None, + multi_esdt: MultiEsdtPayment::from_single_item(self), + } + } +} + +impl TxPayment for &EsdtTokenPayment +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + self.amount == 0u32 + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.as_refs() + .perform_transfer_execute(env, to, gas_limit, fc); + } + + #[inline] + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + self.as_refs().with_normalized(env, from, to, fc, f) + } + + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { + FullPaymentData { + egld: None, + multi_esdt: MultiEsdtPayment::from_single_item(self.clone()), + } + } +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs new file mode 100644 index 0000000000..c91391d316 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_ref.rs @@ -0,0 +1,80 @@ +use crate::{ + contract_base::SendRawWrapper, + types::{ + BigUint, EsdtTokenPaymentRefs, ManagedAddress, MultiEsdtPayment, TxFrom, TxToSpecified, + }, +}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl<'a, Env> TxPayment for EsdtTokenPaymentRefs<'a, Env::Api> +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + self.amount == &0u32 + } + + fn perform_transfer_execute( + self, + _env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + if self.token_nonce == 0 { + // fungible ESDT + let _ = SendRawWrapper::::new().transfer_esdt_execute( + to, + self.token_identifier, + self.amount, + gas_limit, + &fc.function_name, + &fc.arg_buffer, + ); + } else { + // non-fungible/semi-fungible ESDT + let _ = SendRawWrapper::::new().transfer_esdt_nft_execute( + to, + self.token_identifier, + self.token_nonce, + self.amount, + gas_limit, + &fc.function_name, + &fc.arg_buffer, + ); + } + } + + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + to.with_address_ref(env, |to_addr| { + if self.token_nonce == 0 { + let fc_conv = fc.convert_to_single_transfer_fungible_call(self); + f(to_addr, &*BigUint::zero_ref(), fc_conv) + } else { + let fc_conv = fc.convert_to_single_transfer_nft_call(to_addr, self); + f(&from.resolve_address(env), &*BigUint::zero_ref(), fc_conv) + } + }) + } + + fn into_full_payment_data(self, _env: &Env) -> FullPaymentData { + FullPaymentData { + egld: None, + multi_esdt: MultiEsdtPayment::from_single_item(self.to_owned_payment()), + } + } +} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_triple.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_triple.rs new file mode 100644 index 0000000000..aec74201d5 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_single_esdt_triple.rs @@ -0,0 +1,47 @@ +use crate::types::{ + BigUint, EsdtTokenPayment, ManagedAddress, TokenIdentifier, TxFrom, TxToSpecified, +}; + +use super::{FullPaymentData, FunctionCall, TxEnv, TxPayment}; + +impl TxPayment for (TokenIdentifier, u64, BigUint) +where + Env: TxEnv, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + self.2 == 0u32 + } + + #[inline] + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + EsdtTokenPayment::from(self).perform_transfer_execute(env, to, gas_limit, fc) + } + + #[inline] + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, FunctionCall) -> R, + { + EsdtTokenPayment::from(self).with_normalized(env, from, to, fc, f) + } + + #[inline] + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + EsdtTokenPayment::from(self).into_full_payment_data(env) + } +} diff --git a/framework/base/src/types/interaction/tx_proxy.rs b/framework/base/src/types/interaction/tx_proxy.rs new file mode 100644 index 0000000000..e0b62e006a --- /dev/null +++ b/framework/base/src/types/interaction/tx_proxy.rs @@ -0,0 +1,70 @@ +use multiversx_sc_codec::TopEncodeMulti; + +use crate::abi::TypeAbiFrom; + +use super::{ + DeployCall, FunctionCall, OriginalResultMarker, Tx, TxEnv, TxFrom, TxGas, TxTo, UpgradeCall, +}; + +/// Defines a proxy object for a smart contract. +pub trait TxProxyTrait +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods; + + /// Creates the associated type that contains the proxy methods implementations. + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods; +} + +/// Alias for a `Tx` generated from a proxy, in `init`. +/// +/// Replaced by `TxTypedDeploy`. +pub type TxProxyDeploy = + Tx, OriginalResultMarker>; + +/// Alias for a `Tx` generated from a proxy, in `init`. +pub type TxTypedDeploy = + Tx, OriginalResultMarker>; + +/// Alias for a `Tx` generated from a proxy, in an endpoint. +/// +/// Replaced by `TxTypedCall`. +pub type TxProxyCall = + Tx::Api>, OriginalResultMarker>; + +/// Alias for a `Tx` generated from a proxy, in an endpoint. +pub type TxTypedCall = Tx< + Env, + From, + To, + Payment, + Gas, + FunctionCall<::Api>, + OriginalResultMarker, +>; + +/// Alias for a `Tx` generated from a proxy, in `upgrade`. +/// +/// Replaced by `TxTypedUpgrade`. +pub type TxProxyUpgrade = + Tx, OriginalResultMarker>; + +/// Alias for a `Tx` generated from a proxy, in `upgrade`. +pub type TxTypedUpgrade = + Tx, OriginalResultMarker>; + +/// Trait that is automatically implemented for all types that are allowed as proxy inputs. +/// +/// Is automatically implemented for all traits that are `TypeAbiInto + TopEncodeMulti`. +pub trait ProxyArg: TopEncodeMulti {} + +impl ProxyArg for T +where + O: TypeAbiFrom, + T: TopEncodeMulti, +{ +} diff --git a/framework/base/src/types/interaction/tx_result_handler.rs b/framework/base/src/types/interaction/tx_result_handler.rs new file mode 100644 index 0000000000..099d060c44 --- /dev/null +++ b/framework/base/src/types/interaction/tx_result_handler.rs @@ -0,0 +1,33 @@ +use super::TxEnv; + +/// Marks a general result handler, to be used in the transaction unified syntax. +/// +/// Rationale described here: https://twitter.com/andreimmarinica/status/1781371938750841288 +/// +/// Used for: +/// - async callbacks +/// - processing of results in sync calls, tests and interactors. +pub trait TxResultHandler +where + Env: TxEnv, +{ + type OriginalResult; +} + +impl TxResultHandler for () +where + Env: TxEnv, +{ + type OriginalResult = (); +} + +/// Indicates that given result handler is empty, i.e. doesn't cause any side effects and returns nothing. +/// +/// Implemented for `()` and `OriginalResultMarker`. +pub trait TxEmptyResultHandler: TxResultHandler +where + Env: TxEnv, +{ +} + +impl TxEmptyResultHandler for () where Env: TxEnv {} diff --git a/framework/base/src/types/interaction/tx_result_handler_list.rs b/framework/base/src/types/interaction/tx_result_handler_list.rs new file mode 100644 index 0000000000..b66a4ba52e --- /dev/null +++ b/framework/base/src/types/interaction/tx_result_handler_list.rs @@ -0,0 +1,9 @@ +mod original_result; +mod tx_result_handler_list_cons; +mod tx_result_handler_list_exec; +mod tx_result_handler_list_item; + +pub use original_result::OriginalResultMarker; +pub use tx_result_handler_list_cons::*; +pub use tx_result_handler_list_exec::*; +pub use tx_result_handler_list_item::*; diff --git a/framework/base/src/types/interaction/tx_result_handler_list/original_result.rs b/framework/base/src/types/interaction/tx_result_handler_list/original_result.rs new file mode 100644 index 0000000000..175f5c6404 --- /dev/null +++ b/framework/base/src/types/interaction/tx_result_handler_list/original_result.rs @@ -0,0 +1,36 @@ +use core::marker::PhantomData; + +use crate::types::{TxEmptyResultHandler, TxEnv, TxResultHandler}; + +/// Contains no data. +/// +/// Indicates to the compiler the original result type expected from a transaction. +/// +/// Note that the transaction result might be interpreted as a different type, +/// but the originally declared type is required to perform any type checking. +pub struct OriginalResultMarker { + _phantom: PhantomData, +} + +impl Default for OriginalResultMarker { + fn default() -> Self { + Self { + _phantom: Default::default(), + } + } +} + +impl OriginalResultMarker { + pub fn new() -> Self { + Self::default() + } +} + +impl TxResultHandler for OriginalResultMarker +where + Env: TxEnv, +{ + type OriginalResult = O; +} + +impl TxEmptyResultHandler for OriginalResultMarker where Env: TxEnv {} diff --git a/framework/base/src/types/interaction/tx_result_handler_list/tx_result_handler_list_cons.rs b/framework/base/src/types/interaction/tx_result_handler_list/tx_result_handler_list_cons.rs new file mode 100644 index 0000000000..86a24e8a19 --- /dev/null +++ b/framework/base/src/types/interaction/tx_result_handler_list/tx_result_handler_list_cons.rs @@ -0,0 +1,239 @@ +use core::marker::PhantomData; + +use crate::types::{OriginalResultMarker, TxEnv, TxResultHandler}; + +use super::RHListItem; + +pub trait RHList: TxResultHandler +where + Env: TxEnv, +{ + type ListReturns; +} + +pub trait RHListAppendRet: RHList +where + Env: TxEnv, + T: RHListItem, +{ + type RetOutput: RHList; + + fn append_ret(self, t: T) -> Self::RetOutput; +} + +pub trait RHListAppendNoRet: RHList +where + Env: TxEnv, + T: RHListItem, +{ + type NoRetOutput: RHList; + + fn append_no_ret(self, t: T) -> Self::NoRetOutput; +} + +impl RHList for () +where + Env: TxEnv, +{ + type ListReturns = (); +} + +impl RHListAppendRet for () +where + Env: TxEnv, + T: RHListItem, +{ + type RetOutput = ConsRet; + + fn append_ret(self, t: T) -> Self::RetOutput { + ConsRet::new(t, self) + } +} + +impl RHListAppendNoRet for () +where + Env: TxEnv, + T: RHListItem, +{ + type NoRetOutput = ConsNoRet; + + fn append_no_ret(self, t: T) -> Self::NoRetOutput { + ConsNoRet::new(t, self) + } +} + +impl RHList for OriginalResultMarker +where + Env: TxEnv, +{ + type ListReturns = (); +} + +impl RHListAppendRet for OriginalResultMarker +where + Env: TxEnv, + T: RHListItem, +{ + type RetOutput = ConsRet>; + + fn append_ret(self, t: T) -> Self::RetOutput { + ConsRet::new(t, self) + } +} + +impl RHListAppendNoRet for OriginalResultMarker +where + Env: TxEnv, + T: RHListItem, +{ + type NoRetOutput = ConsNoRet>; + + fn append_no_ret(self, t: T) -> Self::NoRetOutput { + ConsNoRet::new(t, self) + } +} + +pub struct ConsRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList, +{ + _phantom: PhantomData, + pub head: Head, + pub tail: Tail, +} + +impl ConsRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList, +{ + fn new(head: Head, tail: Tail) -> Self { + ConsRet { + _phantom: PhantomData, + head, + tail, + } + } +} + +impl TxResultHandler for ConsRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList, +{ + type OriginalResult = Tail::OriginalResult; +} + +impl RHList for ConsRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList, +{ + type ListReturns = (Head::Returns, Tail::ListReturns); +} + +impl RHListAppendRet for ConsRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList + RHListAppendRet, + T: RHListItem, +{ + type RetOutput = ConsRet>::RetOutput>; + + fn append_ret(self, t: T) -> Self::RetOutput { + ConsRet::new(self.head, self.tail.append_ret(t)) + } +} + +impl RHListAppendNoRet for ConsRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList + RHListAppendNoRet, + T: RHListItem, +{ + type NoRetOutput = ConsRet>::NoRetOutput>; + + fn append_no_ret(self, t: T) -> Self::NoRetOutput { + ConsRet::new(self.head, self.tail.append_no_ret(t)) + } +} + +/// Handlers that return nothing. +pub struct ConsNoRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList, +{ + _phantom: PhantomData, + pub head: Head, + pub tail: Tail, +} + +impl ConsNoRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList, +{ + fn new(head: Head, tail: Tail) -> Self { + ConsNoRet { + _phantom: PhantomData, + head, + tail, + } + } +} + +impl TxResultHandler for ConsNoRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList, +{ + type OriginalResult = Tail::OriginalResult; +} + +impl RHList for ConsNoRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList, +{ + type ListReturns = Tail::ListReturns; +} + +impl RHListAppendRet for ConsNoRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList + RHListAppendRet, + T: RHListItem, +{ + type RetOutput = ConsNoRet>::RetOutput>; + + fn append_ret(self, t: T) -> Self::RetOutput { + ConsNoRet::new(self.head, self.tail.append_ret(t)) + } +} + +impl RHListAppendNoRet for ConsNoRet +where + Env: TxEnv, + Head: RHListItem, + Tail: RHList + RHListAppendNoRet, + T: RHListItem, +{ + type NoRetOutput = ConsNoRet>::NoRetOutput>; + + fn append_no_ret(self, t: T) -> Self::NoRetOutput { + ConsNoRet::new(self.head, self.tail.append_no_ret(t)) + } +} diff --git a/framework/base/src/types/interaction/tx_result_handler_list/tx_result_handler_list_exec.rs b/framework/base/src/types/interaction/tx_result_handler_list/tx_result_handler_list_exec.rs new file mode 100644 index 0000000000..93f559b4ba --- /dev/null +++ b/framework/base/src/types/interaction/tx_result_handler_list/tx_result_handler_list_exec.rs @@ -0,0 +1,98 @@ +use crate::types::{OriginalResultMarker, TxEnv}; + +use super::{ConsNoRet, ConsRet, RHList, RHListItem}; + +/// Indicates how result processing will undergo for one specific result handler. +/// +/// Note that the `ResultType` needs to be the first generic type in the definition, +/// so we can add new implementations of the same result handlers for new raw result types in subsequent crates. +pub trait RHListItemExec: RHListItem +where + Env: TxEnv, +{ + /// Part of the execution pre-processing, each result handler needs to produce an "expect" field, + /// as defined in the environment. + /// + /// The operation is chained, so all result handlers can contribute, hence the `prev` argument, + /// which represents the "expect" field produces by the other result handlers. + /// + /// The default behavior is to leave it unchanged. + fn item_tx_expect(&self, prev: Env::RHExpect) -> Env::RHExpect { + prev + } + + /// The main functionality of a result handler, it either does some computation internally + /// (e.g. execution of a lambda function), or produces a result, or both. + fn item_process_result(self, raw_result: &RawResult) -> Self::Returns; +} + +/// Indicates how result processing will undergo for an ensemble of result handlers. +pub trait RHListExec: RHList +where + Env: TxEnv, +{ + /// Provides the execution pre-processing, in which result handlers collectively produce an "expect" field. + /// + /// The operation starts with the default "expect" field, which normally has all fields unspecified, except + /// for the "status", which is by default set to "0". This means that failing transactions will cause a panic + /// unless explicitly stated in one of the result handlers. + fn list_tx_expect(&self) -> Env::RHExpect; + + /// Aggregates the executions of all result handlers, as configured for a transaction. + fn list_process_result(self, raw_result: &RawResult) -> Self::ListReturns; +} + +impl RHListExec for () +where + Env: TxEnv, +{ + fn list_tx_expect(&self) -> Env::RHExpect { + Env::RHExpect::default() + } + + fn list_process_result(self, _raw_result: &RawResult) -> Self::ListReturns {} +} + +impl RHListExec for OriginalResultMarker +where + Env: TxEnv, +{ + fn list_tx_expect(&self) -> Env::RHExpect { + Env::RHExpect::default() + } + + fn list_process_result(self, _raw_result: &RawResult) -> Self::ListReturns {} +} + +impl RHListExec for ConsRet +where + Env: TxEnv, + Head: RHListItemExec, + Tail: RHListExec, +{ + fn list_tx_expect(&self) -> Env::RHExpect { + self.head.item_tx_expect(self.tail.list_tx_expect()) + } + + fn list_process_result(self, raw_result: &RawResult) -> Self::ListReturns { + let head_result = self.head.item_process_result(raw_result); + let tail_result = self.tail.list_process_result(raw_result); + (head_result, tail_result) + } +} + +impl RHListExec for ConsNoRet +where + Env: TxEnv, + Head: RHListItemExec, + Tail: RHListExec, +{ + fn list_tx_expect(&self) -> Env::RHExpect { + self.head.item_tx_expect(self.tail.list_tx_expect()) + } + + fn list_process_result(self, raw_result: &RawResult) -> Self::ListReturns { + self.head.item_process_result(raw_result); + self.tail.list_process_result(raw_result) + } +} diff --git a/framework/base/src/types/interaction/tx_result_handler_list/tx_result_handler_list_item.rs b/framework/base/src/types/interaction/tx_result_handler_list/tx_result_handler_list_item.rs new file mode 100644 index 0000000000..9ca98bac65 --- /dev/null +++ b/framework/base/src/types/interaction/tx_result_handler_list/tx_result_handler_list_item.rs @@ -0,0 +1,23 @@ +use crate::types::TxEnv; + +/// Result handler list item. +/// +/// It acts as a result handler that produces a single result. +#[diagnostic::on_unimplemented( + message = "Type `{Self}` cannot be used as a decoder result handler (does not implement `RHListItem<{Env}>`)", + label = "not a valid decoder result handler", + note = "there are multiple ways to specify the result handling, but `{Self}` is not one of them" +)] +pub trait RHListItem +where + Env: TxEnv, +{ + type Returns; +} + +impl RHListItem for () +where + Env: TxEnv, +{ + type Returns = (); +} diff --git a/framework/base/src/types/interaction/tx_to.rs b/framework/base/src/types/interaction/tx_to.rs new file mode 100644 index 0000000000..41d5d4ce39 --- /dev/null +++ b/framework/base/src/types/interaction/tx_to.rs @@ -0,0 +1,48 @@ +use crate::types::{heap::Address, ManagedAddress}; + +use super::{AnnotatedValue, TxEnv}; + +/// Marks the recipient of any transaction. +pub trait TxTo +where + Env: TxEnv, +{ +} + +impl TxTo for () where Env: TxEnv {} + +/// Marks the non-empty recipient of a transaction. +/// +/// Enforces the recipient to be explicitly specified. +#[diagnostic::on_unimplemented( + message = "Type `{Self}` cannot be used as recipient value (does not implement `TxToSpecified<{Env}>`)", + label = "recipient needs to be explicit", + note = "there are multiple ways to specify the recipient value for a transaction, but `{Self}` is not one of them" +)] +pub trait TxToSpecified: TxTo + AnnotatedValue> +where + Env: TxEnv, +{ + /// Avoids a clone when performing transfer-execute. + /// + /// Other than that, does thesame as `AnnotatedValue::into_value`. + #[inline] + fn with_address_ref(&self, env: &Env, f: F) -> R + where + F: FnOnce(&ManagedAddress) -> R, + { + self.with_value_ref(env, f) + } +} + +impl TxTo for ManagedAddress where Env: TxEnv {} +impl TxToSpecified for ManagedAddress where Env: TxEnv {} + +impl TxTo for &ManagedAddress where Env: TxEnv {} +impl TxToSpecified for &ManagedAddress where Env: TxEnv {} + +impl TxTo for Address where Env: TxEnv {} +impl TxToSpecified for Address where Env: TxEnv {} + +impl TxTo for &Address where Env: TxEnv {} +impl TxToSpecified for &Address where Env: TxEnv {} diff --git a/framework/base/src/types/io/operation_completion_status.rs b/framework/base/src/types/io/operation_completion_status.rs index a7e030ab96..95fc52f2ed 100644 --- a/framework/base/src/types/io/operation_completion_status.rs +++ b/framework/base/src/types/io/operation_completion_status.rs @@ -4,11 +4,11 @@ use multiversx_sc_codec::{ use crate::{ abi::{ - ExplicitEnumVariantDescription, TypeAbi, TypeContents, TypeDescription, + ExplicitEnumVariantDescription, TypeAbi, TypeAbiFrom, TypeContents, TypeDescription, TypeDescriptionContainer, TypeName, }, api::ManagedTypeApi, - codec::{CodecFrom, EncodeErrorHandler}, + codec::EncodeErrorHandler, types::ManagedBuffer, }; @@ -58,12 +58,14 @@ impl TopDecode for OperationCompletionStatus { I: TopDecodeInput, H: DecodeErrorHandler, { - let mut buffer = [0u8; 16]; - input.into_max_size_buffer(&mut buffer, h)?; + const BUFFER_LEN: usize = 16; + let mut buffer = [0u8; BUFFER_LEN]; + let len = input.into_max_size_buffer_align_right(&mut buffer, h)?; + let bytes = &buffer[BUFFER_LEN - len..]; - if buffer.starts_with(COMPLETED_STR.as_bytes()) { + if bytes.starts_with(COMPLETED_STR.as_bytes()) { Ok(OperationCompletionStatus::Completed) - } else if buffer.starts_with(INTERRUPTED_STR.as_bytes()) { + } else if bytes.starts_with(INTERRUPTED_STR.as_bytes()) { Ok(OperationCompletionStatus::InterruptedBeforeOutOfGas) } else { Err(h.handle_error(DecodeError::INVALID_VALUE)) @@ -71,23 +73,31 @@ impl TopDecode for OperationCompletionStatus { } } -impl CodecFrom for ManagedBuffer {} -impl CodecFrom for crate::types::heap::BoxedBytes {} -impl CodecFrom for crate::types::heap::Vec {} +impl TypeAbiFrom for ManagedBuffer {} +impl TypeAbiFrom for crate::types::heap::BoxedBytes {} +impl TypeAbiFrom for crate::types::heap::Vec {} + +impl TypeAbiFrom for OperationCompletionStatus {} impl TypeAbi for OperationCompletionStatus { + type Unmanaged = Self; + fn type_name() -> TypeName { TypeName::from("OperationCompletionStatus") } + fn type_name_rust() -> TypeName { + TypeName::from("OperationCompletionStatus") + } + fn provide_type_descriptions(accumulator: &mut TDC) { - let type_name = Self::type_name(); + let type_names = Self::type_names(); accumulator.insert( - type_name, + type_names, TypeDescription { docs: Vec::new(), - name: Self::type_name(), + names: Self::type_names(), contents: TypeContents::ExplicitEnum([ ExplicitEnumVariantDescription::new( &["indicates that operation was completed"], @@ -98,6 +108,7 @@ impl TypeAbi for OperationCompletionStatus { INTERRUPTED_STR, ) ].to_vec()), + macro_attributes: Vec::new() }, ); } diff --git a/framework/base/src/types/io/sc_error_static.rs b/framework/base/src/types/io/sc_error_static.rs index a63daa1571..176fb86162 100644 --- a/framework/base/src/types/io/sc_error_static.rs +++ b/framework/base/src/types/io/sc_error_static.rs @@ -54,12 +54,6 @@ impl From for StaticSCError { } } -impl From for StaticSCError { - fn from(_: !) -> Self { - unreachable!() - } -} - impl TopEncodeMulti for StaticSCError { fn multi_encode_or_handle_err(&self, output: &mut O, h: H) -> Result<(), H::HandledErr> where diff --git a/framework/base/src/types/io/sc_result.rs b/framework/base/src/types/io/sc_result.rs index 6278987b45..de000fa1e1 100644 --- a/framework/base/src/types/io/sc_result.rs +++ b/framework/base/src/types/io/sc_result.rs @@ -1,13 +1,14 @@ -use crate::codec::{EncodeErrorHandler, TopEncodeMulti, TopEncodeMultiOutput}; +use alloc::format; + +use crate::{ + abi::TypeAbiFrom, + codec::{EncodeErrorHandler, TopEncodeMulti, TopEncodeMultiOutput}, +}; use crate::{ abi::{OutputAbis, TypeAbi, TypeDescriptionContainer, TypeName}, api::EndpointFinishApi, }; -use core::{ - convert, - ops::{ControlFlow, FromResidual, Try}, -}; use super::{SCError, StaticSCError}; @@ -76,40 +77,6 @@ impl SCResult { } } -/// Implementing the `Try` trait overloads the `?` operator. -/// Documentation on the new version of the trait: -/// -impl Try for SCResult { - type Output = T; - type Residual = E; - - fn branch(self) -> ControlFlow { - match self { - SCResult::Ok(t) => ControlFlow::Continue(t), - SCResult::Err(e) => ControlFlow::Break(e), - } - } - fn from_output(v: T) -> Self { - SCResult::Ok(v) - } -} - -impl FromResidual for SCResult { - fn from_residual(r: E) -> Self { - SCResult::Err(r) - } -} - -impl FromResidual> for SCResult -where - FromErr: Into, -{ - fn from_residual(residual: Result) -> Self { - let Err(e) = residual; - SCResult::Err(e.into()) - } -} - impl TopEncodeMulti for SCResult where T: TopEncodeMulti, @@ -127,11 +94,23 @@ where } } +impl TypeAbiFrom for SCResult {} + impl TypeAbi for SCResult { + type Unmanaged = Self; + fn type_name() -> TypeName { T::type_name() } + fn type_name_rust() -> TypeName { + format!( + "SCResult<{}, {}>", + T::type_name_rust(), + core::any::type_name::() + ) + } + /// Gives `SCResult<()>` the possibility to produce 0 output ABIs, /// just like `()`. /// It is also possible to have `SCResult>`, diff --git a/framework/base/src/types/managed/basic/big_float.rs b/framework/base/src/types/managed/basic/big_float.rs index 44abed8b86..934bd2c636 100644 --- a/framework/base/src/types/managed/basic/big_float.rs +++ b/framework/base/src/types/managed/basic/big_float.rs @@ -1,6 +1,7 @@ use super::ManagedBuffer; use crate::{ + abi::{TypeAbi, TypeAbiFrom}, api::{ use_raw_handle, BigFloatApiImpl, ManagedTypeApi, ManagedTypeApiImpl, Sign, StaticVarApiImpl, }, @@ -9,9 +10,8 @@ use crate::{ use alloc::string::String; use crate::codec::{ - CodecFromSelf, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, - NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, - TryStaticCast, + DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, + NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, TryStaticCast, }; #[derive(Debug)] @@ -92,8 +92,6 @@ big_float_conv_num! {isize} big_float_conv_num! {i16} big_float_conv_num! {i8} -impl CodecFromSelf for BigFloat where M: ManagedTypeApi {} - impl BigFloat { #[inline] pub fn neg(&self) -> Self { @@ -289,7 +287,14 @@ impl NestedDecode for BigFloat { } } -impl crate::abi::TypeAbi for BigFloat { +impl TypeAbiFrom> for f64 where M: ManagedTypeApi {} + +impl TypeAbiFrom for BigFloat where M: ManagedTypeApi {} +impl TypeAbiFrom<&Self> for BigFloat where M: ManagedTypeApi {} + +impl TypeAbi for BigFloat { + type Unmanaged = f64; + fn type_name() -> String { String::from("BigFloat") } diff --git a/framework/base/src/types/managed/basic/big_int.rs b/framework/base/src/types/managed/basic/big_int.rs index 227a298d02..7f84593f2b 100644 --- a/framework/base/src/types/managed/basic/big_int.rs +++ b/framework/base/src/types/managed/basic/big_int.rs @@ -1,15 +1,14 @@ use core::{convert::TryInto, marker::PhantomData}; use crate::{ - abi::TypeName, + abi::{TypeAbiFrom, TypeName}, api::{ const_handles, use_raw_handle, BigIntApiImpl, HandleConstraints, ManagedBufferApiImpl, ManagedTypeApi, ManagedTypeApiImpl, RawHandle, StaticVarApiImpl, }, codec::{ - CodecFrom, CodecFromSelf, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, - NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, - TopEncodeOutput, TryStaticCast, + DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, + NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, TryStaticCast, }, formatter::{hex_util::encode_bytes_as_hex, FormatByteReceiver, SCDisplay}, types::{heap::BoxedBytes, BigUint, ManagedBuffer, ManagedOption, ManagedType, Sign}, @@ -100,7 +99,8 @@ macro_rules! big_int_conv_num { } } - impl CodecFrom<$num_ty> for BigInt {} + impl TypeAbiFrom<$num_ty> for BigInt {} + impl TypeAbiFrom<&$num_ty> for BigInt {} }; } @@ -111,12 +111,29 @@ big_int_conv_num! {isize} big_int_conv_num! {i16} big_int_conv_num! {i8} -impl CodecFromSelf for BigInt where M: ManagedTypeApi {} - #[cfg(feature = "num-bigint")] -impl CodecFrom for BigInt {} +impl TypeAbiFrom for BigInt {} #[cfg(feature = "num-bigint")] -impl CodecFrom> for crate::codec::num_bigint::BigInt {} +impl TypeAbiFrom> for crate::codec::num_bigint::BigInt {} + +impl TypeAbiFrom for BigInt where M: ManagedTypeApi {} +impl TypeAbiFrom<&Self> for BigInt where M: ManagedTypeApi {} + +impl crate::abi::TypeAbi for BigInt { + #[cfg(feature = "num-bigint")] + type Unmanaged = crate::codec::num_bigint::BigInt; + + #[cfg(not(feature = "num-bigint"))] + type Unmanaged = Self; + + fn type_name() -> TypeName { + TypeName::from("BigInt") + } + + fn type_name_rust() -> TypeName { + TypeName::from("BigInt<$API>") + } +} #[cfg(feature = "num-bigint")] impl From<&crate::codec::num_bigint::BigInt> for BigInt { @@ -298,12 +315,6 @@ impl TopDecode for BigInt { } } -impl crate::abi::TypeAbi for BigInt { - fn type_name() -> TypeName { - TypeName::from("BigInt") - } -} - impl BigInt { #[must_use] pub fn pow(&self, exp: u32) -> Self { diff --git a/framework/base/src/types/managed/basic/big_int_sign.rs b/framework/base/src/types/managed/basic/big_int_sign.rs index 5d850afe79..178e55f981 100644 --- a/framework/base/src/types/managed/basic/big_int_sign.rs +++ b/framework/base/src/types/managed/basic/big_int_sign.rs @@ -3,7 +3,7 @@ use crate::codec::{ NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, }; -use crate::abi::TypeName; +use crate::abi::{TypeAbi, TypeAbiFrom, TypeName}; // BigInt sign. #[allow(clippy::enum_variant_names)] @@ -79,8 +79,16 @@ impl TopDecode for Sign { } } -impl crate::abi::TypeAbi for Sign { +impl TypeAbiFrom for Sign {} + +impl TypeAbi for Sign { + type Unmanaged = Self; + fn type_name() -> TypeName { TypeName::from("Sign") } + + fn type_name_rust() -> TypeName { + TypeName::from("multiversx_sc::types::Sign") + } } diff --git a/framework/base/src/types/managed/basic/big_uint.rs b/framework/base/src/types/managed/basic/big_uint.rs index b139f823dc..7f9f6bb17b 100644 --- a/framework/base/src/types/managed/basic/big_uint.rs +++ b/framework/base/src/types/managed/basic/big_uint.rs @@ -1,18 +1,18 @@ use core::convert::TryInto; use crate::{ - abi::TypeName, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ const_handles, use_raw_handle, BigIntApiImpl, HandleConstraints, ManagedBufferApiImpl, ManagedTypeApi, ManagedTypeApiImpl, RawHandle, StaticVarApiImpl, }, codec::{ - CodecFrom, CodecFromSelf, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, - NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, - TopEncodeOutput, TryStaticCast, + DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, + NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, TryStaticCast, }, - formatter::{hex_util::encode_bytes_as_hex, FormatByteReceiver, SCDisplay}, - types::{heap::BoxedBytes, ManagedBuffer, ManagedType}, + formatter::{hex_util::encode_bytes_as_hex, FormatBuffer, FormatByteReceiver, SCDisplay}, + proxy_imports::ManagedRef, + types::{heap::BoxedBytes, ManagedBuffer, ManagedBufferCachedBuilder, ManagedType}, }; use super::cast_to_i64::cast_to_i64; @@ -94,7 +94,7 @@ macro_rules! big_uint_conv_num { } } - impl CodecFrom<$num_ty> for BigUint {} + impl TypeAbiFrom<$num_ty> for BigUint {} }; } @@ -104,12 +104,29 @@ big_uint_conv_num! {usize} big_uint_conv_num! {u16} big_uint_conv_num! {u8} -impl CodecFromSelf for BigUint where M: ManagedTypeApi {} - #[cfg(feature = "num-bigint")] -impl CodecFrom for BigUint {} +impl TypeAbiFrom for BigUint {} #[cfg(feature = "num-bigint")] -impl CodecFrom> for crate::codec::num_bigint::BigUint {} +impl TypeAbiFrom> for crate::codec::num_bigint::BigUint {} + +impl TypeAbiFrom for BigUint where M: ManagedTypeApi {} +impl TypeAbiFrom<&Self> for BigUint where M: ManagedTypeApi {} + +impl TypeAbi for BigUint { + #[cfg(feature = "num-bigint")] + type Unmanaged = crate::codec::num_bigint::BigUint; + + #[cfg(not(feature = "num-bigint"))] + type Unmanaged = Self; + + fn type_name() -> TypeName { + TypeName::from("BigUint") + } + + fn type_name_rust() -> TypeName { + TypeName::from("BigUint<$API>") + } +} #[cfg(feature = "num-bigint")] impl From<&crate::codec::num_bigint::BigUint> for BigUint { @@ -146,6 +163,12 @@ impl BigUint { BigUint::from_handle(handle) } + pub fn zero_ref() -> ManagedRef<'static, M, BigUint> { + let handle: M::BigIntHandle = use_raw_handle(const_handles::BIG_INT_CONST_ZERO); + M::managed_type_impl().bi_set_int64(handle.clone(), 0); + unsafe { ManagedRef::wrap_handle(handle) } + } + #[inline] pub fn to_u64(&self) -> Option { let api = M::managed_type_impl(); @@ -287,12 +310,6 @@ impl TopDecode for BigUint { } } -impl crate::abi::TypeAbi for BigUint { - fn type_name() -> TypeName { - TypeName::from("BigUint") - } -} - impl SCDisplay for BigUint { fn fmt(&self, f: &mut F) { let str_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); @@ -303,6 +320,15 @@ impl SCDisplay for BigUint { } } +impl BigUint { + /// Creates to a managed buffer containing the textual representation of the number. + pub fn to_display(&self) -> ManagedBuffer { + let mut result = ManagedBufferCachedBuilder::new_from_slice(&[]); + result.append_display(self); + result.into_managed_buffer() + } +} + impl core::fmt::Debug for BigUint { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("BigUint") diff --git a/framework/base/src/types/managed/basic/cast_to_i64.rs b/framework/base/src/types/managed/basic/cast_to_i64.rs index b41ffed95e..a9de298223 100644 --- a/framework/base/src/types/managed/basic/cast_to_i64.rs +++ b/framework/base/src/types/managed/basic/cast_to_i64.rs @@ -12,5 +12,5 @@ where { value .try_into() - .unwrap_or_else(|_| M::error_api_impl().signal_error(err_msg::CAST_TO_I64_ERROR)) + .unwrap_or_else(|_| M::error_api_impl().signal_error(err_msg::CAST_TO_I64_ERROR.as_bytes())) } diff --git a/framework/base/src/types/managed/basic/elliptic_curve.rs b/framework/base/src/types/managed/basic/elliptic_curve.rs index d70f7f738d..8c6d66990f 100644 --- a/framework/base/src/types/managed/basic/elliptic_curve.rs +++ b/framework/base/src/types/managed/basic/elliptic_curve.rs @@ -1,5 +1,5 @@ use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{use_raw_handle, BigIntApiImpl, EllipticCurveApiImpl, ManagedTypeApi}, types::{BigUint, ManagedType}, }; @@ -418,8 +418,16 @@ impl TopEncode for EllipticCurve { } } +impl TypeAbiFrom for EllipticCurve where M: ManagedTypeApi {} + impl TypeAbi for EllipticCurve { + type Unmanaged = Self; + fn type_name() -> TypeName { TypeName::from("EllipticCurve") } + + fn type_name_rust() -> TypeName { + TypeName::from("EllipticCurve<$API>") + } } diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index 7c08f32699..d232776b2e 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -1,18 +1,19 @@ use crate::{ - abi::TypeName, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ use_raw_handle, ErrorApiImpl, HandleConstraints, InvalidSliceError, ManagedBufferApiImpl, ManagedTypeApi, StaticVarApiImpl, }, codec::{ - CodecFrom, CodecFromSelf, DecodeErrorHandler, Empty, EncodeErrorHandler, NestedDecode, - NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, - TopEncodeOutput, TryStaticCast, + DecodeErrorHandler, Empty, EncodeErrorHandler, NestedDecode, NestedDecodeInput, + NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, + TryStaticCast, }, formatter::{ - hex_util::encode_bytes_as_hex, FormatByteReceiver, SCBinary, SCDisplay, SCLowerHex, + hex_util::encode_bytes_as_hex, FormatBuffer, FormatByteReceiver, SCBinary, SCDisplay, + SCLowerHex, }, - types::{heap::BoxedBytes, ManagedType, StaticBufferRef}, + types::{heap::BoxedBytes, ManagedBufferCachedBuilder, ManagedType, StaticBufferRef}, }; /// A byte buffer managed by an external API. @@ -159,6 +160,26 @@ where } } +impl From for ManagedBuffer +where + M: ManagedTypeApi, +{ + #[inline] + fn from(s: crate::types::heap::String) -> Self { + Self::new_from_bytes(s.as_bytes()) + } +} + +impl From<&crate::types::heap::String> for ManagedBuffer +where + M: ManagedTypeApi, +{ + #[inline] + fn from(s: &crate::types::heap::String) -> Self { + Self::new_from_bytes(s.as_bytes()) + } +} + impl Default for ManagedBuffer { #[inline] fn default() -> Self { @@ -310,6 +331,14 @@ impl ManagedBuffer { Some(u64::from_be_bytes(bytes)) } } + + /// Produces a hex expression in another managed buffer, + /// made up of "0x" + the hex representation of the data. + pub fn hex_expr(&self) -> ManagedBuffer { + let mut result = ManagedBufferCachedBuilder::new_from_slice(b"0x"); + result.append_lower_hex(self); + result.into_managed_buffer() + } } impl Clone for ManagedBuffer { @@ -384,18 +413,16 @@ impl TopEncode for ManagedBuffer { } } -impl CodecFromSelf for ManagedBuffer where M: ManagedTypeApi {} - -impl CodecFrom<&[u8]> for ManagedBuffer where M: ManagedTypeApi {} -impl CodecFrom<&str> for ManagedBuffer where M: ManagedTypeApi {} -impl CodecFrom<&[u8; N]> for ManagedBuffer where M: ManagedTypeApi {} +impl TypeAbiFrom<&[u8]> for ManagedBuffer where M: ManagedTypeApi {} +impl TypeAbiFrom<&str> for ManagedBuffer where M: ManagedTypeApi {} +impl TypeAbiFrom<&[u8; N]> for ManagedBuffer where M: ManagedTypeApi {} macro_rules! managed_buffer_codec_from_impl_bi_di { ($other_ty:ty) => { - impl CodecFrom<$other_ty> for ManagedBuffer {} - impl CodecFrom<&$other_ty> for ManagedBuffer {} - impl CodecFrom> for $other_ty {} - impl CodecFrom<&ManagedBuffer> for $other_ty {} + impl TypeAbiFrom<$other_ty> for ManagedBuffer {} + impl TypeAbiFrom<&$other_ty> for ManagedBuffer {} + impl TypeAbiFrom> for $other_ty {} + impl TypeAbiFrom<&ManagedBuffer> for $other_ty {} }; } @@ -432,10 +459,19 @@ impl TopDecode for ManagedBuffer { } } -impl crate::abi::TypeAbi for ManagedBuffer { +impl TypeAbiFrom for ManagedBuffer where M: ManagedTypeApi {} +impl TypeAbiFrom<&Self> for ManagedBuffer where M: ManagedTypeApi {} + +impl TypeAbi for ManagedBuffer { + type Unmanaged = multiversx_sc_codec::Vec; + fn type_name() -> TypeName { "bytes".into() } + + fn type_name_rust() -> TypeName { + "ManagedBuffer<$API>".into() + } } impl SCDisplay for ManagedBuffer { diff --git a/framework/base/src/types/managed/codec_util/managed_buffer_top_de_input.rs b/framework/base/src/types/managed/codec_util/managed_buffer_top_de_input.rs index acc280de1d..fb091781a2 100644 --- a/framework/base/src/types/managed/codec_util/managed_buffer_top_de_input.rs +++ b/framework/base/src/types/managed/codec_util/managed_buffer_top_de_input.rs @@ -1,12 +1,15 @@ -use crate::codec::{ - try_execute_then_cast, DecodeError, DecodeErrorHandler, TopDecodeInput, TryStaticCast, -}; -use alloc::boxed::Box; - use crate::{ - api::ManagedTypeApi, + api::{ + const_handles, managed_types::BigIntApiImpl, use_raw_handle, ManagedTypeApi, + ManagedTypeApiImpl, + }, + codec::{ + try_execute_then_cast, DecodeError, DecodeErrorHandler, TopDecodeInput, TryStaticCast, + }, + err_msg, types::{BigInt, BigUint, ManagedBuffer}, }; +use alloc::boxed::Box; use super::ManagedBufferNestedDecodeInput; @@ -41,6 +44,38 @@ where Ok(byte_slice) } + fn into_max_size_buffer_align_right( + self, + buffer: &mut [u8; MAX_LEN], + h: H, + ) -> Result + where + H: DecodeErrorHandler, + { + let len = self.len(); + if len > MAX_LEN { + return Err(h.handle_error(DecodeError::INPUT_TOO_LONG)); + } + unsafe { + let byte_slice = buffer.get_unchecked_mut(MAX_LEN - len..); + let _ = self.load_slice(0, byte_slice); + } + Ok(len) + } + + fn into_i64(self, h: H) -> Result + where + H: DecodeErrorHandler, + { + let big_int_temp: M::BigIntHandle = use_raw_handle(const_handles::BIG_INT_TEMPORARY_1); + M::managed_type_impl().mb_to_big_int_signed(self.handle.clone(), big_int_temp.clone()); + if let Some(value) = M::managed_type_impl().bi_to_i64(big_int_temp) { + Ok(value) + } else { + Err(h.handle_error(err_msg::ARG_OUT_OF_RANGE.into())) + } + } + #[inline] fn supports_specialized_type() -> bool { T::type_eq::>() || T::type_eq::>() || T::type_eq::>() diff --git a/framework/base/src/types/managed/multi_value/async_call_result_managed.rs b/framework/base/src/types/managed/multi_value/async_call_result_managed.rs index 6cdd2d7513..afa978f429 100644 --- a/framework/base/src/types/managed/multi_value/async_call_result_managed.rs +++ b/framework/base/src/types/managed/multi_value/async_call_result_managed.rs @@ -1,5 +1,5 @@ use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::ManagedTypeApi, codec::{ DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, @@ -97,11 +97,20 @@ where } } +impl TypeAbiFrom for ManagedAsyncCallResult +where + M: ManagedTypeApi, + T: TypeAbi, +{ +} + impl TypeAbi for ManagedAsyncCallResult where M: ManagedTypeApi, T: TypeAbi, { + type Unmanaged = Self; + fn type_name() -> TypeName { let mut repr = TypeName::from("AsyncCallResult<"); repr.push_str(T::type_name().as_str()); diff --git a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs index 66149fe04c..7e7cd934a3 100644 --- a/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs +++ b/framework/base/src/types/managed/multi_value/esdt_token_payment_multi_value.rs @@ -1,6 +1,9 @@ -use crate::codec::{ - multi_types::MultiValue3, DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, - TopDecodeMultiInput, TopDecodeMultiLength, TopEncodeMulti, TopEncodeMultiOutput, +use crate::{ + abi::TypeAbiFrom, + codec::{ + multi_types::MultiValue3, DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, + TopDecodeMultiInput, TopDecodeMultiLength, TopEncodeMulti, TopEncodeMultiOutput, + }, }; use crate::{ @@ -37,7 +40,7 @@ impl EsdtTokenPaymentMultiValue { } impl ManagedVecItem for EsdtTokenPaymentMultiValue { - const PAYLOAD_SIZE: usize = EsdtTokenPayment::::PAYLOAD_SIZE; + type PAYLOAD = as ManagedVecItem>::PAYLOAD; const SKIPS_RESERIALIZATION: bool = EsdtTokenPayment::::SKIPS_RESERIALIZATION; type Ref<'a> = Self; @@ -98,14 +101,22 @@ where const LEN: usize = 3; } +impl TypeAbiFrom for EsdtTokenPaymentMultiValue where M: ManagedTypeApi {} + impl TypeAbi for EsdtTokenPaymentMultiValue where M: ManagedTypeApi, { + type Unmanaged = Self; + fn type_name() -> TypeName { MultiValue3::, u64, BigUint>::type_name() } + fn type_name_rust() -> TypeName { + "EsdtTokenPaymentMultiValue<$API>".into() + } + fn is_variadic() -> bool { true } diff --git a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs index ebf8e0cb69..f06a6fcbdc 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs @@ -1,8 +1,10 @@ +use unwrap_infallible::UnwrapInfallible; + use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::{ErrorApi, ManagedTypeApi}, codec::{ - try_cast_execute_or_else, CodecFromSelf, DecodeErrorHandler, EncodeErrorHandler, TopDecode, + try_cast_execute_or_else, DecodeErrorHandler, EncodeErrorHandler, TopDecode, TopDecodeMulti, TopDecodeMultiInput, TopDecodeMultiLength, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, }, @@ -68,10 +70,11 @@ where T: TopEncodeMulti, { pub fn push(&mut self, item: T) { - let Ok(()) = item.multi_encode_or_handle_err( + item.multi_encode_or_handle_err( &mut self.raw_buffers, ExitCodecErrorHandler::::from(err_msg::SERIALIZER_ENCODE_ERROR), - ); + ) + .unwrap_infallible() } } @@ -222,15 +225,39 @@ where } } +impl TypeAbiFrom for MultiValueEncoded +where + M: ManagedTypeApi, + T: TypeAbi, +{ +} + +impl TypeAbiFrom<&Self> for MultiValueEncoded +where + M: ManagedTypeApi, + T: TypeAbi, +{ +} + impl TypeAbi for MultiValueEncoded where M: ManagedTypeApi, T: TypeAbi, { + #[cfg(feature = "alloc")] + type Unmanaged = MultiValueVec; + + #[cfg(not(feature = "alloc"))] + type Unmanaged = Self; + fn type_name() -> TypeName { crate::abi::type_name_variadic::() } + fn type_name_rust() -> TypeName { + crate::abi::type_name_multi_value_encoded::() + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } @@ -240,26 +267,24 @@ where } } -impl CodecFromSelf for MultiValueEncoded where M: ManagedTypeApi {} - #[cfg(feature = "alloc")] -use crate::codec::{multi_types::MultiValueVec, CodecFrom}; +use crate::codec::multi_types::MultiValueVec; #[cfg(feature = "alloc")] -impl CodecFrom> for MultiValueEncoded +impl TypeAbiFrom> for MultiValueEncoded where M: ManagedTypeApi + ErrorApi, T: TopEncodeMulti, - U: CodecFrom, + U: TypeAbiFrom, { } #[cfg(feature = "alloc")] -impl CodecFrom> for MultiValueVec +impl TypeAbiFrom> for MultiValueVec where M: ManagedTypeApi + ErrorApi, T: TopEncodeMulti, - U: CodecFrom, + U: TypeAbiFrom, { } diff --git a/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs b/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs index 99ef7fa132..8a88ffeef7 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_encoded_iter.rs @@ -1,5 +1,7 @@ use core::marker::PhantomData; +use unwrap_infallible::UnwrapInfallible; + use crate::codec::{TopDecodeMulti, TopDecodeMultiInput}; use crate::{ @@ -54,7 +56,8 @@ where if self.data_loader.has_next() { let arg_id = ArgId::from(&b"var args"[..]); let h = ArgErrorHandler::::from(arg_id); - let Ok(result) = T::multi_decode_or_handle_err(&mut self.data_loader, h); + let result = + T::multi_decode_or_handle_err(&mut self.data_loader, h).unwrap_infallible(); Some(result) } else { None diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs index a00042ed5b..0c1f094cb6 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs @@ -1,5 +1,5 @@ use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::ManagedTypeApi, codec::{ DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, @@ -210,16 +210,30 @@ where } } +impl TypeAbiFrom for MultiValueManagedVec +where + M: ManagedTypeApi, + T: ManagedVecItem, +{ +} + impl TypeAbi for MultiValueManagedVec where M: ManagedTypeApi, T: ManagedVecItem, { + #[cfg(feature = "alloc")] + type Unmanaged = multiversx_sc_codec::multi_types::MultiValueVec; + + #[cfg(not(feature = "alloc"))] + type Unmanaged = Self; + fn type_name() -> TypeName { - let mut repr = TypeName::from("variadic<"); - repr.push_str(T::type_name().as_str()); - repr.push('>'); - repr + crate::abi::type_name_variadic::() + } + + fn type_name_rust() -> TypeName { + alloc::format!("MultiValueManagedVec<$API, {}>", T::type_name_rust()) } fn provide_type_descriptions(accumulator: &mut TDC) { diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs index eaab79dbed..60ffb780ee 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec_counted.rs @@ -1,5 +1,5 @@ use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::ManagedTypeApi, codec::{ DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, @@ -126,11 +126,20 @@ where } } +impl TypeAbiFrom for MultiValueManagedVecCounted +where + M: ManagedTypeApi, + T: ManagedVecItem + TypeAbi, +{ +} + impl TypeAbi for MultiValueManagedVecCounted where M: ManagedTypeApi, T: ManagedVecItem + TypeAbi, { + type Unmanaged = Self; + fn type_name() -> TypeName { let mut repr = TypeName::from("counted-variadic<"); repr.push_str(T::type_name().as_str()); diff --git a/framework/base/src/types/managed/wrapped/builder.rs b/framework/base/src/types/managed/wrapped/builder.rs new file mode 100644 index 0000000000..78f81f6e81 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/builder.rs @@ -0,0 +1,18 @@ +mod managed_buffer_builder; +mod managed_buffer_builder_impl; +mod managed_buffer_builder_impl_basic; +mod managed_buffer_builder_impl_cached; + +pub use managed_buffer_builder::ManagedBufferBuilder; +pub use managed_buffer_builder_impl::ManagedBufferBuilderImpl; +pub use managed_buffer_builder_impl_basic::ManagedBufferBuilderImplBasic; +pub use managed_buffer_builder_impl_cached::ManagedBufferBuilderImplCached; + +#[deprecated(since = "0.48.0", note = "Renamed to ManagedBufferBuilder.")] +pub type ManagedBufferCachedBuilder = ManagedBufferBuilder; + +#[cfg(feature = "managed-buffer-builder-cached")] +pub type ManagedBufferImplDefault = ManagedBufferBuilderImplCached; + +#[cfg(not(feature = "managed-buffer-builder-cached"))] +pub type ManagedBufferImplDefault = ManagedBufferBuilderImplBasic; diff --git a/framework/base/src/types/managed/wrapped/managed_buffer_cached_builder.rs b/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder.rs similarity index 63% rename from framework/base/src/types/managed/wrapped/managed_buffer_cached_builder.rs rename to framework/base/src/types/managed/wrapped/builder/managed_buffer_builder.rs index 85d6c5a264..b65aa8e0e0 100644 --- a/framework/base/src/types/managed/wrapped/managed_buffer_cached_builder.rs +++ b/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder.rs @@ -1,3 +1,5 @@ +use core::marker::PhantomData; + use crate::codec::{EncodeError, EncodeErrorHandler, NestedEncodeOutput, TryStaticCast}; use crate::{ @@ -6,45 +8,41 @@ use crate::{ hex_util::{byte_to_binary_digits, byte_to_hex_digits}, FormatBuffer, FormatByteReceiver, SCBinary, SCCodec, SCDisplay, SCLowerHex, }, - types::{BigInt, BigUint, ManagedBuffer, StaticBufferRef}, + types::ManagedBuffer, }; +use super::{ManagedBufferBuilderImpl, ManagedBufferImplDefault}; + const HEX_CONVERSION_BUFFER_LEN: usize = 32; const BIN_CONVERSION_BUFFER_LEN: usize = 32; -pub struct ManagedBufferCachedBuilder +pub struct ManagedBufferBuilder> where M: ManagedTypeApi, + Impl: ManagedBufferBuilderImpl, { - managed_buffer: ManagedBuffer, - static_cache: Option>, + _phantom: PhantomData, + implementation: Impl, } -impl ManagedBufferCachedBuilder +impl ManagedBufferBuilder where M: ManagedTypeApi, + Impl: ManagedBufferBuilderImpl, { /// Creates instance as lazily as possible. /// If possible, the slice is loaded into the static buffer. /// If not, it is saved into the managed buffer so that the data is not lost. /// Use `flush_to_managed_buffer` after this to ensure that the managed buffer is populated. pub fn new_from_slice(slice: &[u8]) -> Self { - let static_cache = StaticBufferRef::try_new(slice); - if static_cache.is_some() { - ManagedBufferCachedBuilder { - managed_buffer: ManagedBuffer::new(), - static_cache, - } - } else { - ManagedBufferCachedBuilder { - managed_buffer: slice.into(), - static_cache: None, - } + ManagedBufferBuilder { + _phantom: PhantomData, + implementation: Impl::new_from_slice(slice), } } } -impl Default for ManagedBufferCachedBuilder +impl Default for ManagedBufferBuilder> where M: ManagedTypeApi, { @@ -54,48 +52,21 @@ where } } -impl ManagedBufferCachedBuilder +impl ManagedBufferBuilder where M: ManagedTypeApi, + Impl: ManagedBufferBuilderImpl, { - pub fn into_managed_buffer(mut self) -> ManagedBuffer { - self.flush_to_managed_buffer(); - self.managed_buffer - } - - fn flush_to_managed_buffer(&mut self) { - let old_static_cache = core::mem::take(&mut self.static_cache); - if let Some(static_cache) = &old_static_cache { - static_cache.with_buffer_contents(|bytes| { - self.managed_buffer.append_bytes(bytes); - }); - } + pub fn into_managed_buffer(self) -> ManagedBuffer { + self.implementation.into_managed_buffer() } pub fn append_bytes(&mut self, bytes: &[u8]) { - if let Some(static_cache) = &mut self.static_cache { - let success = static_cache.try_extend_from_slice(bytes); - if !success { - self.flush_to_managed_buffer(); - self.managed_buffer.append_bytes(bytes); - } - } else { - self.managed_buffer.append_bytes(bytes); - } + self.implementation.append_bytes(bytes); } pub fn append_managed_buffer(&mut self, item: &ManagedBuffer) { - if let Some(static_cache) = &mut self.static_cache { - let success = static_cache.try_extend_from_copy_bytes(item.len(), |dest_slice| { - let _ = item.load_slice(0, dest_slice); - }); - if !success { - self.flush_to_managed_buffer(); - self.managed_buffer.append(item); - } - } else { - self.managed_buffer.append(item); - } + self.implementation.append_managed_buffer(item); } /// Converts the input to hex and adds it to the current buffer. @@ -125,14 +96,18 @@ where } } -impl NestedEncodeOutput for ManagedBufferCachedBuilder { +impl NestedEncodeOutput for ManagedBufferBuilder +where + M: ManagedTypeApi, + Impl: ManagedBufferBuilderImpl, +{ fn write(&mut self, bytes: &[u8]) { self.append_bytes(bytes); } #[inline] fn supports_specialized_type() -> bool { - T::type_eq::>() || T::type_eq::>() || T::type_eq::>() + T::type_eq::>() } #[inline] @@ -156,9 +131,10 @@ impl NestedEncodeOutput for ManagedBufferCachedBuilder { } } -impl FormatByteReceiver for ManagedBufferCachedBuilder +impl FormatByteReceiver for ManagedBufferBuilder where M: ManagedTypeApi, + Impl: ManagedBufferBuilderImpl, { type Api = M; @@ -179,7 +155,10 @@ where } } -impl FormatBuffer for ManagedBufferCachedBuilder { +impl FormatBuffer for ManagedBufferBuilder> +where + M: ManagedTypeApi, +{ fn append_ascii(&mut self, ascii: &[u8]) { self.append_bytes(ascii) } diff --git a/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder_impl.rs b/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder_impl.rs new file mode 100644 index 0000000000..dfade9b6e3 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder_impl.rs @@ -0,0 +1,14 @@ +use crate::{api::ManagedTypeApi, types::ManagedBuffer}; + +pub trait ManagedBufferBuilderImpl +where + M: ManagedTypeApi, +{ + fn new_from_slice(slice: &[u8]) -> Self; + + fn into_managed_buffer(self) -> ManagedBuffer; + + fn append_bytes(&mut self, bytes: &[u8]); + + fn append_managed_buffer(&mut self, item: &ManagedBuffer); +} diff --git a/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder_impl_basic.rs b/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder_impl_basic.rs new file mode 100644 index 0000000000..3c1e87c7fb --- /dev/null +++ b/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder_impl_basic.rs @@ -0,0 +1,40 @@ +use crate::{api::ManagedTypeApi, types::ManagedBuffer}; + +use super::ManagedBufferBuilderImpl; + +/// Basic implementation of a ManagedBuffer builder, no caching. +/// +/// It is the ManagedBuffer itself, we just append to it each time. +pub struct ManagedBufferBuilderImplBasic +where + M: ManagedTypeApi, +{ + managed_buffer: ManagedBuffer, +} + +impl ManagedBufferBuilderImpl for ManagedBufferBuilderImplBasic +where + M: ManagedTypeApi, +{ + #[inline] + fn new_from_slice(slice: &[u8]) -> Self { + ManagedBufferBuilderImplBasic { + managed_buffer: slice.into(), + } + } + + #[inline] + fn into_managed_buffer(self) -> ManagedBuffer { + self.managed_buffer + } + + #[inline] + fn append_bytes(&mut self, bytes: &[u8]) { + self.managed_buffer.append_bytes(bytes); + } + + #[inline] + fn append_managed_buffer(&mut self, item: &ManagedBuffer) { + self.managed_buffer.append(item); + } +} diff --git a/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder_impl_cached.rs b/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder_impl_cached.rs new file mode 100644 index 0000000000..ead06e151c --- /dev/null +++ b/framework/base/src/types/managed/wrapped/builder/managed_buffer_builder_impl_cached.rs @@ -0,0 +1,84 @@ +use crate::{ + api::ManagedTypeApi, + types::{ManagedBuffer, StaticBufferRef}, +}; + +use super::ManagedBufferBuilderImpl; + +/// A ManagedBuffer builder implementation that caches data to the static cache locally in the contract. +pub struct ManagedBufferBuilderImplCached +where + M: ManagedTypeApi, +{ + managed_buffer: ManagedBuffer, + static_cache: Option>, +} + +impl ManagedBufferBuilderImplCached +where + M: ManagedTypeApi, +{ + fn flush_to_managed_buffer(&mut self) { + let old_static_cache = core::mem::take(&mut self.static_cache); + if let Some(static_cache) = &old_static_cache { + static_cache.with_buffer_contents(|bytes| { + self.managed_buffer.append_bytes(bytes); + }); + } + } +} + +impl ManagedBufferBuilderImpl for ManagedBufferBuilderImplCached +where + M: ManagedTypeApi, +{ + /// Creates instance as lazily as possible. + /// If possible, the slice is loaded into the static buffer. + /// If not, it is saved into the managed buffer so that the data is not lost. + /// Use `flush_to_managed_buffer` after this to ensure that the managed buffer is populated. + fn new_from_slice(slice: &[u8]) -> Self { + let static_cache = StaticBufferRef::try_new(slice); + if static_cache.is_some() { + ManagedBufferBuilderImplCached { + managed_buffer: ManagedBuffer::new(), + static_cache, + } + } else { + ManagedBufferBuilderImplCached { + managed_buffer: slice.into(), + static_cache: None, + } + } + } + + fn into_managed_buffer(mut self) -> ManagedBuffer { + self.flush_to_managed_buffer(); + self.managed_buffer + } + + fn append_bytes(&mut self, bytes: &[u8]) { + if let Some(static_cache) = &mut self.static_cache { + let success = static_cache.try_extend_from_slice(bytes); + if !success { + self.flush_to_managed_buffer(); + self.managed_buffer.append_bytes(bytes); + } + } else { + self.managed_buffer.append_bytes(bytes); + } + } + + fn append_managed_buffer(&mut self, item: &ManagedBuffer) { + if let Some(static_cache) = &mut self.static_cache { + let success = static_cache.try_extend_from_copy_bytes(item.len(), |dest_slice| { + let _ = item.load_slice(0, dest_slice); + }); + if !success { + self.flush_to_managed_buffer(); + self.managed_buffer.append(item); + } + } else { + self.managed_buffer.append(item); + } + } +} diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index e885181eca..19506645a2 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -1,11 +1,12 @@ use alloc::string::ToString; use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{HandleConstraints, ManagedTypeApi}, codec::*, derive::ManagedVecItem, formatter::{FormatByteReceiver, SCDisplay, SCLowerHex}, + proxy_imports::TestTokenIdentifier, types::{ManagedBuffer, ManagedOption, ManagedRef, ManagedType, TokenIdentifier}, }; @@ -28,7 +29,7 @@ use crate as multiversx_sc; // required by the ManagedVecItem derive #[repr(transparent)] #[derive(ManagedVecItem, Clone)] pub struct EgldOrEsdtTokenIdentifier { - data: ManagedOption>, + pub(crate) data: ManagedOption>, } impl EgldOrEsdtTokenIdentifier { @@ -83,8 +84,9 @@ impl EgldOrEsdtTokenIdentifier { #[inline] pub fn into_name(self) -> ManagedBuffer { self.map_or_else( - || ManagedBuffer::from(&Self::EGLD_REPRESENTATION[..]), - |token_identifier| token_identifier.into_managed_buffer(), + (), + |()| ManagedBuffer::from(&Self::EGLD_REPRESENTATION[..]), + |(), token_identifier| token_identifier.into_managed_buffer(), ) } @@ -93,25 +95,26 @@ impl EgldOrEsdtTokenIdentifier { /// Will fail if it encodes an invalid ESDT token identifier. pub fn is_valid(&self) -> bool { self.map_ref_or_else( - || true, - |token_identifier| token_identifier.is_valid_esdt_identifier(), + (), + |()| true, + |(), token_identifier| token_identifier.is_valid_esdt_identifier(), ) } - pub fn map_or_else(self, for_egld: D, for_esdt: F) -> U + pub fn map_or_else(self, context: Context, for_egld: D, for_esdt: F) -> R where - D: FnOnce() -> U, - F: FnOnce(TokenIdentifier) -> U, + D: FnOnce(Context) -> R, + F: FnOnce(Context, TokenIdentifier) -> R, { - self.data.map_or_else(for_egld, for_esdt) + self.data.map_or_else(context, for_egld, for_esdt) } - pub fn map_ref_or_else(&self, for_egld: D, for_esdt: F) -> U + pub fn map_ref_or_else(&self, context: Context, for_egld: D, for_esdt: F) -> R where - D: FnOnce() -> U, - F: FnOnce(&TokenIdentifier) -> U, + D: FnOnce(Context) -> R, + F: FnOnce(Context, &TokenIdentifier) -> R, { - self.data.map_ref_or_else(for_egld, for_esdt) + self.data.map_ref_or_else(context, for_egld, for_esdt) } pub fn unwrap_esdt(self) -> TokenIdentifier { @@ -144,8 +147,9 @@ impl PartialEq> for EgldOrEsdtTokenIdentif #[inline] fn eq(&self, other: &TokenIdentifier) -> bool { self.map_ref_or_else( - || false, - |self_esdt_token_identifier| self_esdt_token_identifier == other, + (), + |()| false, + |(), self_esdt_token_identifier| self_esdt_token_identifier == other, ) } } @@ -204,18 +208,33 @@ impl TopDecode for EgldOrEsdtTokenIdentifier { } } -impl CodecFromSelf for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom<&TokenIdentifier> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom<&[u8]> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom<&str> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} -impl CodecFrom> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} -impl CodecFrom<&TokenIdentifier> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} +impl<'a, M> TypeAbiFrom> for EgldOrEsdtTokenIdentifier where + M: ManagedTypeApi +{ +} +impl<'a, M> TypeAbiFrom<&TestTokenIdentifier<'a>> for EgldOrEsdtTokenIdentifier where + M: ManagedTypeApi +{ +} -impl CodecFrom<&[u8]> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} -impl CodecFrom<&str> for EgldOrEsdtTokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom for EgldOrEsdtTokenIdentifier {} +impl TypeAbiFrom<&Self> for EgldOrEsdtTokenIdentifier {} impl TypeAbi for EgldOrEsdtTokenIdentifier { + type Unmanaged = Self; + fn type_name() -> TypeName { "EgldOrEsdtTokenIdentifier".into() } + + fn type_name_rust() -> TypeName { + "EgldOrEsdtTokenIdentifier<$API>".into() + } } impl SCDisplay for EgldOrEsdtTokenIdentifier { diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs index ed76946617..2e702a0701 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs @@ -1,4 +1,5 @@ use crate::{ + abi::TypeAbiFrom, api::ManagedTypeApi, types::{BigUint, EgldOrEsdtTokenIdentifier}, }; @@ -6,13 +7,12 @@ use crate::{ use crate::codec::{ self, derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, - CodecFrom, CodecFromSelf, }; use crate as multiversx_sc; // needed by the TypeAbi generated code use crate::derive::TypeAbi; -use super::EsdtTokenPayment; +use super::{EsdtTokenPayment, EsdtTokenPaymentRefs}; #[derive( TopDecode, TopEncode, NestedDecode, NestedEncode, TypeAbi, Clone, PartialEq, Eq, Debug, @@ -53,6 +53,54 @@ impl EgldOrEsdtTokenPayment { ) } + /// Equivalent to a `match { Egld | Esdt }`. + /// + /// Context passed on from function to closures, to avoid ownership issues. + /// More precisely, since only one of the two closures `for_egld` and `for_esdt` is called, + /// it is ok for them to have fully owned access to anything from the environment. + /// The compiler doesn't know that only one of them can ever be called, + /// so if we pass context to both closures, it will complain that they are moved twice. + pub fn map_egld_or_esdt(self, context: Context, for_egld: D, for_esdt: F) -> U + where + D: FnOnce(Context, BigUint) -> U, + F: FnOnce(Context, EsdtTokenPayment) -> U, + { + self.token_identifier.map_or_else( + (context, self.amount), + |(context, amount)| for_egld(context, amount), + |(context, amount), token_identifier| { + for_esdt( + context, + EsdtTokenPayment::new(token_identifier, self.token_nonce, amount), + ) + }, + ) + } + + /// Same as `map_egld_or_esdt`, but only takes a reference, + /// and consequently, the closures also only get references. + pub fn map_ref_egld_or_esdt( + &self, + context: Context, + for_egld: D, + for_esdt: F, + ) -> U + where + D: FnOnce(Context, &BigUint) -> U, + F: FnOnce(Context, EsdtTokenPaymentRefs<'_, M>) -> U, + { + self.token_identifier.map_ref_or_else( + context, + |context| for_egld(context, &self.amount), + |context, token_identifier| { + for_esdt( + context, + EsdtTokenPaymentRefs::new(token_identifier, self.token_nonce, &self.amount), + ) + }, + ) + } + pub fn into_tuple(self) -> (EgldOrEsdtTokenIdentifier, u64, BigUint) { (self.token_identifier, self.token_nonce, self.amount) } @@ -78,6 +126,60 @@ impl From> for EgldOrEsdtTokenPayment } } -impl CodecFromSelf for EgldOrEsdtTokenPayment where M: ManagedTypeApi {} +impl TypeAbiFrom<&[u8]> for EgldOrEsdtTokenPayment where M: ManagedTypeApi {} + +impl EgldOrEsdtTokenPayment { + pub fn as_refs(&self) -> EgldOrEsdtTokenPaymentRefs<'_, M> { + EgldOrEsdtTokenPaymentRefs::new(&self.token_identifier, self.token_nonce, &self.amount) + } +} + +/// Similar to `EgldOrEsdtTokenPayment`, but only contains references. +pub struct EgldOrEsdtTokenPaymentRefs<'a, M: ManagedTypeApi> { + pub token_identifier: &'a EgldOrEsdtTokenIdentifier, + pub token_nonce: u64, + pub amount: &'a BigUint, +} + +impl<'a, M: ManagedTypeApi> EgldOrEsdtTokenPaymentRefs<'a, M> { + pub fn new( + token_identifier: &'a EgldOrEsdtTokenIdentifier, + token_nonce: u64, + amount: &'a BigUint, + ) -> EgldOrEsdtTokenPaymentRefs<'a, M> { + EgldOrEsdtTokenPaymentRefs { + token_identifier, + token_nonce, + amount, + } + } + + pub fn to_owned_payment(&self) -> EgldOrEsdtTokenPayment { + EgldOrEsdtTokenPayment { + token_identifier: self.token_identifier.clone(), + token_nonce: self.token_nonce, + amount: self.amount.clone(), + } + } + + pub fn is_empty(&self) -> bool { + self.amount == &0u32 + } -impl CodecFrom<&[u8]> for EgldOrEsdtTokenPayment where M: ManagedTypeApi {} + pub fn map_egld_or_esdt(self, context: Context, for_egld: D, for_esdt: F) -> U + where + D: FnOnce(Context, &BigUint) -> U, + F: FnOnce(Context, EsdtTokenPaymentRefs) -> U, + { + self.token_identifier.map_ref_or_else( + context, + |context| for_egld(context, self.amount), + |context, token_identifier| { + for_esdt( + context, + EsdtTokenPaymentRefs::new(token_identifier, self.token_nonce, self.amount), + ) + }, + ) + } +} diff --git a/framework/base/src/types/managed/wrapped/egld_or_multi_esdt_payment.rs b/framework/base/src/types/managed/wrapped/egld_or_multi_esdt_payment.rs index 653b76d5a0..4c3187e3c9 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_multi_esdt_payment.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_multi_esdt_payment.rs @@ -4,7 +4,6 @@ use crate::{ codec::{ self, derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, - CodecFromSelf, }, types::BigUint, }; @@ -23,4 +22,50 @@ pub enum EgldOrMultiEsdtPayment { MultiEsdt(ManagedVec>), } -impl CodecFromSelf for EgldOrMultiEsdtPayment where M: ManagedTypeApi {} +impl EgldOrMultiEsdtPayment { + pub fn is_empty(&self) -> bool { + match self { + EgldOrMultiEsdtPayment::Egld(egld_value) => egld_value == &0u32, + EgldOrMultiEsdtPayment::MultiEsdt(esdt_payments) => esdt_payments.is_empty(), + } + } +} + +/// The version of `EgldOrMultiEsdtPayment` that contains referrences instead of owned fields. +pub enum EgldOrMultiEsdtPaymentRefs<'a, M: ManagedTypeApi> { + Egld(&'a BigUint), + MultiEsdt(&'a ManagedVec>), +} + +impl EgldOrMultiEsdtPayment { + pub fn as_refs(&self) -> EgldOrMultiEsdtPaymentRefs<'_, M> { + match self { + EgldOrMultiEsdtPayment::Egld(egld_value) => { + EgldOrMultiEsdtPaymentRefs::Egld(egld_value) + }, + EgldOrMultiEsdtPayment::MultiEsdt(esdt_payments) => { + EgldOrMultiEsdtPaymentRefs::MultiEsdt(esdt_payments) + }, + } + } +} + +impl<'a, M: ManagedTypeApi> EgldOrMultiEsdtPaymentRefs<'a, M> { + pub fn to_owned_payment(&self) -> EgldOrMultiEsdtPayment { + match self { + EgldOrMultiEsdtPaymentRefs::Egld(egld_value) => { + EgldOrMultiEsdtPayment::Egld((*egld_value).clone()) + }, + EgldOrMultiEsdtPaymentRefs::MultiEsdt(esdt_payments) => { + EgldOrMultiEsdtPayment::MultiEsdt((*esdt_payments).clone()) + }, + } + } + + pub fn is_empty(&self) -> bool { + match self { + EgldOrMultiEsdtPaymentRefs::Egld(egld_value) => *egld_value == &0u32, + EgldOrMultiEsdtPaymentRefs::MultiEsdt(esdt_payments) => esdt_payments.is_empty(), + } + } +} diff --git a/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs b/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs index 12a0e3defc..fd7af7c51f 100644 --- a/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/encoded_managed_vec_item.rs @@ -1,23 +1,21 @@ -use super::ManagedVecItem; +use super::{ManagedVecItem, ManagedVecItemPayload}; use core::{cmp::Ordering, marker::PhantomData}; pub struct EncodedManagedVecItem where T: ManagedVecItem, - [(); ::PAYLOAD_SIZE]:, { - pub encoded: [u8; ::PAYLOAD_SIZE], + pub encoded: T::PAYLOAD, _phantom: PhantomData, } impl EncodedManagedVecItem where T: ManagedVecItem, - [(); ::PAYLOAD_SIZE]:, { pub(crate) fn decode(&self) -> T { T::from_byte_reader(|item_bytes| { - item_bytes.copy_from_slice(&self.encoded); + item_bytes.copy_from_slice(self.encoded.payload_slice()); }) } } @@ -25,7 +23,6 @@ where impl PartialEq for EncodedManagedVecItem where T: PartialEq + ManagedVecItem, - [(); ::PAYLOAD_SIZE]:, { #[inline] fn eq(&self, other: &Self) -> bool { @@ -33,17 +30,11 @@ where } } -impl Eq for EncodedManagedVecItem -where - T: Eq + ManagedVecItem, - [(); ::PAYLOAD_SIZE]:, -{ -} +impl Eq for EncodedManagedVecItem where T: Eq + ManagedVecItem {} impl PartialOrd for EncodedManagedVecItem where T: PartialOrd + ManagedVecItem, - [(); ::PAYLOAD_SIZE]:, { #[inline] fn partial_cmp(&self, other: &Self) -> Option { @@ -54,7 +45,6 @@ where impl Ord for EncodedManagedVecItem where T: Ord + ManagedVecItem, - [(); ::PAYLOAD_SIZE]:, { fn cmp(&self, other: &Self) -> Ordering { self.decode().cmp(&other.decode()) diff --git a/framework/base/src/types/managed/wrapped/esdt_token_data.rs b/framework/base/src/types/managed/wrapped/esdt_token_data.rs index d4b13afdbe..060a66b942 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_data.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_data.rs @@ -1,4 +1,5 @@ use multiversx_sc_derive::ManagedVecItem; +use unwrap_infallible::UnwrapInfallible; use crate::{ api::ManagedTypeApi, @@ -12,13 +13,12 @@ use crate::{ }; use crate as multiversx_sc; // needed by the TypeAbi generated code -use crate::derive::TypeAbi; +use crate::derive::type_abi; -const DECODE_ATTRIBUTE_ERROR_PREFIX: &[u8] = b"error decoding ESDT attributes: "; +const DECODE_ATTRIBUTE_ERROR_PREFIX: &str = "error decoding ESDT attributes: "; -#[derive( - Clone, TopDecode, TopEncode, NestedDecode, NestedEncode, TypeAbi, Debug, ManagedVecItem, -)] +#[type_abi] +#[derive(Clone, TopDecode, TopEncode, NestedDecode, NestedEncode, Debug, ManagedVecItem)] pub struct EsdtTokenData { pub token_type: EsdtTokenType, pub amount: BigUint, @@ -53,10 +53,10 @@ impl EsdtTokenData { } pub fn decode_attributes(&self) -> T { - let Ok(value) = T::top_decode_or_handle_err( + T::top_decode_or_handle_err( self.attributes.clone(), // TODO: remove clone ExitCodecErrorHandler::::from(DECODE_ATTRIBUTE_ERROR_PREFIX), - ); - value + ) + .unwrap_infallible() } } diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 29391f5381..5aedefb3d8 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -10,12 +10,13 @@ use crate::{ derive::{NestedEncode, TopEncode}, IntoMultiValue, NestedDecode, TopDecode, }, - derive::TypeAbi, + derive::type_abi, }; -use super::ManagedVec; +use super::{ManagedVec, ManagedVecItemPayloadBuffer}; -#[derive(TopEncode, NestedEncode, TypeAbi, Clone, PartialEq, Eq, Debug)] +#[type_abi] +#[derive(TopEncode, NestedEncode, Clone, PartialEq, Eq, Debug)] pub struct EsdtTokenPayment { pub token_identifier: TokenIdentifier, pub token_nonce: u64, @@ -157,7 +158,7 @@ where T: ManagedVecItem, { ManagedVecItem::from_byte_reader(|bytes| { - let size = T::PAYLOAD_SIZE; + let size = T::payload_size(); bytes.copy_from_slice(&arr[*index..*index + size]); *index += size; }) @@ -168,7 +169,7 @@ where T: ManagedVecItem, { ManagedVecItem::to_byte_writer(item, |bytes| { - let size = T::PAYLOAD_SIZE; + let size = T::payload_size(); arr[*index..*index + size].copy_from_slice(bytes); *index += size; }); @@ -184,7 +185,7 @@ impl IntoMultiValue for EsdtTokenPayment { } impl ManagedVecItem for EsdtTokenPayment { - const PAYLOAD_SIZE: usize = 16; + type PAYLOAD = ManagedVecItemPayloadBuffer<16>; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; @@ -221,3 +222,61 @@ impl ManagedVecItem for EsdtTokenPayment { writer(&arr[..]) } } + +/// The version of `EsdtTokenPayment` that contains referrences instead of owned fields. +pub struct EsdtTokenPaymentRefs<'a, M: ManagedTypeApi> { + pub token_identifier: &'a TokenIdentifier, + pub token_nonce: u64, + pub amount: &'a BigUint, +} + +impl EsdtTokenPayment { + pub fn as_refs(&self) -> EsdtTokenPaymentRefs<'_, M> { + EsdtTokenPaymentRefs::new(&self.token_identifier, self.token_nonce, &self.amount) + } +} + +impl<'a, M: ManagedTypeApi> EsdtTokenPaymentRefs<'a, M> { + #[inline] + pub fn new( + token_identifier: &'a TokenIdentifier, + token_nonce: u64, + amount: &'a BigUint, + ) -> Self { + EsdtTokenPaymentRefs { + token_identifier, + token_nonce, + amount, + } + } + + /// Will clone the referenced values. + pub fn to_owned_payment(&self) -> EsdtTokenPayment { + EsdtTokenPayment { + token_identifier: self.token_identifier.clone(), + token_nonce: self.token_nonce, + amount: self.amount.clone(), + } + } +} + +impl From<()> for MultiEsdtPayment { + #[inline] + fn from(_value: ()) -> Self { + MultiEsdtPayment::new() + } +} + +impl From> for MultiEsdtPayment { + #[inline] + fn from(value: EsdtTokenPayment) -> Self { + MultiEsdtPayment::from_single_item(value) + } +} + +impl From<(TokenIdentifier, u64, BigUint)> for MultiEsdtPayment { + #[inline] + fn from(value: (TokenIdentifier, u64, BigUint)) -> Self { + MultiEsdtPayment::from_single_item(value.into()) + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_address.rs b/framework/base/src/types/managed/wrapped/managed_address.rs index 1ce1524bb6..ca871a718b 100644 --- a/framework/base/src/types/managed/wrapped/managed_address.rs +++ b/framework/base/src/types/managed/wrapped/managed_address.rs @@ -1,12 +1,11 @@ use core::convert::{TryFrom, TryInto}; use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::ManagedTypeApi, codec::{ - CodecFrom, CodecFromSelf, DecodeError, DecodeErrorHandler, EncodeErrorHandler, - NestedDecode, NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, - TopDecodeInput, TopEncode, TopEncodeOutput, TryStaticCast, + DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, + NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, }, formatter::{hex_util::encode_bytes_as_hex, FormatByteReceiver, SCLowerHex}, types::{heap::Address, ManagedBuffer, ManagedByteArray, ManagedType}, @@ -200,11 +199,6 @@ where } } -#[derive(Clone)] -pub(crate) struct ManagedBufferSizeContext(pub usize); - -impl TryStaticCast for ManagedBufferSizeContext {} - impl NestedEncode for ManagedAddress where M: ManagedTypeApi, @@ -234,14 +228,27 @@ where } } +impl TypeAbiFrom for ManagedAddress where M: ManagedTypeApi {} +impl TypeAbiFrom<&Self> for ManagedAddress where M: ManagedTypeApi {} + impl TypeAbi for ManagedAddress where M: ManagedTypeApi, { + #[cfg(feature = "alloc")] + type Unmanaged = crate::types::heap::Address; + + #[cfg(not(feature = "alloc"))] + type Unmanaged = Self; + /// `"Address"` instead of `"array32"`. fn type_name() -> TypeName { Address::type_name() } + + fn type_name_rust() -> TypeName { + "ManagedAddress<$API>".into() + } } impl SCLowerHex for ManagedAddress { @@ -250,6 +257,12 @@ impl SCLowerHex for ManagedAddress { } } +impl ManagedAddress { + pub fn hex_expr(&self) -> ManagedBuffer { + self.bytes.buffer.hex_expr() + } +} + impl core::fmt::Debug for ManagedAddress { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("ManagedAddress") @@ -259,18 +272,16 @@ impl core::fmt::Debug for ManagedAddress { } } -impl CodecFromSelf for ManagedAddress where M: ManagedTypeApi {} - -impl CodecFrom<[u8; 32]> for ManagedAddress where M: ManagedTypeApi {} +impl TypeAbiFrom<[u8; 32]> for ManagedAddress where M: ManagedTypeApi {} #[cfg(feature = "alloc")] -impl CodecFrom
for ManagedAddress where M: ManagedTypeApi {} +impl TypeAbiFrom
for ManagedAddress where M: ManagedTypeApi {} #[cfg(feature = "alloc")] -impl CodecFrom<&Address> for ManagedAddress where M: ManagedTypeApi {} +impl TypeAbiFrom<&Address> for ManagedAddress where M: ManagedTypeApi {} #[cfg(feature = "alloc")] -impl CodecFrom> for Address where M: ManagedTypeApi {} +impl TypeAbiFrom> for Address where M: ManagedTypeApi {} #[cfg(feature = "alloc")] -impl CodecFrom<&ManagedAddress> for Address where M: ManagedTypeApi {} +impl TypeAbiFrom<&ManagedAddress> for Address where M: ManagedTypeApi {} diff --git a/framework/base/src/types/managed/wrapped/managed_byte_array.rs b/framework/base/src/types/managed/wrapped/managed_byte_array.rs index ed41ba4951..83e95d332c 100644 --- a/framework/base/src/types/managed/wrapped/managed_byte_array.rs +++ b/framework/base/src/types/managed/wrapped/managed_byte_array.rs @@ -1,7 +1,9 @@ use core::convert::TryFrom; +use alloc::format; + use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::ManagedTypeApi, codec::{ DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, @@ -203,13 +205,24 @@ where } } +impl TypeAbiFrom> for [u8; N] where M: ManagedTypeApi {} + +impl TypeAbiFrom for ManagedByteArray where M: ManagedTypeApi {} +impl TypeAbiFrom<&Self> for ManagedByteArray where M: ManagedTypeApi {} + impl TypeAbi for ManagedByteArray where M: ManagedTypeApi, { + type Unmanaged = [u8; N]; + /// It is semantically equivalent to `[u8; N]`. fn type_name() -> TypeName { - <&[u8; N] as TypeAbi>::type_name() + <[u8; N] as TypeAbi>::type_name() + } + + fn type_name_rust() -> TypeName { + format!("ManagedByteArray<$API, {N}usize>") } } diff --git a/framework/base/src/types/managed/wrapped/managed_decimal.rs b/framework/base/src/types/managed/wrapped/managed_decimal.rs index 39a8263396..89a7c47ca9 100644 --- a/framework/base/src/types/managed/wrapped/managed_decimal.rs +++ b/framework/base/src/types/managed/wrapped/managed_decimal.rs @@ -1,5 +1,5 @@ use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ const_handles, use_raw_handle, BigFloatApiImpl, BigIntApiImpl, ManagedTypeApi, StaticVarApiImpl, @@ -363,7 +363,11 @@ impl PartialEq TypeAbiFrom for ManagedDecimal {} + impl TypeAbi for ManagedDecimal { + type Unmanaged = Self; + fn type_name() -> TypeName { TypeName::from("ManagedDecimal") } @@ -373,13 +377,27 @@ impl TypeAbi for ManagedDecimal { } } +impl TypeAbiFrom + for ManagedDecimal> +{ +} + impl TypeAbi for ManagedDecimal> { + type Unmanaged = Self; + fn type_name() -> TypeName { TypeName::from(alloc::format!("ManagedDecimal<{}>", DECIMALS)) } + fn type_name_rust() -> TypeName { + TypeName::from(alloc::format!( + "ManagedDecimal<$API, ConstDecimals<{}>>", + DECIMALS + )) + } + fn is_variadic() -> bool { false } diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index 64766f43db..ddedbbdb8d 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -1,8 +1,11 @@ use core::marker::PhantomData; -use crate::codec::{ - DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, - NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, +use crate::{ + abi::TypeAbiFrom, + codec::{ + DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, + NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, + }, }; use crate::{ @@ -11,7 +14,7 @@ use crate::{ types::{ManagedRef, ManagedType}, }; -use super::ManagedVecItem; +use super::{ManagedVecItem, ManagedVecItemPayloadBuffer}; /// A very efficient optional managed type. /// @@ -73,9 +76,18 @@ where !self.is_none() } + /// Assumes that value is Some and unwraps without checking. + /// + /// # Safety + /// + /// Must always be called under an `if` checking `.is_some()`, otherwise will lead to undefined behaviour. + pub unsafe fn unwrap_no_check(self) -> T { + T::from_handle(self.handle) + } + pub fn into_option(self) -> Option { if self.is_some() { - Some(T::from_handle(self.handle)) + Some(unsafe { self.unwrap_no_check() }) } else { None } @@ -91,7 +103,7 @@ where pub fn unwrap_or_else T>(self, f: F) -> T { if self.is_some() { - T::from_handle(self.handle) + unsafe { self.unwrap_no_check() } } else { f() } @@ -107,33 +119,33 @@ where F: FnOnce(T) -> U, { if self.is_some() { - ManagedOption::::some(f(T::from_handle(self.handle))) + ManagedOption::::some(f(unsafe { self.unwrap_no_check() })) } else { ManagedOption::::none() } } - pub fn map_or_else(self, default: D, f: F) -> U + pub fn map_or_else(self, context: Context, default: D, f: F) -> R where - D: FnOnce() -> U, - F: FnOnce(T) -> U, + D: FnOnce(Context) -> R, + F: FnOnce(Context, T) -> R, { if self.is_some() { - f(T::from_handle(self.handle)) + f(context, unsafe { self.unwrap_no_check() }) } else { - default() + default(context) } } - pub fn map_ref_or_else(&self, default: D, f: F) -> U + pub fn map_ref_or_else(&self, context: Context, default: D, f: F) -> R where - D: FnOnce() -> U, - F: FnOnce(&T) -> U, + D: FnOnce(Context) -> R, + F: FnOnce(Context, &T) -> R, { if self.is_some() { - f(&T::from_handle(self.handle.clone())) + f(context, &T::from_handle(self.handle.clone())) } else { - default() + default(context) } } } @@ -183,7 +195,7 @@ where M: ManagedTypeApi, T: ManagedType + 'static, { - const PAYLOAD_SIZE: usize = 4; + type PAYLOAD = ManagedVecItemPayloadBuffer<4>; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; @@ -260,16 +272,45 @@ where } } +impl TypeAbiFrom> for ManagedOption +where + M: ManagedTypeApi, + U: ManagedType, + T: ManagedType + TypeAbiFrom, +{ +} + +impl TypeAbiFrom> for ManagedOption +where + M: ManagedTypeApi, + T: ManagedType + TypeAbiFrom, +{ +} + +impl TypeAbiFrom> for Option +where + M: ManagedTypeApi, + U: ManagedType, + T: TypeAbiFrom, +{ +} + impl TypeAbi for ManagedOption where M: ManagedTypeApi, T: ManagedType + TypeAbi, { + type Unmanaged = Option; + /// It is semantically equivalent to any list of `T`. fn type_name() -> TypeName { Option::::type_name() } + fn type_name_rust() -> TypeName { + Option::::type_name_rust() + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/types/managed/wrapped/managed_ref.rs b/framework/base/src/types/managed/wrapped/managed_ref.rs index 748c704956..143d79e1d4 100644 --- a/framework/base/src/types/managed/wrapped/managed_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_ref.rs @@ -54,6 +54,7 @@ where M: ManagedTypeApi, T: ManagedType + Clone, { + /// Syntactic sugar for dereferencing and cloning the object. pub fn clone_value(&self) -> T { self.deref().clone() } diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index f7b8cad171..e37dd872d5 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -1,6 +1,6 @@ use super::EncodedManagedVecItem; use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::{ErrorApiImpl, InvalidSliceError, ManagedTypeApi}, codec::{ DecodeErrorHandler, EncodeErrorHandler, IntoMultiValue, NestedDecode, NestedDecodeInput, @@ -12,7 +12,7 @@ use crate::{ ManagedVecRefIterator, MultiValueEncoded, MultiValueManagedVec, }, }; -use alloc::vec::Vec; +use alloc::{format, vec::Vec}; use core::{ borrow::Borrow, cmp::Ordering, @@ -123,7 +123,7 @@ where /// Number of items. #[inline] pub fn len(&self) -> usize { - self.byte_len() / T::PAYLOAD_SIZE + self.byte_len() / T::payload_size() } #[inline] @@ -132,7 +132,7 @@ where } pub fn try_get(&self, index: usize) -> Option> { - let byte_index = index * T::PAYLOAD_SIZE; + let byte_index = index * T::payload_size(); let mut load_result = Ok(()); let result = unsafe { T::from_byte_reader_as_borrow(|dest_slice| { @@ -178,7 +178,7 @@ where } pub(super) unsafe fn get_unsafe(&self, index: usize) -> T { - let byte_index = index * T::PAYLOAD_SIZE; + let byte_index = index * T::payload_size(); let mut load_result = Ok(()); let result = T::from_byte_reader(|dest_slice| { load_result = self.buffer.load_slice(byte_index, dest_slice); @@ -191,15 +191,15 @@ where } pub fn set(&mut self, index: usize, item: &T) -> Result<(), InvalidSliceError> { - let byte_index = index * T::PAYLOAD_SIZE; + let byte_index = index * T::payload_size(); item.to_byte_writer(|slice| self.buffer.set_slice(byte_index, slice)) } /// Returns a new `ManagedVec`, containing the [start_index, end_index) range of elements. /// Returns `None` if any index is out of range pub fn slice(&self, start_index: usize, end_index: usize) -> Option { - let byte_start = start_index * T::PAYLOAD_SIZE; - let byte_end = end_index * T::PAYLOAD_SIZE; + let byte_start = start_index * T::payload_size(); + let byte_end = end_index * T::payload_size(); let opt_buffer = self.buffer.copy_slice(byte_start, byte_end - byte_start); opt_buffer.map(ManagedVec::new_from_raw_buffer) } @@ -314,10 +314,9 @@ where fn with_self_as_slice(&self, f: F) -> R where F: FnOnce(&[EncodedManagedVecItem]) -> R, - [(); T::PAYLOAD_SIZE]:, { self.buffer.with_buffer_contents(|bytes| { - let item_len = bytes.len() / T::PAYLOAD_SIZE; + let item_len = bytes.len() / T::payload_size(); let values = Self::transmute_slice(bytes, item_len); f(values) }) @@ -326,14 +325,13 @@ where fn with_self_as_slice_mut(&mut self, f: F) where F: FnOnce(&mut [EncodedManagedVecItem]) -> &[EncodedManagedVecItem], - [(); T::PAYLOAD_SIZE]:, { self.buffer.with_buffer_contents_mut(|bytes| { - let item_len = bytes.len() / T::PAYLOAD_SIZE; + let item_len = bytes.len() / T::payload_size(); let values = Self::transmute_slice_mut(bytes, item_len); let result = f(values); - let result_len = result.len() * T::PAYLOAD_SIZE; + let result_len = result.len() * T::payload_size(); Self::transmute_slice(result, result_len) }); } @@ -357,7 +355,6 @@ impl ManagedVec where M: ManagedTypeApi, T: ManagedVecItem + Ord + Debug, - [(); T::PAYLOAD_SIZE]:, { pub fn sort(&mut self) { self.with_self_as_slice_mut(|slice| { @@ -398,10 +395,7 @@ where }); } - pub fn sort_unstable(&mut self) - where - [(); T::PAYLOAD_SIZE]:, - { + pub fn sort_unstable(&mut self) { self.with_self_as_slice_mut(|slice| { slice.sort_unstable(); slice @@ -411,7 +405,6 @@ where pub fn sort_unstable_by(&mut self, mut compare: F) where F: FnMut(&T, &T) -> Ordering, - [(); T::PAYLOAD_SIZE]:, { self.with_self_as_slice_mut(|slice| { slice.sort_unstable_by(|a, b| compare(&a.decode(), &b.decode())); @@ -423,7 +416,6 @@ where where F: FnMut(&T) -> K, K: Ord, - [(); T::PAYLOAD_SIZE]:, { self.with_self_as_slice_mut(|slice| { slice.sort_unstable_by_key(|a| f(&a.decode())); @@ -463,10 +455,7 @@ where M: ManagedTypeApi, T: ManagedVecItem + PartialEq + Debug, { - pub fn dedup(&mut self) - where - [(); T::PAYLOAD_SIZE]:, - { + pub fn dedup(&mut self) { self.with_self_as_slice_mut(|slice| { let same_bucket = |a, b| a == b; let len = slice.len(); @@ -539,7 +528,7 @@ where if self_item != other_item { return false; } - byte_index += T::PAYLOAD_SIZE; + byte_index += T::payload_size(); } true } @@ -678,16 +667,45 @@ where } } +impl TypeAbiFrom> for ManagedVec +where + M: ManagedTypeApi, + U: ManagedVecItem, + T: ManagedVecItem + TypeAbiFrom, +{ +} + +impl TypeAbiFrom> for ManagedVec +where + M: ManagedTypeApi, + T: ManagedVecItem + TypeAbiFrom, +{ +} + +impl TypeAbiFrom> for Vec +where + M: ManagedTypeApi, + U: ManagedVecItem, + T: TypeAbiFrom, +{ +} + impl TypeAbi for ManagedVec where M: ManagedTypeApi, T: ManagedVecItem + TypeAbi, { + type Unmanaged = Vec; + /// It is semantically equivalent to any list of `T`. fn type_name() -> TypeName { <&[T] as TypeAbi>::type_name() } + fn type_name_rust() -> TypeName { + format!("ManagedVec<$API, {}>", T::type_name_rust()) + } + fn provide_type_descriptions(accumulator: &mut TDC) { T::provide_type_descriptions(accumulator); } diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 100a85ec14..648635e143 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -1,4 +1,4 @@ -use core::{borrow::Borrow, mem::MaybeUninit}; +use core::borrow::Borrow; use crate::{ api::ManagedTypeApi, @@ -8,14 +8,16 @@ use crate::{ }, }; +use super::{ManagedVecItemNestedTuple, ManagedVecItemPayload, ManagedVecItemPayloadBuffer}; + /// Types that implement this trait can be items inside a `ManagedVec`. /// All these types need a payload, i.e a representation that gets stored /// in the underlying managed buffer. /// Not all data needs to be stored as payload, for instance for most managed types /// the payload is just the handle, whereas the mai ndata is kept by the VM. pub trait ManagedVecItem: 'static { - /// Size of the data stored in the underlying `ManagedBuffer`. - const PAYLOAD_SIZE: usize; + /// Type managing the underlying binary representation in a ManagedVec.. + type PAYLOAD: ManagedVecItemPayload; /// If true, then the encoding of the item is identical to the payload, /// and no further conversion is necessary @@ -32,6 +34,10 @@ pub trait ManagedVecItem: 'static { /// TODO: wrap other types in readonly wrapper. type Ref<'a>: Borrow; + fn payload_size() -> usize { + Self::PAYLOAD::payload_size() + } + /// Parses given bytes as a an owned object. fn from_byte_reader(reader: Reader) -> Self; @@ -50,7 +56,7 @@ pub trait ManagedVecItem: 'static { macro_rules! impl_int { ($ty:ident, $payload_size:expr) => { impl ManagedVecItem for $ty { - const PAYLOAD_SIZE: usize = $payload_size; + type PAYLOAD = ManagedVecItemPayloadBuffer<$payload_size>; const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; fn from_byte_reader(mut reader: Reader) -> Self { @@ -79,7 +85,7 @@ impl_int! {i32, 4} impl_int! {i64, 8} impl ManagedVecItem for usize { - const PAYLOAD_SIZE: usize = 4; + type PAYLOAD = ManagedVecItemPayloadBuffer<4>; const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; @@ -102,7 +108,7 @@ impl ManagedVecItem for usize { } impl ManagedVecItem for bool { - const PAYLOAD_SIZE: usize = 1; + type PAYLOAD = ManagedVecItemPayloadBuffer<1>; const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; @@ -126,21 +132,22 @@ impl ManagedVecItem for bool { impl ManagedVecItem for Option where - [(); 1 + T::PAYLOAD_SIZE]:, + (u8, (T, ())): ManagedVecItemNestedTuple, T: ManagedVecItem, { - const PAYLOAD_SIZE: usize = 1 + T::PAYLOAD_SIZE; + type PAYLOAD = <(u8, (T, ())) as ManagedVecItemNestedTuple>::PAYLOAD; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = Self; fn from_byte_reader(mut reader: Reader) -> Self { - let mut byte_arr: [u8; 1 + T::PAYLOAD_SIZE] = [0u8; 1 + T::PAYLOAD_SIZE]; - reader(&mut byte_arr[..]); - if byte_arr[0] == 0 { + let mut payload = Self::PAYLOAD::new_buffer(); + let payload_slice = payload.payload_slice_mut(); + reader(payload_slice); + if payload_slice[0] == 0 { None } else { Some(T::from_byte_reader(|bytes| { - bytes.copy_from_slice(&byte_arr[1..]); + bytes.copy_from_slice(&payload_slice[1..]); })) } } @@ -152,21 +159,22 @@ where } fn to_byte_writer R>(&self, mut writer: Writer) -> R { - let mut byte_arr: [u8; 1 + T::PAYLOAD_SIZE] = [0u8; 1 + T::PAYLOAD_SIZE]; + let mut payload = Self::PAYLOAD::new_buffer(); + let slice = payload.payload_slice_mut(); if let Some(t) = self { - byte_arr[0] = 1; + slice[0] = 1; T::to_byte_writer(t, |bytes| { - byte_arr[1..].copy_from_slice(bytes); + slice[1..].copy_from_slice(bytes); }); } - writer(&byte_arr[..]) + writer(slice) } } macro_rules! impl_managed_type { ($ty:ident) => { impl ManagedVecItem for $ty { - const PAYLOAD_SIZE: usize = 4; + type PAYLOAD = ManagedVecItemPayloadBuffer<4>; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = ManagedRef<'a, M, Self>; @@ -200,7 +208,7 @@ impl ManagedVecItem for ManagedByteArray where M: ManagedTypeApi, { - const PAYLOAD_SIZE: usize = 4; + type PAYLOAD = ManagedVecItemPayloadBuffer<4>; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = ManagedRef<'a, M, Self>; @@ -224,56 +232,12 @@ where } } -impl ManagedVecItem for [T; N] -where - [(); T::PAYLOAD_SIZE * N]:, - T: ManagedVecItem, -{ - const PAYLOAD_SIZE: usize = T::PAYLOAD_SIZE * N; - const SKIPS_RESERIALIZATION: bool = T::SKIPS_RESERIALIZATION; - type Ref<'a> = Self; - - fn from_byte_reader(mut reader: Reader) -> Self { - let mut byte_arr: [u8; T::PAYLOAD_SIZE * N] = [0; T::PAYLOAD_SIZE * N]; - reader(&mut byte_arr[..]); - let mut result: [T; N] = unsafe { MaybeUninit::zeroed().assume_init() }; - let mut from_index = 0; - for item in result.iter_mut() { - let to_index = from_index + T::PAYLOAD_SIZE; - *item = T::from_byte_reader(|bytes| { - bytes.copy_from_slice(&byte_arr[from_index..to_index]); - }); - from_index = to_index; - } - result - } - - unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( - reader: Reader, - ) -> Self::Ref<'a> { - Self::from_byte_reader(reader) - } - - fn to_byte_writer R>(&self, mut writer: Writer) -> R { - let mut byte_arr: [u8; T::PAYLOAD_SIZE * N] = [0; T::PAYLOAD_SIZE * N]; - let mut from_index = 0; - for item in self { - let to_index = from_index + T::PAYLOAD_SIZE; - item.to_byte_writer(|bytes| { - byte_arr[from_index..to_index].copy_from_slice(bytes); - }); - from_index = to_index; - } - writer(&byte_arr[..]) - } -} - impl ManagedVecItem for ManagedVec where M: ManagedTypeApi, T: ManagedVecItem, { - const PAYLOAD_SIZE: usize = 4; + type PAYLOAD = ManagedVecItemPayloadBuffer<4>; const SKIPS_RESERIALIZATION: bool = false; type Ref<'a> = ManagedRef<'a, M, Self>; diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs new file mode 100644 index 0000000000..3a25bf4993 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_nested_tuple.rs @@ -0,0 +1,40 @@ +use super::{ + ManagedVecItem, ManagedVecItemEmptyPayload, ManagedVecItemPayload, ManagedVecItemPayloadAdd, +}; + +/// Syntactic sugar, that allows us to more easily represent composite payloads as nested tuples. +pub trait ManagedVecItemNestedTuple { + type PAYLOAD: ManagedVecItemPayload; +} + +/// End of the list. +impl ManagedVecItemNestedTuple for () { + type PAYLOAD = ManagedVecItemEmptyPayload; +} + +impl ManagedVecItemNestedTuple for (Head, Tail) +where + Head: ManagedVecItem, + Tail: ManagedVecItemNestedTuple, + Head::PAYLOAD: ManagedVecItemPayloadAdd, +{ + type PAYLOAD = >::Output; +} + +#[cfg(test)] +pub mod tests { + use super::*; + + #[test] + fn managed_vec_item_nesteds_tuple_test() { + assert_payload_size::<()>(0); + assert_payload_size::<(u8, ())>(1); + assert_payload_size::<(usize, ())>(4); + assert_payload_size::<(usize, (usize, ()))>(8); + assert_payload_size::<(Option, ())>(5); + } + + fn assert_payload_size(expected_size: usize) { + assert_eq!(N::PAYLOAD::payload_size(), expected_size); + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs new file mode 100644 index 0000000000..07adc31a08 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_vec_item_payload.rs @@ -0,0 +1,6234 @@ +/// Describes the binary represetnation of a ManagedVecItem. +/// +/// It is always an array that can be allocated directly on stack. +pub trait ManagedVecItemPayload { + fn new_buffer() -> Self; + + fn payload_size() -> usize; + + fn payload_slice(&self) -> &[u8]; + + fn payload_slice_mut(&mut self) -> &mut [u8]; +} + +/// Empty ManagedVecItem. +/// +/// Only used as type, never as implementation, since all ManagedVecItem have some data in them. +pub struct ManagedVecItemEmptyPayload; + +impl ManagedVecItemPayload for ManagedVecItemEmptyPayload { + fn new_buffer() -> Self { + ManagedVecItemEmptyPayload + } + + fn payload_size() -> usize { + 0 + } + + fn payload_slice(&self) -> &[u8] { + &[] + } + + fn payload_slice_mut(&mut self) -> &mut [u8] { + &mut [] + } +} + +/// The main ManagedVecItemPayload implementation. Uses an array in its implementation. +pub struct ManagedVecItemPayloadBuffer { + buffer: [u8; N], +} + +impl ManagedVecItemPayload for ManagedVecItemPayloadBuffer { + fn new_buffer() -> Self { + ManagedVecItemPayloadBuffer { buffer: [0u8; N] } + } + + fn payload_size() -> usize { + N + } + + fn payload_slice(&self) -> &[u8] { + &self.buffer[..] + } + + fn payload_slice_mut(&mut self) -> &mut [u8] { + &mut self.buffer[..] + } +} + +/// Describes concatantion of smaller payloads into a larger one. +/// +/// There is no runtime implementation, just a type-level addition. +/// +/// Implemented via macros, because generic const expressions are currently unstable. +pub trait ManagedVecItemPayloadAdd: ManagedVecItemPayload +where + Rhs: ManagedVecItemPayload, +{ + type Output: ManagedVecItemPayload; +} + +impl ManagedVecItemPayloadAdd + for ManagedVecItemPayloadBuffer +{ + type Output = Self; +} + +/// Replaces a const generic expression. +/// +/// Remove once const generic expressions are stabilized in Rust. +macro_rules! payload_add { + ($dec1:expr, $dec2:expr, $result_add:expr) => { + impl ManagedVecItemPayloadAdd> + for ManagedVecItemPayloadBuffer<$dec1> + { + type Output = ManagedVecItemPayloadBuffer<$result_add>; + } + }; +} + +payload_add!(1usize, 1usize, 2usize); +payload_add!(1usize, 2usize, 3usize); +payload_add!(1usize, 3usize, 4usize); +payload_add!(1usize, 4usize, 5usize); +payload_add!(1usize, 5usize, 6usize); +payload_add!(1usize, 6usize, 7usize); +payload_add!(1usize, 7usize, 8usize); +payload_add!(1usize, 8usize, 9usize); +payload_add!(1usize, 9usize, 10usize); +payload_add!(1usize, 10usize, 11usize); +payload_add!(1usize, 11usize, 12usize); +payload_add!(1usize, 12usize, 13usize); +payload_add!(1usize, 13usize, 14usize); +payload_add!(1usize, 14usize, 15usize); +payload_add!(1usize, 15usize, 16usize); +payload_add!(1usize, 16usize, 17usize); +payload_add!(1usize, 17usize, 18usize); +payload_add!(1usize, 18usize, 19usize); +payload_add!(1usize, 19usize, 20usize); +payload_add!(1usize, 20usize, 21usize); +payload_add!(1usize, 21usize, 22usize); +payload_add!(1usize, 22usize, 23usize); +payload_add!(1usize, 23usize, 24usize); +payload_add!(1usize, 24usize, 25usize); +payload_add!(1usize, 25usize, 26usize); +payload_add!(1usize, 26usize, 27usize); +payload_add!(1usize, 27usize, 28usize); +payload_add!(1usize, 28usize, 29usize); +payload_add!(1usize, 29usize, 30usize); +payload_add!(1usize, 30usize, 31usize); +payload_add!(1usize, 31usize, 32usize); +payload_add!(1usize, 32usize, 33usize); +payload_add!(1usize, 33usize, 34usize); +payload_add!(1usize, 34usize, 35usize); +payload_add!(1usize, 35usize, 36usize); +payload_add!(1usize, 36usize, 37usize); +payload_add!(1usize, 37usize, 38usize); +payload_add!(1usize, 38usize, 39usize); +payload_add!(1usize, 39usize, 40usize); +payload_add!(1usize, 40usize, 41usize); +payload_add!(1usize, 41usize, 42usize); +payload_add!(1usize, 42usize, 43usize); +payload_add!(1usize, 43usize, 44usize); +payload_add!(1usize, 44usize, 45usize); +payload_add!(1usize, 45usize, 46usize); +payload_add!(1usize, 46usize, 47usize); +payload_add!(1usize, 47usize, 48usize); +payload_add!(1usize, 48usize, 49usize); +payload_add!(1usize, 49usize, 50usize); +payload_add!(1usize, 50usize, 51usize); +payload_add!(1usize, 51usize, 52usize); +payload_add!(1usize, 52usize, 53usize); +payload_add!(1usize, 53usize, 54usize); +payload_add!(1usize, 54usize, 55usize); +payload_add!(1usize, 55usize, 56usize); +payload_add!(1usize, 56usize, 57usize); +payload_add!(1usize, 57usize, 58usize); +payload_add!(1usize, 58usize, 59usize); +payload_add!(1usize, 59usize, 60usize); +payload_add!(1usize, 60usize, 61usize); +payload_add!(1usize, 61usize, 62usize); +payload_add!(1usize, 62usize, 63usize); +payload_add!(1usize, 63usize, 64usize); +payload_add!(1usize, 64usize, 65usize); +payload_add!(1usize, 65usize, 66usize); +payload_add!(1usize, 66usize, 67usize); +payload_add!(1usize, 67usize, 68usize); +payload_add!(1usize, 68usize, 69usize); +payload_add!(1usize, 69usize, 70usize); +payload_add!(1usize, 70usize, 71usize); +payload_add!(1usize, 71usize, 72usize); +payload_add!(1usize, 72usize, 73usize); +payload_add!(1usize, 73usize, 74usize); +payload_add!(1usize, 74usize, 75usize); +payload_add!(1usize, 75usize, 76usize); +payload_add!(1usize, 76usize, 77usize); +payload_add!(1usize, 77usize, 78usize); +payload_add!(1usize, 78usize, 79usize); +payload_add!(1usize, 79usize, 80usize); +payload_add!(1usize, 80usize, 81usize); +payload_add!(1usize, 81usize, 82usize); +payload_add!(1usize, 82usize, 83usize); +payload_add!(1usize, 83usize, 84usize); +payload_add!(1usize, 84usize, 85usize); +payload_add!(1usize, 85usize, 86usize); +payload_add!(1usize, 86usize, 87usize); +payload_add!(1usize, 87usize, 88usize); +payload_add!(1usize, 88usize, 89usize); +payload_add!(1usize, 89usize, 90usize); +payload_add!(1usize, 90usize, 91usize); +payload_add!(1usize, 91usize, 92usize); +payload_add!(1usize, 92usize, 93usize); +payload_add!(1usize, 93usize, 94usize); +payload_add!(1usize, 94usize, 95usize); +payload_add!(1usize, 95usize, 96usize); +payload_add!(1usize, 96usize, 97usize); +payload_add!(1usize, 97usize, 98usize); +payload_add!(1usize, 98usize, 99usize); +payload_add!(1usize, 99usize, 100usize); +payload_add!(1usize, 100usize, 101usize); +payload_add!(1usize, 101usize, 102usize); +payload_add!(1usize, 102usize, 103usize); +payload_add!(1usize, 103usize, 104usize); +payload_add!(1usize, 104usize, 105usize); +payload_add!(1usize, 105usize, 106usize); +payload_add!(1usize, 106usize, 107usize); +payload_add!(1usize, 107usize, 108usize); +payload_add!(1usize, 108usize, 109usize); +payload_add!(1usize, 109usize, 110usize); +payload_add!(1usize, 110usize, 111usize); +payload_add!(1usize, 111usize, 112usize); +payload_add!(1usize, 112usize, 113usize); +payload_add!(1usize, 113usize, 114usize); +payload_add!(1usize, 114usize, 115usize); +payload_add!(1usize, 115usize, 116usize); +payload_add!(1usize, 116usize, 117usize); +payload_add!(1usize, 117usize, 118usize); +payload_add!(1usize, 118usize, 119usize); +payload_add!(1usize, 119usize, 120usize); +payload_add!(1usize, 120usize, 121usize); +payload_add!(1usize, 121usize, 122usize); +payload_add!(1usize, 122usize, 123usize); +payload_add!(1usize, 123usize, 124usize); +payload_add!(1usize, 124usize, 125usize); +payload_add!(1usize, 125usize, 126usize); +payload_add!(1usize, 126usize, 127usize); +payload_add!(1usize, 127usize, 128usize); +payload_add!(1usize, 128usize, 129usize); +payload_add!(2usize, 1usize, 3usize); +payload_add!(2usize, 2usize, 4usize); +payload_add!(2usize, 3usize, 5usize); +payload_add!(2usize, 4usize, 6usize); +payload_add!(2usize, 5usize, 7usize); +payload_add!(2usize, 6usize, 8usize); +payload_add!(2usize, 7usize, 9usize); +payload_add!(2usize, 8usize, 10usize); +payload_add!(2usize, 9usize, 11usize); +payload_add!(2usize, 10usize, 12usize); +payload_add!(2usize, 11usize, 13usize); +payload_add!(2usize, 12usize, 14usize); +payload_add!(2usize, 13usize, 15usize); +payload_add!(2usize, 14usize, 16usize); +payload_add!(2usize, 15usize, 17usize); +payload_add!(2usize, 16usize, 18usize); +payload_add!(2usize, 17usize, 19usize); +payload_add!(2usize, 18usize, 20usize); +payload_add!(2usize, 19usize, 21usize); +payload_add!(2usize, 20usize, 22usize); +payload_add!(2usize, 21usize, 23usize); +payload_add!(2usize, 22usize, 24usize); +payload_add!(2usize, 23usize, 25usize); +payload_add!(2usize, 24usize, 26usize); +payload_add!(2usize, 25usize, 27usize); +payload_add!(2usize, 26usize, 28usize); +payload_add!(2usize, 27usize, 29usize); +payload_add!(2usize, 28usize, 30usize); +payload_add!(2usize, 29usize, 31usize); +payload_add!(2usize, 30usize, 32usize); +payload_add!(2usize, 31usize, 33usize); +payload_add!(2usize, 32usize, 34usize); +payload_add!(2usize, 33usize, 35usize); +payload_add!(2usize, 34usize, 36usize); +payload_add!(2usize, 35usize, 37usize); +payload_add!(2usize, 36usize, 38usize); +payload_add!(2usize, 37usize, 39usize); +payload_add!(2usize, 38usize, 40usize); +payload_add!(2usize, 39usize, 41usize); +payload_add!(2usize, 40usize, 42usize); +payload_add!(2usize, 41usize, 43usize); +payload_add!(2usize, 42usize, 44usize); +payload_add!(2usize, 43usize, 45usize); +payload_add!(2usize, 44usize, 46usize); +payload_add!(2usize, 45usize, 47usize); +payload_add!(2usize, 46usize, 48usize); +payload_add!(2usize, 47usize, 49usize); +payload_add!(2usize, 48usize, 50usize); +payload_add!(2usize, 49usize, 51usize); +payload_add!(2usize, 50usize, 52usize); +payload_add!(2usize, 51usize, 53usize); +payload_add!(2usize, 52usize, 54usize); +payload_add!(2usize, 53usize, 55usize); +payload_add!(2usize, 54usize, 56usize); +payload_add!(2usize, 55usize, 57usize); +payload_add!(2usize, 56usize, 58usize); +payload_add!(2usize, 57usize, 59usize); +payload_add!(2usize, 58usize, 60usize); +payload_add!(2usize, 59usize, 61usize); +payload_add!(2usize, 60usize, 62usize); +payload_add!(2usize, 61usize, 63usize); +payload_add!(2usize, 62usize, 64usize); +payload_add!(2usize, 63usize, 65usize); +payload_add!(2usize, 64usize, 66usize); +payload_add!(2usize, 65usize, 67usize); +payload_add!(2usize, 66usize, 68usize); +payload_add!(2usize, 67usize, 69usize); +payload_add!(2usize, 68usize, 70usize); +payload_add!(2usize, 69usize, 71usize); +payload_add!(2usize, 70usize, 72usize); +payload_add!(2usize, 71usize, 73usize); +payload_add!(2usize, 72usize, 74usize); +payload_add!(2usize, 73usize, 75usize); +payload_add!(2usize, 74usize, 76usize); +payload_add!(2usize, 75usize, 77usize); +payload_add!(2usize, 76usize, 78usize); +payload_add!(2usize, 77usize, 79usize); +payload_add!(2usize, 78usize, 80usize); +payload_add!(2usize, 79usize, 81usize); +payload_add!(2usize, 80usize, 82usize); +payload_add!(2usize, 81usize, 83usize); +payload_add!(2usize, 82usize, 84usize); +payload_add!(2usize, 83usize, 85usize); +payload_add!(2usize, 84usize, 86usize); +payload_add!(2usize, 85usize, 87usize); +payload_add!(2usize, 86usize, 88usize); +payload_add!(2usize, 87usize, 89usize); +payload_add!(2usize, 88usize, 90usize); +payload_add!(2usize, 89usize, 91usize); +payload_add!(2usize, 90usize, 92usize); +payload_add!(2usize, 91usize, 93usize); +payload_add!(2usize, 92usize, 94usize); +payload_add!(2usize, 93usize, 95usize); +payload_add!(2usize, 94usize, 96usize); +payload_add!(2usize, 95usize, 97usize); +payload_add!(2usize, 96usize, 98usize); +payload_add!(2usize, 97usize, 99usize); +payload_add!(2usize, 98usize, 100usize); +payload_add!(2usize, 99usize, 101usize); +payload_add!(2usize, 100usize, 102usize); +payload_add!(2usize, 101usize, 103usize); +payload_add!(2usize, 102usize, 104usize); +payload_add!(2usize, 103usize, 105usize); +payload_add!(2usize, 104usize, 106usize); +payload_add!(2usize, 105usize, 107usize); +payload_add!(2usize, 106usize, 108usize); +payload_add!(2usize, 107usize, 109usize); +payload_add!(2usize, 108usize, 110usize); +payload_add!(2usize, 109usize, 111usize); +payload_add!(2usize, 110usize, 112usize); +payload_add!(2usize, 111usize, 113usize); +payload_add!(2usize, 112usize, 114usize); +payload_add!(2usize, 113usize, 115usize); +payload_add!(2usize, 114usize, 116usize); +payload_add!(2usize, 115usize, 117usize); +payload_add!(2usize, 116usize, 118usize); +payload_add!(2usize, 117usize, 119usize); +payload_add!(2usize, 118usize, 120usize); +payload_add!(2usize, 119usize, 121usize); +payload_add!(2usize, 120usize, 122usize); +payload_add!(2usize, 121usize, 123usize); +payload_add!(2usize, 122usize, 124usize); +payload_add!(2usize, 123usize, 125usize); +payload_add!(2usize, 124usize, 126usize); +payload_add!(2usize, 125usize, 127usize); +payload_add!(2usize, 126usize, 128usize); +payload_add!(2usize, 127usize, 129usize); +payload_add!(2usize, 128usize, 130usize); +payload_add!(3usize, 1usize, 4usize); +payload_add!(3usize, 2usize, 5usize); +payload_add!(3usize, 3usize, 6usize); +payload_add!(3usize, 4usize, 7usize); +payload_add!(3usize, 5usize, 8usize); +payload_add!(3usize, 6usize, 9usize); +payload_add!(3usize, 7usize, 10usize); +payload_add!(3usize, 8usize, 11usize); +payload_add!(3usize, 9usize, 12usize); +payload_add!(3usize, 10usize, 13usize); +payload_add!(3usize, 11usize, 14usize); +payload_add!(3usize, 12usize, 15usize); +payload_add!(3usize, 13usize, 16usize); +payload_add!(3usize, 14usize, 17usize); +payload_add!(3usize, 15usize, 18usize); +payload_add!(3usize, 16usize, 19usize); +payload_add!(3usize, 17usize, 20usize); +payload_add!(3usize, 18usize, 21usize); +payload_add!(3usize, 19usize, 22usize); +payload_add!(3usize, 20usize, 23usize); +payload_add!(3usize, 21usize, 24usize); +payload_add!(3usize, 22usize, 25usize); +payload_add!(3usize, 23usize, 26usize); +payload_add!(3usize, 24usize, 27usize); +payload_add!(3usize, 25usize, 28usize); +payload_add!(3usize, 26usize, 29usize); +payload_add!(3usize, 27usize, 30usize); +payload_add!(3usize, 28usize, 31usize); +payload_add!(3usize, 29usize, 32usize); +payload_add!(3usize, 30usize, 33usize); +payload_add!(3usize, 31usize, 34usize); +payload_add!(3usize, 32usize, 35usize); +payload_add!(3usize, 33usize, 36usize); +payload_add!(3usize, 34usize, 37usize); +payload_add!(3usize, 35usize, 38usize); +payload_add!(3usize, 36usize, 39usize); +payload_add!(3usize, 37usize, 40usize); +payload_add!(3usize, 38usize, 41usize); +payload_add!(3usize, 39usize, 42usize); +payload_add!(3usize, 40usize, 43usize); +payload_add!(3usize, 41usize, 44usize); +payload_add!(3usize, 42usize, 45usize); +payload_add!(3usize, 43usize, 46usize); +payload_add!(3usize, 44usize, 47usize); +payload_add!(3usize, 45usize, 48usize); +payload_add!(3usize, 46usize, 49usize); +payload_add!(3usize, 47usize, 50usize); +payload_add!(3usize, 48usize, 51usize); +payload_add!(3usize, 49usize, 52usize); +payload_add!(3usize, 50usize, 53usize); +payload_add!(3usize, 51usize, 54usize); +payload_add!(3usize, 52usize, 55usize); +payload_add!(3usize, 53usize, 56usize); +payload_add!(3usize, 54usize, 57usize); +payload_add!(3usize, 55usize, 58usize); +payload_add!(3usize, 56usize, 59usize); +payload_add!(3usize, 57usize, 60usize); +payload_add!(3usize, 58usize, 61usize); +payload_add!(3usize, 59usize, 62usize); +payload_add!(3usize, 60usize, 63usize); +payload_add!(3usize, 61usize, 64usize); +payload_add!(3usize, 62usize, 65usize); +payload_add!(3usize, 63usize, 66usize); +payload_add!(3usize, 64usize, 67usize); +payload_add!(3usize, 65usize, 68usize); +payload_add!(3usize, 66usize, 69usize); +payload_add!(3usize, 67usize, 70usize); +payload_add!(3usize, 68usize, 71usize); +payload_add!(3usize, 69usize, 72usize); +payload_add!(3usize, 70usize, 73usize); +payload_add!(3usize, 71usize, 74usize); +payload_add!(3usize, 72usize, 75usize); +payload_add!(3usize, 73usize, 76usize); +payload_add!(3usize, 74usize, 77usize); +payload_add!(3usize, 75usize, 78usize); +payload_add!(3usize, 76usize, 79usize); +payload_add!(3usize, 77usize, 80usize); +payload_add!(3usize, 78usize, 81usize); +payload_add!(3usize, 79usize, 82usize); +payload_add!(3usize, 80usize, 83usize); +payload_add!(3usize, 81usize, 84usize); +payload_add!(3usize, 82usize, 85usize); +payload_add!(3usize, 83usize, 86usize); +payload_add!(3usize, 84usize, 87usize); +payload_add!(3usize, 85usize, 88usize); +payload_add!(3usize, 86usize, 89usize); +payload_add!(3usize, 87usize, 90usize); +payload_add!(3usize, 88usize, 91usize); +payload_add!(3usize, 89usize, 92usize); +payload_add!(3usize, 90usize, 93usize); +payload_add!(3usize, 91usize, 94usize); +payload_add!(3usize, 92usize, 95usize); +payload_add!(3usize, 93usize, 96usize); +payload_add!(3usize, 94usize, 97usize); +payload_add!(3usize, 95usize, 98usize); +payload_add!(3usize, 96usize, 99usize); +payload_add!(3usize, 97usize, 100usize); +payload_add!(3usize, 98usize, 101usize); +payload_add!(3usize, 99usize, 102usize); +payload_add!(3usize, 100usize, 103usize); +payload_add!(3usize, 101usize, 104usize); +payload_add!(3usize, 102usize, 105usize); +payload_add!(3usize, 103usize, 106usize); +payload_add!(3usize, 104usize, 107usize); +payload_add!(3usize, 105usize, 108usize); +payload_add!(3usize, 106usize, 109usize); +payload_add!(3usize, 107usize, 110usize); +payload_add!(3usize, 108usize, 111usize); +payload_add!(3usize, 109usize, 112usize); +payload_add!(3usize, 110usize, 113usize); +payload_add!(3usize, 111usize, 114usize); +payload_add!(3usize, 112usize, 115usize); +payload_add!(3usize, 113usize, 116usize); +payload_add!(3usize, 114usize, 117usize); +payload_add!(3usize, 115usize, 118usize); +payload_add!(3usize, 116usize, 119usize); +payload_add!(3usize, 117usize, 120usize); +payload_add!(3usize, 118usize, 121usize); +payload_add!(3usize, 119usize, 122usize); +payload_add!(3usize, 120usize, 123usize); +payload_add!(3usize, 121usize, 124usize); +payload_add!(3usize, 122usize, 125usize); +payload_add!(3usize, 123usize, 126usize); +payload_add!(3usize, 124usize, 127usize); +payload_add!(3usize, 125usize, 128usize); +payload_add!(3usize, 126usize, 129usize); +payload_add!(3usize, 127usize, 130usize); +payload_add!(3usize, 128usize, 131usize); +payload_add!(4usize, 1usize, 5usize); +payload_add!(4usize, 2usize, 6usize); +payload_add!(4usize, 3usize, 7usize); +payload_add!(4usize, 4usize, 8usize); +payload_add!(4usize, 5usize, 9usize); +payload_add!(4usize, 6usize, 10usize); +payload_add!(4usize, 7usize, 11usize); +payload_add!(4usize, 8usize, 12usize); +payload_add!(4usize, 9usize, 13usize); +payload_add!(4usize, 10usize, 14usize); +payload_add!(4usize, 11usize, 15usize); +payload_add!(4usize, 12usize, 16usize); +payload_add!(4usize, 13usize, 17usize); +payload_add!(4usize, 14usize, 18usize); +payload_add!(4usize, 15usize, 19usize); +payload_add!(4usize, 16usize, 20usize); +payload_add!(4usize, 17usize, 21usize); +payload_add!(4usize, 18usize, 22usize); +payload_add!(4usize, 19usize, 23usize); +payload_add!(4usize, 20usize, 24usize); +payload_add!(4usize, 21usize, 25usize); +payload_add!(4usize, 22usize, 26usize); +payload_add!(4usize, 23usize, 27usize); +payload_add!(4usize, 24usize, 28usize); +payload_add!(4usize, 25usize, 29usize); +payload_add!(4usize, 26usize, 30usize); +payload_add!(4usize, 27usize, 31usize); +payload_add!(4usize, 28usize, 32usize); +payload_add!(4usize, 29usize, 33usize); +payload_add!(4usize, 30usize, 34usize); +payload_add!(4usize, 31usize, 35usize); +payload_add!(4usize, 32usize, 36usize); +payload_add!(4usize, 33usize, 37usize); +payload_add!(4usize, 34usize, 38usize); +payload_add!(4usize, 35usize, 39usize); +payload_add!(4usize, 36usize, 40usize); +payload_add!(4usize, 37usize, 41usize); +payload_add!(4usize, 38usize, 42usize); +payload_add!(4usize, 39usize, 43usize); +payload_add!(4usize, 40usize, 44usize); +payload_add!(4usize, 41usize, 45usize); +payload_add!(4usize, 42usize, 46usize); +payload_add!(4usize, 43usize, 47usize); +payload_add!(4usize, 44usize, 48usize); +payload_add!(4usize, 45usize, 49usize); +payload_add!(4usize, 46usize, 50usize); +payload_add!(4usize, 47usize, 51usize); +payload_add!(4usize, 48usize, 52usize); +payload_add!(4usize, 49usize, 53usize); +payload_add!(4usize, 50usize, 54usize); +payload_add!(4usize, 51usize, 55usize); +payload_add!(4usize, 52usize, 56usize); +payload_add!(4usize, 53usize, 57usize); +payload_add!(4usize, 54usize, 58usize); +payload_add!(4usize, 55usize, 59usize); +payload_add!(4usize, 56usize, 60usize); +payload_add!(4usize, 57usize, 61usize); +payload_add!(4usize, 58usize, 62usize); +payload_add!(4usize, 59usize, 63usize); +payload_add!(4usize, 60usize, 64usize); +payload_add!(4usize, 61usize, 65usize); +payload_add!(4usize, 62usize, 66usize); +payload_add!(4usize, 63usize, 67usize); +payload_add!(4usize, 64usize, 68usize); +payload_add!(4usize, 65usize, 69usize); +payload_add!(4usize, 66usize, 70usize); +payload_add!(4usize, 67usize, 71usize); +payload_add!(4usize, 68usize, 72usize); +payload_add!(4usize, 69usize, 73usize); +payload_add!(4usize, 70usize, 74usize); +payload_add!(4usize, 71usize, 75usize); +payload_add!(4usize, 72usize, 76usize); +payload_add!(4usize, 73usize, 77usize); +payload_add!(4usize, 74usize, 78usize); +payload_add!(4usize, 75usize, 79usize); +payload_add!(4usize, 76usize, 80usize); +payload_add!(4usize, 77usize, 81usize); +payload_add!(4usize, 78usize, 82usize); +payload_add!(4usize, 79usize, 83usize); +payload_add!(4usize, 80usize, 84usize); +payload_add!(4usize, 81usize, 85usize); +payload_add!(4usize, 82usize, 86usize); +payload_add!(4usize, 83usize, 87usize); +payload_add!(4usize, 84usize, 88usize); +payload_add!(4usize, 85usize, 89usize); +payload_add!(4usize, 86usize, 90usize); +payload_add!(4usize, 87usize, 91usize); +payload_add!(4usize, 88usize, 92usize); +payload_add!(4usize, 89usize, 93usize); +payload_add!(4usize, 90usize, 94usize); +payload_add!(4usize, 91usize, 95usize); +payload_add!(4usize, 92usize, 96usize); +payload_add!(4usize, 93usize, 97usize); +payload_add!(4usize, 94usize, 98usize); +payload_add!(4usize, 95usize, 99usize); +payload_add!(4usize, 96usize, 100usize); +payload_add!(4usize, 97usize, 101usize); +payload_add!(4usize, 98usize, 102usize); +payload_add!(4usize, 99usize, 103usize); +payload_add!(4usize, 100usize, 104usize); +payload_add!(4usize, 101usize, 105usize); +payload_add!(4usize, 102usize, 106usize); +payload_add!(4usize, 103usize, 107usize); +payload_add!(4usize, 104usize, 108usize); +payload_add!(4usize, 105usize, 109usize); +payload_add!(4usize, 106usize, 110usize); +payload_add!(4usize, 107usize, 111usize); +payload_add!(4usize, 108usize, 112usize); +payload_add!(4usize, 109usize, 113usize); +payload_add!(4usize, 110usize, 114usize); +payload_add!(4usize, 111usize, 115usize); +payload_add!(4usize, 112usize, 116usize); +payload_add!(4usize, 113usize, 117usize); +payload_add!(4usize, 114usize, 118usize); +payload_add!(4usize, 115usize, 119usize); +payload_add!(4usize, 116usize, 120usize); +payload_add!(4usize, 117usize, 121usize); +payload_add!(4usize, 118usize, 122usize); +payload_add!(4usize, 119usize, 123usize); +payload_add!(4usize, 120usize, 124usize); +payload_add!(4usize, 121usize, 125usize); +payload_add!(4usize, 122usize, 126usize); +payload_add!(4usize, 123usize, 127usize); +payload_add!(4usize, 124usize, 128usize); +payload_add!(4usize, 125usize, 129usize); +payload_add!(4usize, 126usize, 130usize); +payload_add!(4usize, 127usize, 131usize); +payload_add!(4usize, 128usize, 132usize); +payload_add!(5usize, 1usize, 6usize); +payload_add!(5usize, 2usize, 7usize); +payload_add!(5usize, 3usize, 8usize); +payload_add!(5usize, 4usize, 9usize); +payload_add!(5usize, 5usize, 10usize); +payload_add!(5usize, 6usize, 11usize); +payload_add!(5usize, 7usize, 12usize); +payload_add!(5usize, 8usize, 13usize); +payload_add!(5usize, 9usize, 14usize); +payload_add!(5usize, 10usize, 15usize); +payload_add!(5usize, 11usize, 16usize); +payload_add!(5usize, 12usize, 17usize); +payload_add!(5usize, 13usize, 18usize); +payload_add!(5usize, 14usize, 19usize); +payload_add!(5usize, 15usize, 20usize); +payload_add!(5usize, 16usize, 21usize); +payload_add!(5usize, 17usize, 22usize); +payload_add!(5usize, 18usize, 23usize); +payload_add!(5usize, 19usize, 24usize); +payload_add!(5usize, 20usize, 25usize); +payload_add!(5usize, 21usize, 26usize); +payload_add!(5usize, 22usize, 27usize); +payload_add!(5usize, 23usize, 28usize); +payload_add!(5usize, 24usize, 29usize); +payload_add!(5usize, 25usize, 30usize); +payload_add!(5usize, 26usize, 31usize); +payload_add!(5usize, 27usize, 32usize); +payload_add!(5usize, 28usize, 33usize); +payload_add!(5usize, 29usize, 34usize); +payload_add!(5usize, 30usize, 35usize); +payload_add!(5usize, 31usize, 36usize); +payload_add!(5usize, 32usize, 37usize); +payload_add!(5usize, 33usize, 38usize); +payload_add!(5usize, 34usize, 39usize); +payload_add!(5usize, 35usize, 40usize); +payload_add!(5usize, 36usize, 41usize); +payload_add!(5usize, 37usize, 42usize); +payload_add!(5usize, 38usize, 43usize); +payload_add!(5usize, 39usize, 44usize); +payload_add!(5usize, 40usize, 45usize); +payload_add!(5usize, 41usize, 46usize); +payload_add!(5usize, 42usize, 47usize); +payload_add!(5usize, 43usize, 48usize); +payload_add!(5usize, 44usize, 49usize); +payload_add!(5usize, 45usize, 50usize); +payload_add!(5usize, 46usize, 51usize); +payload_add!(5usize, 47usize, 52usize); +payload_add!(5usize, 48usize, 53usize); +payload_add!(5usize, 49usize, 54usize); +payload_add!(5usize, 50usize, 55usize); +payload_add!(5usize, 51usize, 56usize); +payload_add!(5usize, 52usize, 57usize); +payload_add!(5usize, 53usize, 58usize); +payload_add!(5usize, 54usize, 59usize); +payload_add!(5usize, 55usize, 60usize); +payload_add!(5usize, 56usize, 61usize); +payload_add!(5usize, 57usize, 62usize); +payload_add!(5usize, 58usize, 63usize); +payload_add!(5usize, 59usize, 64usize); +payload_add!(5usize, 60usize, 65usize); +payload_add!(5usize, 61usize, 66usize); +payload_add!(5usize, 62usize, 67usize); +payload_add!(5usize, 63usize, 68usize); +payload_add!(5usize, 64usize, 69usize); +payload_add!(5usize, 65usize, 70usize); +payload_add!(5usize, 66usize, 71usize); +payload_add!(5usize, 67usize, 72usize); +payload_add!(5usize, 68usize, 73usize); +payload_add!(5usize, 69usize, 74usize); +payload_add!(5usize, 70usize, 75usize); +payload_add!(5usize, 71usize, 76usize); +payload_add!(5usize, 72usize, 77usize); +payload_add!(5usize, 73usize, 78usize); +payload_add!(5usize, 74usize, 79usize); +payload_add!(5usize, 75usize, 80usize); +payload_add!(5usize, 76usize, 81usize); +payload_add!(5usize, 77usize, 82usize); +payload_add!(5usize, 78usize, 83usize); +payload_add!(5usize, 79usize, 84usize); +payload_add!(5usize, 80usize, 85usize); +payload_add!(5usize, 81usize, 86usize); +payload_add!(5usize, 82usize, 87usize); +payload_add!(5usize, 83usize, 88usize); +payload_add!(5usize, 84usize, 89usize); +payload_add!(5usize, 85usize, 90usize); +payload_add!(5usize, 86usize, 91usize); +payload_add!(5usize, 87usize, 92usize); +payload_add!(5usize, 88usize, 93usize); +payload_add!(5usize, 89usize, 94usize); +payload_add!(5usize, 90usize, 95usize); +payload_add!(5usize, 91usize, 96usize); +payload_add!(5usize, 92usize, 97usize); +payload_add!(5usize, 93usize, 98usize); +payload_add!(5usize, 94usize, 99usize); +payload_add!(5usize, 95usize, 100usize); +payload_add!(5usize, 96usize, 101usize); +payload_add!(5usize, 97usize, 102usize); +payload_add!(5usize, 98usize, 103usize); +payload_add!(5usize, 99usize, 104usize); +payload_add!(5usize, 100usize, 105usize); +payload_add!(5usize, 101usize, 106usize); +payload_add!(5usize, 102usize, 107usize); +payload_add!(5usize, 103usize, 108usize); +payload_add!(5usize, 104usize, 109usize); +payload_add!(5usize, 105usize, 110usize); +payload_add!(5usize, 106usize, 111usize); +payload_add!(5usize, 107usize, 112usize); +payload_add!(5usize, 108usize, 113usize); +payload_add!(5usize, 109usize, 114usize); +payload_add!(5usize, 110usize, 115usize); +payload_add!(5usize, 111usize, 116usize); +payload_add!(5usize, 112usize, 117usize); +payload_add!(5usize, 113usize, 118usize); +payload_add!(5usize, 114usize, 119usize); +payload_add!(5usize, 115usize, 120usize); +payload_add!(5usize, 116usize, 121usize); +payload_add!(5usize, 117usize, 122usize); +payload_add!(5usize, 118usize, 123usize); +payload_add!(5usize, 119usize, 124usize); +payload_add!(5usize, 120usize, 125usize); +payload_add!(5usize, 121usize, 126usize); +payload_add!(5usize, 122usize, 127usize); +payload_add!(5usize, 123usize, 128usize); +payload_add!(5usize, 124usize, 129usize); +payload_add!(5usize, 125usize, 130usize); +payload_add!(5usize, 126usize, 131usize); +payload_add!(5usize, 127usize, 132usize); +payload_add!(5usize, 128usize, 133usize); +payload_add!(6usize, 1usize, 7usize); +payload_add!(6usize, 2usize, 8usize); +payload_add!(6usize, 3usize, 9usize); +payload_add!(6usize, 4usize, 10usize); +payload_add!(6usize, 5usize, 11usize); +payload_add!(6usize, 6usize, 12usize); +payload_add!(6usize, 7usize, 13usize); +payload_add!(6usize, 8usize, 14usize); +payload_add!(6usize, 9usize, 15usize); +payload_add!(6usize, 10usize, 16usize); +payload_add!(6usize, 11usize, 17usize); +payload_add!(6usize, 12usize, 18usize); +payload_add!(6usize, 13usize, 19usize); +payload_add!(6usize, 14usize, 20usize); +payload_add!(6usize, 15usize, 21usize); +payload_add!(6usize, 16usize, 22usize); +payload_add!(6usize, 17usize, 23usize); +payload_add!(6usize, 18usize, 24usize); +payload_add!(6usize, 19usize, 25usize); +payload_add!(6usize, 20usize, 26usize); +payload_add!(6usize, 21usize, 27usize); +payload_add!(6usize, 22usize, 28usize); +payload_add!(6usize, 23usize, 29usize); +payload_add!(6usize, 24usize, 30usize); +payload_add!(6usize, 25usize, 31usize); +payload_add!(6usize, 26usize, 32usize); +payload_add!(6usize, 27usize, 33usize); +payload_add!(6usize, 28usize, 34usize); +payload_add!(6usize, 29usize, 35usize); +payload_add!(6usize, 30usize, 36usize); +payload_add!(6usize, 31usize, 37usize); +payload_add!(6usize, 32usize, 38usize); +payload_add!(6usize, 33usize, 39usize); +payload_add!(6usize, 34usize, 40usize); +payload_add!(6usize, 35usize, 41usize); +payload_add!(6usize, 36usize, 42usize); +payload_add!(6usize, 37usize, 43usize); +payload_add!(6usize, 38usize, 44usize); +payload_add!(6usize, 39usize, 45usize); +payload_add!(6usize, 40usize, 46usize); +payload_add!(6usize, 41usize, 47usize); +payload_add!(6usize, 42usize, 48usize); +payload_add!(6usize, 43usize, 49usize); +payload_add!(6usize, 44usize, 50usize); +payload_add!(6usize, 45usize, 51usize); +payload_add!(6usize, 46usize, 52usize); +payload_add!(6usize, 47usize, 53usize); +payload_add!(6usize, 48usize, 54usize); +payload_add!(6usize, 49usize, 55usize); +payload_add!(6usize, 50usize, 56usize); +payload_add!(6usize, 51usize, 57usize); +payload_add!(6usize, 52usize, 58usize); +payload_add!(6usize, 53usize, 59usize); +payload_add!(6usize, 54usize, 60usize); +payload_add!(6usize, 55usize, 61usize); +payload_add!(6usize, 56usize, 62usize); +payload_add!(6usize, 57usize, 63usize); +payload_add!(6usize, 58usize, 64usize); +payload_add!(6usize, 59usize, 65usize); +payload_add!(6usize, 60usize, 66usize); +payload_add!(6usize, 61usize, 67usize); +payload_add!(6usize, 62usize, 68usize); +payload_add!(6usize, 63usize, 69usize); +payload_add!(6usize, 64usize, 70usize); +payload_add!(6usize, 65usize, 71usize); +payload_add!(6usize, 66usize, 72usize); +payload_add!(6usize, 67usize, 73usize); +payload_add!(6usize, 68usize, 74usize); +payload_add!(6usize, 69usize, 75usize); +payload_add!(6usize, 70usize, 76usize); +payload_add!(6usize, 71usize, 77usize); +payload_add!(6usize, 72usize, 78usize); +payload_add!(6usize, 73usize, 79usize); +payload_add!(6usize, 74usize, 80usize); +payload_add!(6usize, 75usize, 81usize); +payload_add!(6usize, 76usize, 82usize); +payload_add!(6usize, 77usize, 83usize); +payload_add!(6usize, 78usize, 84usize); +payload_add!(6usize, 79usize, 85usize); +payload_add!(6usize, 80usize, 86usize); +payload_add!(6usize, 81usize, 87usize); +payload_add!(6usize, 82usize, 88usize); +payload_add!(6usize, 83usize, 89usize); +payload_add!(6usize, 84usize, 90usize); +payload_add!(6usize, 85usize, 91usize); +payload_add!(6usize, 86usize, 92usize); +payload_add!(6usize, 87usize, 93usize); +payload_add!(6usize, 88usize, 94usize); +payload_add!(6usize, 89usize, 95usize); +payload_add!(6usize, 90usize, 96usize); +payload_add!(6usize, 91usize, 97usize); +payload_add!(6usize, 92usize, 98usize); +payload_add!(6usize, 93usize, 99usize); +payload_add!(6usize, 94usize, 100usize); +payload_add!(6usize, 95usize, 101usize); +payload_add!(6usize, 96usize, 102usize); +payload_add!(6usize, 97usize, 103usize); +payload_add!(6usize, 98usize, 104usize); +payload_add!(6usize, 99usize, 105usize); +payload_add!(6usize, 100usize, 106usize); +payload_add!(6usize, 101usize, 107usize); +payload_add!(6usize, 102usize, 108usize); +payload_add!(6usize, 103usize, 109usize); +payload_add!(6usize, 104usize, 110usize); +payload_add!(6usize, 105usize, 111usize); +payload_add!(6usize, 106usize, 112usize); +payload_add!(6usize, 107usize, 113usize); +payload_add!(6usize, 108usize, 114usize); +payload_add!(6usize, 109usize, 115usize); +payload_add!(6usize, 110usize, 116usize); +payload_add!(6usize, 111usize, 117usize); +payload_add!(6usize, 112usize, 118usize); +payload_add!(6usize, 113usize, 119usize); +payload_add!(6usize, 114usize, 120usize); +payload_add!(6usize, 115usize, 121usize); +payload_add!(6usize, 116usize, 122usize); +payload_add!(6usize, 117usize, 123usize); +payload_add!(6usize, 118usize, 124usize); +payload_add!(6usize, 119usize, 125usize); +payload_add!(6usize, 120usize, 126usize); +payload_add!(6usize, 121usize, 127usize); +payload_add!(6usize, 122usize, 128usize); +payload_add!(6usize, 123usize, 129usize); +payload_add!(6usize, 124usize, 130usize); +payload_add!(6usize, 125usize, 131usize); +payload_add!(6usize, 126usize, 132usize); +payload_add!(6usize, 127usize, 133usize); +payload_add!(6usize, 128usize, 134usize); +payload_add!(7usize, 1usize, 8usize); +payload_add!(7usize, 2usize, 9usize); +payload_add!(7usize, 3usize, 10usize); +payload_add!(7usize, 4usize, 11usize); +payload_add!(7usize, 5usize, 12usize); +payload_add!(7usize, 6usize, 13usize); +payload_add!(7usize, 7usize, 14usize); +payload_add!(7usize, 8usize, 15usize); +payload_add!(7usize, 9usize, 16usize); +payload_add!(7usize, 10usize, 17usize); +payload_add!(7usize, 11usize, 18usize); +payload_add!(7usize, 12usize, 19usize); +payload_add!(7usize, 13usize, 20usize); +payload_add!(7usize, 14usize, 21usize); +payload_add!(7usize, 15usize, 22usize); +payload_add!(7usize, 16usize, 23usize); +payload_add!(7usize, 17usize, 24usize); +payload_add!(7usize, 18usize, 25usize); +payload_add!(7usize, 19usize, 26usize); +payload_add!(7usize, 20usize, 27usize); +payload_add!(7usize, 21usize, 28usize); +payload_add!(7usize, 22usize, 29usize); +payload_add!(7usize, 23usize, 30usize); +payload_add!(7usize, 24usize, 31usize); +payload_add!(7usize, 25usize, 32usize); +payload_add!(7usize, 26usize, 33usize); +payload_add!(7usize, 27usize, 34usize); +payload_add!(7usize, 28usize, 35usize); +payload_add!(7usize, 29usize, 36usize); +payload_add!(7usize, 30usize, 37usize); +payload_add!(7usize, 31usize, 38usize); +payload_add!(7usize, 32usize, 39usize); +payload_add!(7usize, 33usize, 40usize); +payload_add!(7usize, 34usize, 41usize); +payload_add!(7usize, 35usize, 42usize); +payload_add!(7usize, 36usize, 43usize); +payload_add!(7usize, 37usize, 44usize); +payload_add!(7usize, 38usize, 45usize); +payload_add!(7usize, 39usize, 46usize); +payload_add!(7usize, 40usize, 47usize); +payload_add!(7usize, 41usize, 48usize); +payload_add!(7usize, 42usize, 49usize); +payload_add!(7usize, 43usize, 50usize); +payload_add!(7usize, 44usize, 51usize); +payload_add!(7usize, 45usize, 52usize); +payload_add!(7usize, 46usize, 53usize); +payload_add!(7usize, 47usize, 54usize); +payload_add!(7usize, 48usize, 55usize); +payload_add!(7usize, 49usize, 56usize); +payload_add!(7usize, 50usize, 57usize); +payload_add!(7usize, 51usize, 58usize); +payload_add!(7usize, 52usize, 59usize); +payload_add!(7usize, 53usize, 60usize); +payload_add!(7usize, 54usize, 61usize); +payload_add!(7usize, 55usize, 62usize); +payload_add!(7usize, 56usize, 63usize); +payload_add!(7usize, 57usize, 64usize); +payload_add!(7usize, 58usize, 65usize); +payload_add!(7usize, 59usize, 66usize); +payload_add!(7usize, 60usize, 67usize); +payload_add!(7usize, 61usize, 68usize); +payload_add!(7usize, 62usize, 69usize); +payload_add!(7usize, 63usize, 70usize); +payload_add!(7usize, 64usize, 71usize); +payload_add!(7usize, 65usize, 72usize); +payload_add!(7usize, 66usize, 73usize); +payload_add!(7usize, 67usize, 74usize); +payload_add!(7usize, 68usize, 75usize); +payload_add!(7usize, 69usize, 76usize); +payload_add!(7usize, 70usize, 77usize); +payload_add!(7usize, 71usize, 78usize); +payload_add!(7usize, 72usize, 79usize); +payload_add!(7usize, 73usize, 80usize); +payload_add!(7usize, 74usize, 81usize); +payload_add!(7usize, 75usize, 82usize); +payload_add!(7usize, 76usize, 83usize); +payload_add!(7usize, 77usize, 84usize); +payload_add!(7usize, 78usize, 85usize); +payload_add!(7usize, 79usize, 86usize); +payload_add!(7usize, 80usize, 87usize); +payload_add!(7usize, 81usize, 88usize); +payload_add!(7usize, 82usize, 89usize); +payload_add!(7usize, 83usize, 90usize); +payload_add!(7usize, 84usize, 91usize); +payload_add!(7usize, 85usize, 92usize); +payload_add!(7usize, 86usize, 93usize); +payload_add!(7usize, 87usize, 94usize); +payload_add!(7usize, 88usize, 95usize); +payload_add!(7usize, 89usize, 96usize); +payload_add!(7usize, 90usize, 97usize); +payload_add!(7usize, 91usize, 98usize); +payload_add!(7usize, 92usize, 99usize); +payload_add!(7usize, 93usize, 100usize); +payload_add!(7usize, 94usize, 101usize); +payload_add!(7usize, 95usize, 102usize); +payload_add!(7usize, 96usize, 103usize); +payload_add!(7usize, 97usize, 104usize); +payload_add!(7usize, 98usize, 105usize); +payload_add!(7usize, 99usize, 106usize); +payload_add!(7usize, 100usize, 107usize); +payload_add!(7usize, 101usize, 108usize); +payload_add!(7usize, 102usize, 109usize); +payload_add!(7usize, 103usize, 110usize); +payload_add!(7usize, 104usize, 111usize); +payload_add!(7usize, 105usize, 112usize); +payload_add!(7usize, 106usize, 113usize); +payload_add!(7usize, 107usize, 114usize); +payload_add!(7usize, 108usize, 115usize); +payload_add!(7usize, 109usize, 116usize); +payload_add!(7usize, 110usize, 117usize); +payload_add!(7usize, 111usize, 118usize); +payload_add!(7usize, 112usize, 119usize); +payload_add!(7usize, 113usize, 120usize); +payload_add!(7usize, 114usize, 121usize); +payload_add!(7usize, 115usize, 122usize); +payload_add!(7usize, 116usize, 123usize); +payload_add!(7usize, 117usize, 124usize); +payload_add!(7usize, 118usize, 125usize); +payload_add!(7usize, 119usize, 126usize); +payload_add!(7usize, 120usize, 127usize); +payload_add!(7usize, 121usize, 128usize); +payload_add!(7usize, 122usize, 129usize); +payload_add!(7usize, 123usize, 130usize); +payload_add!(7usize, 124usize, 131usize); +payload_add!(7usize, 125usize, 132usize); +payload_add!(7usize, 126usize, 133usize); +payload_add!(7usize, 127usize, 134usize); +payload_add!(7usize, 128usize, 135usize); +payload_add!(8usize, 1usize, 9usize); +payload_add!(8usize, 2usize, 10usize); +payload_add!(8usize, 3usize, 11usize); +payload_add!(8usize, 4usize, 12usize); +payload_add!(8usize, 5usize, 13usize); +payload_add!(8usize, 6usize, 14usize); +payload_add!(8usize, 7usize, 15usize); +payload_add!(8usize, 8usize, 16usize); +payload_add!(8usize, 9usize, 17usize); +payload_add!(8usize, 10usize, 18usize); +payload_add!(8usize, 11usize, 19usize); +payload_add!(8usize, 12usize, 20usize); +payload_add!(8usize, 13usize, 21usize); +payload_add!(8usize, 14usize, 22usize); +payload_add!(8usize, 15usize, 23usize); +payload_add!(8usize, 16usize, 24usize); +payload_add!(8usize, 17usize, 25usize); +payload_add!(8usize, 18usize, 26usize); +payload_add!(8usize, 19usize, 27usize); +payload_add!(8usize, 20usize, 28usize); +payload_add!(8usize, 21usize, 29usize); +payload_add!(8usize, 22usize, 30usize); +payload_add!(8usize, 23usize, 31usize); +payload_add!(8usize, 24usize, 32usize); +payload_add!(8usize, 25usize, 33usize); +payload_add!(8usize, 26usize, 34usize); +payload_add!(8usize, 27usize, 35usize); +payload_add!(8usize, 28usize, 36usize); +payload_add!(8usize, 29usize, 37usize); +payload_add!(8usize, 30usize, 38usize); +payload_add!(8usize, 31usize, 39usize); +payload_add!(8usize, 32usize, 40usize); +payload_add!(8usize, 33usize, 41usize); +payload_add!(8usize, 34usize, 42usize); +payload_add!(8usize, 35usize, 43usize); +payload_add!(8usize, 36usize, 44usize); +payload_add!(8usize, 37usize, 45usize); +payload_add!(8usize, 38usize, 46usize); +payload_add!(8usize, 39usize, 47usize); +payload_add!(8usize, 40usize, 48usize); +payload_add!(8usize, 41usize, 49usize); +payload_add!(8usize, 42usize, 50usize); +payload_add!(8usize, 43usize, 51usize); +payload_add!(8usize, 44usize, 52usize); +payload_add!(8usize, 45usize, 53usize); +payload_add!(8usize, 46usize, 54usize); +payload_add!(8usize, 47usize, 55usize); +payload_add!(8usize, 48usize, 56usize); +payload_add!(8usize, 49usize, 57usize); +payload_add!(8usize, 50usize, 58usize); +payload_add!(8usize, 51usize, 59usize); +payload_add!(8usize, 52usize, 60usize); +payload_add!(8usize, 53usize, 61usize); +payload_add!(8usize, 54usize, 62usize); +payload_add!(8usize, 55usize, 63usize); +payload_add!(8usize, 56usize, 64usize); +payload_add!(8usize, 57usize, 65usize); +payload_add!(8usize, 58usize, 66usize); +payload_add!(8usize, 59usize, 67usize); +payload_add!(8usize, 60usize, 68usize); +payload_add!(8usize, 61usize, 69usize); +payload_add!(8usize, 62usize, 70usize); +payload_add!(8usize, 63usize, 71usize); +payload_add!(8usize, 64usize, 72usize); +payload_add!(8usize, 65usize, 73usize); +payload_add!(8usize, 66usize, 74usize); +payload_add!(8usize, 67usize, 75usize); +payload_add!(8usize, 68usize, 76usize); +payload_add!(8usize, 69usize, 77usize); +payload_add!(8usize, 70usize, 78usize); +payload_add!(8usize, 71usize, 79usize); +payload_add!(8usize, 72usize, 80usize); +payload_add!(8usize, 73usize, 81usize); +payload_add!(8usize, 74usize, 82usize); +payload_add!(8usize, 75usize, 83usize); +payload_add!(8usize, 76usize, 84usize); +payload_add!(8usize, 77usize, 85usize); +payload_add!(8usize, 78usize, 86usize); +payload_add!(8usize, 79usize, 87usize); +payload_add!(8usize, 80usize, 88usize); +payload_add!(8usize, 81usize, 89usize); +payload_add!(8usize, 82usize, 90usize); +payload_add!(8usize, 83usize, 91usize); +payload_add!(8usize, 84usize, 92usize); +payload_add!(8usize, 85usize, 93usize); +payload_add!(8usize, 86usize, 94usize); +payload_add!(8usize, 87usize, 95usize); +payload_add!(8usize, 88usize, 96usize); +payload_add!(8usize, 89usize, 97usize); +payload_add!(8usize, 90usize, 98usize); +payload_add!(8usize, 91usize, 99usize); +payload_add!(8usize, 92usize, 100usize); +payload_add!(8usize, 93usize, 101usize); +payload_add!(8usize, 94usize, 102usize); +payload_add!(8usize, 95usize, 103usize); +payload_add!(8usize, 96usize, 104usize); +payload_add!(8usize, 97usize, 105usize); +payload_add!(8usize, 98usize, 106usize); +payload_add!(8usize, 99usize, 107usize); +payload_add!(8usize, 100usize, 108usize); +payload_add!(8usize, 101usize, 109usize); +payload_add!(8usize, 102usize, 110usize); +payload_add!(8usize, 103usize, 111usize); +payload_add!(8usize, 104usize, 112usize); +payload_add!(8usize, 105usize, 113usize); +payload_add!(8usize, 106usize, 114usize); +payload_add!(8usize, 107usize, 115usize); +payload_add!(8usize, 108usize, 116usize); +payload_add!(8usize, 109usize, 117usize); +payload_add!(8usize, 110usize, 118usize); +payload_add!(8usize, 111usize, 119usize); +payload_add!(8usize, 112usize, 120usize); +payload_add!(8usize, 113usize, 121usize); +payload_add!(8usize, 114usize, 122usize); +payload_add!(8usize, 115usize, 123usize); +payload_add!(8usize, 116usize, 124usize); +payload_add!(8usize, 117usize, 125usize); +payload_add!(8usize, 118usize, 126usize); +payload_add!(8usize, 119usize, 127usize); +payload_add!(8usize, 120usize, 128usize); +payload_add!(8usize, 121usize, 129usize); +payload_add!(8usize, 122usize, 130usize); +payload_add!(8usize, 123usize, 131usize); +payload_add!(8usize, 124usize, 132usize); +payload_add!(8usize, 125usize, 133usize); +payload_add!(8usize, 126usize, 134usize); +payload_add!(8usize, 127usize, 135usize); +payload_add!(8usize, 128usize, 136usize); +payload_add!(9usize, 1usize, 10usize); +payload_add!(9usize, 2usize, 11usize); +payload_add!(9usize, 3usize, 12usize); +payload_add!(9usize, 4usize, 13usize); +payload_add!(9usize, 5usize, 14usize); +payload_add!(9usize, 6usize, 15usize); +payload_add!(9usize, 7usize, 16usize); +payload_add!(9usize, 8usize, 17usize); +payload_add!(9usize, 9usize, 18usize); +payload_add!(9usize, 10usize, 19usize); +payload_add!(9usize, 11usize, 20usize); +payload_add!(9usize, 12usize, 21usize); +payload_add!(9usize, 13usize, 22usize); +payload_add!(9usize, 14usize, 23usize); +payload_add!(9usize, 15usize, 24usize); +payload_add!(9usize, 16usize, 25usize); +payload_add!(9usize, 17usize, 26usize); +payload_add!(9usize, 18usize, 27usize); +payload_add!(9usize, 19usize, 28usize); +payload_add!(9usize, 20usize, 29usize); +payload_add!(9usize, 21usize, 30usize); +payload_add!(9usize, 22usize, 31usize); +payload_add!(9usize, 23usize, 32usize); +payload_add!(9usize, 24usize, 33usize); +payload_add!(9usize, 25usize, 34usize); +payload_add!(9usize, 26usize, 35usize); +payload_add!(9usize, 27usize, 36usize); +payload_add!(9usize, 28usize, 37usize); +payload_add!(9usize, 29usize, 38usize); +payload_add!(9usize, 30usize, 39usize); +payload_add!(9usize, 31usize, 40usize); +payload_add!(9usize, 32usize, 41usize); +payload_add!(9usize, 33usize, 42usize); +payload_add!(9usize, 34usize, 43usize); +payload_add!(9usize, 35usize, 44usize); +payload_add!(9usize, 36usize, 45usize); +payload_add!(9usize, 37usize, 46usize); +payload_add!(9usize, 38usize, 47usize); +payload_add!(9usize, 39usize, 48usize); +payload_add!(9usize, 40usize, 49usize); +payload_add!(9usize, 41usize, 50usize); +payload_add!(9usize, 42usize, 51usize); +payload_add!(9usize, 43usize, 52usize); +payload_add!(9usize, 44usize, 53usize); +payload_add!(9usize, 45usize, 54usize); +payload_add!(9usize, 46usize, 55usize); +payload_add!(9usize, 47usize, 56usize); +payload_add!(9usize, 48usize, 57usize); +payload_add!(9usize, 49usize, 58usize); +payload_add!(9usize, 50usize, 59usize); +payload_add!(9usize, 51usize, 60usize); +payload_add!(9usize, 52usize, 61usize); +payload_add!(9usize, 53usize, 62usize); +payload_add!(9usize, 54usize, 63usize); +payload_add!(9usize, 55usize, 64usize); +payload_add!(9usize, 56usize, 65usize); +payload_add!(9usize, 57usize, 66usize); +payload_add!(9usize, 58usize, 67usize); +payload_add!(9usize, 59usize, 68usize); +payload_add!(9usize, 60usize, 69usize); +payload_add!(9usize, 61usize, 70usize); +payload_add!(9usize, 62usize, 71usize); +payload_add!(9usize, 63usize, 72usize); +payload_add!(9usize, 64usize, 73usize); +payload_add!(9usize, 65usize, 74usize); +payload_add!(9usize, 66usize, 75usize); +payload_add!(9usize, 67usize, 76usize); +payload_add!(9usize, 68usize, 77usize); +payload_add!(9usize, 69usize, 78usize); +payload_add!(9usize, 70usize, 79usize); +payload_add!(9usize, 71usize, 80usize); +payload_add!(9usize, 72usize, 81usize); +payload_add!(9usize, 73usize, 82usize); +payload_add!(9usize, 74usize, 83usize); +payload_add!(9usize, 75usize, 84usize); +payload_add!(9usize, 76usize, 85usize); +payload_add!(9usize, 77usize, 86usize); +payload_add!(9usize, 78usize, 87usize); +payload_add!(9usize, 79usize, 88usize); +payload_add!(9usize, 80usize, 89usize); +payload_add!(9usize, 81usize, 90usize); +payload_add!(9usize, 82usize, 91usize); +payload_add!(9usize, 83usize, 92usize); +payload_add!(9usize, 84usize, 93usize); +payload_add!(9usize, 85usize, 94usize); +payload_add!(9usize, 86usize, 95usize); +payload_add!(9usize, 87usize, 96usize); +payload_add!(9usize, 88usize, 97usize); +payload_add!(9usize, 89usize, 98usize); +payload_add!(9usize, 90usize, 99usize); +payload_add!(9usize, 91usize, 100usize); +payload_add!(9usize, 92usize, 101usize); +payload_add!(9usize, 93usize, 102usize); +payload_add!(9usize, 94usize, 103usize); +payload_add!(9usize, 95usize, 104usize); +payload_add!(9usize, 96usize, 105usize); +payload_add!(9usize, 97usize, 106usize); +payload_add!(9usize, 98usize, 107usize); +payload_add!(9usize, 99usize, 108usize); +payload_add!(9usize, 100usize, 109usize); +payload_add!(9usize, 101usize, 110usize); +payload_add!(9usize, 102usize, 111usize); +payload_add!(9usize, 103usize, 112usize); +payload_add!(9usize, 104usize, 113usize); +payload_add!(9usize, 105usize, 114usize); +payload_add!(9usize, 106usize, 115usize); +payload_add!(9usize, 107usize, 116usize); +payload_add!(9usize, 108usize, 117usize); +payload_add!(9usize, 109usize, 118usize); +payload_add!(9usize, 110usize, 119usize); +payload_add!(9usize, 111usize, 120usize); +payload_add!(9usize, 112usize, 121usize); +payload_add!(9usize, 113usize, 122usize); +payload_add!(9usize, 114usize, 123usize); +payload_add!(9usize, 115usize, 124usize); +payload_add!(9usize, 116usize, 125usize); +payload_add!(9usize, 117usize, 126usize); +payload_add!(9usize, 118usize, 127usize); +payload_add!(9usize, 119usize, 128usize); +payload_add!(9usize, 120usize, 129usize); +payload_add!(9usize, 121usize, 130usize); +payload_add!(9usize, 122usize, 131usize); +payload_add!(9usize, 123usize, 132usize); +payload_add!(9usize, 124usize, 133usize); +payload_add!(9usize, 125usize, 134usize); +payload_add!(9usize, 126usize, 135usize); +payload_add!(9usize, 127usize, 136usize); +payload_add!(9usize, 128usize, 137usize); +payload_add!(10usize, 1usize, 11usize); +payload_add!(10usize, 2usize, 12usize); +payload_add!(10usize, 3usize, 13usize); +payload_add!(10usize, 4usize, 14usize); +payload_add!(10usize, 5usize, 15usize); +payload_add!(10usize, 6usize, 16usize); +payload_add!(10usize, 7usize, 17usize); +payload_add!(10usize, 8usize, 18usize); +payload_add!(10usize, 9usize, 19usize); +payload_add!(10usize, 10usize, 20usize); +payload_add!(10usize, 11usize, 21usize); +payload_add!(10usize, 12usize, 22usize); +payload_add!(10usize, 13usize, 23usize); +payload_add!(10usize, 14usize, 24usize); +payload_add!(10usize, 15usize, 25usize); +payload_add!(10usize, 16usize, 26usize); +payload_add!(10usize, 17usize, 27usize); +payload_add!(10usize, 18usize, 28usize); +payload_add!(10usize, 19usize, 29usize); +payload_add!(10usize, 20usize, 30usize); +payload_add!(10usize, 21usize, 31usize); +payload_add!(10usize, 22usize, 32usize); +payload_add!(10usize, 23usize, 33usize); +payload_add!(10usize, 24usize, 34usize); +payload_add!(10usize, 25usize, 35usize); +payload_add!(10usize, 26usize, 36usize); +payload_add!(10usize, 27usize, 37usize); +payload_add!(10usize, 28usize, 38usize); +payload_add!(10usize, 29usize, 39usize); +payload_add!(10usize, 30usize, 40usize); +payload_add!(10usize, 31usize, 41usize); +payload_add!(10usize, 32usize, 42usize); +payload_add!(10usize, 33usize, 43usize); +payload_add!(10usize, 34usize, 44usize); +payload_add!(10usize, 35usize, 45usize); +payload_add!(10usize, 36usize, 46usize); +payload_add!(10usize, 37usize, 47usize); +payload_add!(10usize, 38usize, 48usize); +payload_add!(10usize, 39usize, 49usize); +payload_add!(10usize, 40usize, 50usize); +payload_add!(10usize, 41usize, 51usize); +payload_add!(10usize, 42usize, 52usize); +payload_add!(10usize, 43usize, 53usize); +payload_add!(10usize, 44usize, 54usize); +payload_add!(10usize, 45usize, 55usize); +payload_add!(10usize, 46usize, 56usize); +payload_add!(10usize, 47usize, 57usize); +payload_add!(10usize, 48usize, 58usize); +payload_add!(10usize, 49usize, 59usize); +payload_add!(10usize, 50usize, 60usize); +payload_add!(10usize, 51usize, 61usize); +payload_add!(10usize, 52usize, 62usize); +payload_add!(10usize, 53usize, 63usize); +payload_add!(10usize, 54usize, 64usize); +payload_add!(10usize, 55usize, 65usize); +payload_add!(10usize, 56usize, 66usize); +payload_add!(10usize, 57usize, 67usize); +payload_add!(10usize, 58usize, 68usize); +payload_add!(10usize, 59usize, 69usize); +payload_add!(10usize, 60usize, 70usize); +payload_add!(10usize, 61usize, 71usize); +payload_add!(10usize, 62usize, 72usize); +payload_add!(10usize, 63usize, 73usize); +payload_add!(10usize, 64usize, 74usize); +payload_add!(10usize, 65usize, 75usize); +payload_add!(10usize, 66usize, 76usize); +payload_add!(10usize, 67usize, 77usize); +payload_add!(10usize, 68usize, 78usize); +payload_add!(10usize, 69usize, 79usize); +payload_add!(10usize, 70usize, 80usize); +payload_add!(10usize, 71usize, 81usize); +payload_add!(10usize, 72usize, 82usize); +payload_add!(10usize, 73usize, 83usize); +payload_add!(10usize, 74usize, 84usize); +payload_add!(10usize, 75usize, 85usize); +payload_add!(10usize, 76usize, 86usize); +payload_add!(10usize, 77usize, 87usize); +payload_add!(10usize, 78usize, 88usize); +payload_add!(10usize, 79usize, 89usize); +payload_add!(10usize, 80usize, 90usize); +payload_add!(10usize, 81usize, 91usize); +payload_add!(10usize, 82usize, 92usize); +payload_add!(10usize, 83usize, 93usize); +payload_add!(10usize, 84usize, 94usize); +payload_add!(10usize, 85usize, 95usize); +payload_add!(10usize, 86usize, 96usize); +payload_add!(10usize, 87usize, 97usize); +payload_add!(10usize, 88usize, 98usize); +payload_add!(10usize, 89usize, 99usize); +payload_add!(10usize, 90usize, 100usize); +payload_add!(10usize, 91usize, 101usize); +payload_add!(10usize, 92usize, 102usize); +payload_add!(10usize, 93usize, 103usize); +payload_add!(10usize, 94usize, 104usize); +payload_add!(10usize, 95usize, 105usize); +payload_add!(10usize, 96usize, 106usize); +payload_add!(10usize, 97usize, 107usize); +payload_add!(10usize, 98usize, 108usize); +payload_add!(10usize, 99usize, 109usize); +payload_add!(10usize, 100usize, 110usize); +payload_add!(10usize, 101usize, 111usize); +payload_add!(10usize, 102usize, 112usize); +payload_add!(10usize, 103usize, 113usize); +payload_add!(10usize, 104usize, 114usize); +payload_add!(10usize, 105usize, 115usize); +payload_add!(10usize, 106usize, 116usize); +payload_add!(10usize, 107usize, 117usize); +payload_add!(10usize, 108usize, 118usize); +payload_add!(10usize, 109usize, 119usize); +payload_add!(10usize, 110usize, 120usize); +payload_add!(10usize, 111usize, 121usize); +payload_add!(10usize, 112usize, 122usize); +payload_add!(10usize, 113usize, 123usize); +payload_add!(10usize, 114usize, 124usize); +payload_add!(10usize, 115usize, 125usize); +payload_add!(10usize, 116usize, 126usize); +payload_add!(10usize, 117usize, 127usize); +payload_add!(10usize, 118usize, 128usize); +payload_add!(10usize, 119usize, 129usize); +payload_add!(10usize, 120usize, 130usize); +payload_add!(10usize, 121usize, 131usize); +payload_add!(10usize, 122usize, 132usize); +payload_add!(10usize, 123usize, 133usize); +payload_add!(10usize, 124usize, 134usize); +payload_add!(10usize, 125usize, 135usize); +payload_add!(10usize, 126usize, 136usize); +payload_add!(10usize, 127usize, 137usize); +payload_add!(10usize, 128usize, 138usize); +payload_add!(11usize, 1usize, 12usize); +payload_add!(11usize, 2usize, 13usize); +payload_add!(11usize, 3usize, 14usize); +payload_add!(11usize, 4usize, 15usize); +payload_add!(11usize, 5usize, 16usize); +payload_add!(11usize, 6usize, 17usize); +payload_add!(11usize, 7usize, 18usize); +payload_add!(11usize, 8usize, 19usize); +payload_add!(11usize, 9usize, 20usize); +payload_add!(11usize, 10usize, 21usize); +payload_add!(11usize, 11usize, 22usize); +payload_add!(11usize, 12usize, 23usize); +payload_add!(11usize, 13usize, 24usize); +payload_add!(11usize, 14usize, 25usize); +payload_add!(11usize, 15usize, 26usize); +payload_add!(11usize, 16usize, 27usize); +payload_add!(11usize, 17usize, 28usize); +payload_add!(11usize, 18usize, 29usize); +payload_add!(11usize, 19usize, 30usize); +payload_add!(11usize, 20usize, 31usize); +payload_add!(11usize, 21usize, 32usize); +payload_add!(11usize, 22usize, 33usize); +payload_add!(11usize, 23usize, 34usize); +payload_add!(11usize, 24usize, 35usize); +payload_add!(11usize, 25usize, 36usize); +payload_add!(11usize, 26usize, 37usize); +payload_add!(11usize, 27usize, 38usize); +payload_add!(11usize, 28usize, 39usize); +payload_add!(11usize, 29usize, 40usize); +payload_add!(11usize, 30usize, 41usize); +payload_add!(11usize, 31usize, 42usize); +payload_add!(11usize, 32usize, 43usize); +payload_add!(11usize, 33usize, 44usize); +payload_add!(11usize, 34usize, 45usize); +payload_add!(11usize, 35usize, 46usize); +payload_add!(11usize, 36usize, 47usize); +payload_add!(11usize, 37usize, 48usize); +payload_add!(11usize, 38usize, 49usize); +payload_add!(11usize, 39usize, 50usize); +payload_add!(11usize, 40usize, 51usize); +payload_add!(11usize, 41usize, 52usize); +payload_add!(11usize, 42usize, 53usize); +payload_add!(11usize, 43usize, 54usize); +payload_add!(11usize, 44usize, 55usize); +payload_add!(11usize, 45usize, 56usize); +payload_add!(11usize, 46usize, 57usize); +payload_add!(11usize, 47usize, 58usize); +payload_add!(11usize, 48usize, 59usize); +payload_add!(11usize, 49usize, 60usize); +payload_add!(11usize, 50usize, 61usize); +payload_add!(11usize, 51usize, 62usize); +payload_add!(11usize, 52usize, 63usize); +payload_add!(11usize, 53usize, 64usize); +payload_add!(11usize, 54usize, 65usize); +payload_add!(11usize, 55usize, 66usize); +payload_add!(11usize, 56usize, 67usize); +payload_add!(11usize, 57usize, 68usize); +payload_add!(11usize, 58usize, 69usize); +payload_add!(11usize, 59usize, 70usize); +payload_add!(11usize, 60usize, 71usize); +payload_add!(11usize, 61usize, 72usize); +payload_add!(11usize, 62usize, 73usize); +payload_add!(11usize, 63usize, 74usize); +payload_add!(11usize, 64usize, 75usize); +payload_add!(11usize, 65usize, 76usize); +payload_add!(11usize, 66usize, 77usize); +payload_add!(11usize, 67usize, 78usize); +payload_add!(11usize, 68usize, 79usize); +payload_add!(11usize, 69usize, 80usize); +payload_add!(11usize, 70usize, 81usize); +payload_add!(11usize, 71usize, 82usize); +payload_add!(11usize, 72usize, 83usize); +payload_add!(11usize, 73usize, 84usize); +payload_add!(11usize, 74usize, 85usize); +payload_add!(11usize, 75usize, 86usize); +payload_add!(11usize, 76usize, 87usize); +payload_add!(11usize, 77usize, 88usize); +payload_add!(11usize, 78usize, 89usize); +payload_add!(11usize, 79usize, 90usize); +payload_add!(11usize, 80usize, 91usize); +payload_add!(11usize, 81usize, 92usize); +payload_add!(11usize, 82usize, 93usize); +payload_add!(11usize, 83usize, 94usize); +payload_add!(11usize, 84usize, 95usize); +payload_add!(11usize, 85usize, 96usize); +payload_add!(11usize, 86usize, 97usize); +payload_add!(11usize, 87usize, 98usize); +payload_add!(11usize, 88usize, 99usize); +payload_add!(11usize, 89usize, 100usize); +payload_add!(11usize, 90usize, 101usize); +payload_add!(11usize, 91usize, 102usize); +payload_add!(11usize, 92usize, 103usize); +payload_add!(11usize, 93usize, 104usize); +payload_add!(11usize, 94usize, 105usize); +payload_add!(11usize, 95usize, 106usize); +payload_add!(11usize, 96usize, 107usize); +payload_add!(11usize, 97usize, 108usize); +payload_add!(11usize, 98usize, 109usize); +payload_add!(11usize, 99usize, 110usize); +payload_add!(11usize, 100usize, 111usize); +payload_add!(11usize, 101usize, 112usize); +payload_add!(11usize, 102usize, 113usize); +payload_add!(11usize, 103usize, 114usize); +payload_add!(11usize, 104usize, 115usize); +payload_add!(11usize, 105usize, 116usize); +payload_add!(11usize, 106usize, 117usize); +payload_add!(11usize, 107usize, 118usize); +payload_add!(11usize, 108usize, 119usize); +payload_add!(11usize, 109usize, 120usize); +payload_add!(11usize, 110usize, 121usize); +payload_add!(11usize, 111usize, 122usize); +payload_add!(11usize, 112usize, 123usize); +payload_add!(11usize, 113usize, 124usize); +payload_add!(11usize, 114usize, 125usize); +payload_add!(11usize, 115usize, 126usize); +payload_add!(11usize, 116usize, 127usize); +payload_add!(11usize, 117usize, 128usize); +payload_add!(11usize, 118usize, 129usize); +payload_add!(11usize, 119usize, 130usize); +payload_add!(11usize, 120usize, 131usize); +payload_add!(11usize, 121usize, 132usize); +payload_add!(11usize, 122usize, 133usize); +payload_add!(11usize, 123usize, 134usize); +payload_add!(11usize, 124usize, 135usize); +payload_add!(11usize, 125usize, 136usize); +payload_add!(11usize, 126usize, 137usize); +payload_add!(11usize, 127usize, 138usize); +payload_add!(11usize, 128usize, 139usize); +payload_add!(12usize, 1usize, 13usize); +payload_add!(12usize, 2usize, 14usize); +payload_add!(12usize, 3usize, 15usize); +payload_add!(12usize, 4usize, 16usize); +payload_add!(12usize, 5usize, 17usize); +payload_add!(12usize, 6usize, 18usize); +payload_add!(12usize, 7usize, 19usize); +payload_add!(12usize, 8usize, 20usize); +payload_add!(12usize, 9usize, 21usize); +payload_add!(12usize, 10usize, 22usize); +payload_add!(12usize, 11usize, 23usize); +payload_add!(12usize, 12usize, 24usize); +payload_add!(12usize, 13usize, 25usize); +payload_add!(12usize, 14usize, 26usize); +payload_add!(12usize, 15usize, 27usize); +payload_add!(12usize, 16usize, 28usize); +payload_add!(12usize, 17usize, 29usize); +payload_add!(12usize, 18usize, 30usize); +payload_add!(12usize, 19usize, 31usize); +payload_add!(12usize, 20usize, 32usize); +payload_add!(12usize, 21usize, 33usize); +payload_add!(12usize, 22usize, 34usize); +payload_add!(12usize, 23usize, 35usize); +payload_add!(12usize, 24usize, 36usize); +payload_add!(12usize, 25usize, 37usize); +payload_add!(12usize, 26usize, 38usize); +payload_add!(12usize, 27usize, 39usize); +payload_add!(12usize, 28usize, 40usize); +payload_add!(12usize, 29usize, 41usize); +payload_add!(12usize, 30usize, 42usize); +payload_add!(12usize, 31usize, 43usize); +payload_add!(12usize, 32usize, 44usize); +payload_add!(12usize, 33usize, 45usize); +payload_add!(12usize, 34usize, 46usize); +payload_add!(12usize, 35usize, 47usize); +payload_add!(12usize, 36usize, 48usize); +payload_add!(12usize, 37usize, 49usize); +payload_add!(12usize, 38usize, 50usize); +payload_add!(12usize, 39usize, 51usize); +payload_add!(12usize, 40usize, 52usize); +payload_add!(12usize, 41usize, 53usize); +payload_add!(12usize, 42usize, 54usize); +payload_add!(12usize, 43usize, 55usize); +payload_add!(12usize, 44usize, 56usize); +payload_add!(12usize, 45usize, 57usize); +payload_add!(12usize, 46usize, 58usize); +payload_add!(12usize, 47usize, 59usize); +payload_add!(12usize, 48usize, 60usize); +payload_add!(12usize, 49usize, 61usize); +payload_add!(12usize, 50usize, 62usize); +payload_add!(12usize, 51usize, 63usize); +payload_add!(12usize, 52usize, 64usize); +payload_add!(12usize, 53usize, 65usize); +payload_add!(12usize, 54usize, 66usize); +payload_add!(12usize, 55usize, 67usize); +payload_add!(12usize, 56usize, 68usize); +payload_add!(12usize, 57usize, 69usize); +payload_add!(12usize, 58usize, 70usize); +payload_add!(12usize, 59usize, 71usize); +payload_add!(12usize, 60usize, 72usize); +payload_add!(12usize, 61usize, 73usize); +payload_add!(12usize, 62usize, 74usize); +payload_add!(12usize, 63usize, 75usize); +payload_add!(12usize, 64usize, 76usize); +payload_add!(12usize, 65usize, 77usize); +payload_add!(12usize, 66usize, 78usize); +payload_add!(12usize, 67usize, 79usize); +payload_add!(12usize, 68usize, 80usize); +payload_add!(12usize, 69usize, 81usize); +payload_add!(12usize, 70usize, 82usize); +payload_add!(12usize, 71usize, 83usize); +payload_add!(12usize, 72usize, 84usize); +payload_add!(12usize, 73usize, 85usize); +payload_add!(12usize, 74usize, 86usize); +payload_add!(12usize, 75usize, 87usize); +payload_add!(12usize, 76usize, 88usize); +payload_add!(12usize, 77usize, 89usize); +payload_add!(12usize, 78usize, 90usize); +payload_add!(12usize, 79usize, 91usize); +payload_add!(12usize, 80usize, 92usize); +payload_add!(12usize, 81usize, 93usize); +payload_add!(12usize, 82usize, 94usize); +payload_add!(12usize, 83usize, 95usize); +payload_add!(12usize, 84usize, 96usize); +payload_add!(12usize, 85usize, 97usize); +payload_add!(12usize, 86usize, 98usize); +payload_add!(12usize, 87usize, 99usize); +payload_add!(12usize, 88usize, 100usize); +payload_add!(12usize, 89usize, 101usize); +payload_add!(12usize, 90usize, 102usize); +payload_add!(12usize, 91usize, 103usize); +payload_add!(12usize, 92usize, 104usize); +payload_add!(12usize, 93usize, 105usize); +payload_add!(12usize, 94usize, 106usize); +payload_add!(12usize, 95usize, 107usize); +payload_add!(12usize, 96usize, 108usize); +payload_add!(12usize, 97usize, 109usize); +payload_add!(12usize, 98usize, 110usize); +payload_add!(12usize, 99usize, 111usize); +payload_add!(12usize, 100usize, 112usize); +payload_add!(12usize, 101usize, 113usize); +payload_add!(12usize, 102usize, 114usize); +payload_add!(12usize, 103usize, 115usize); +payload_add!(12usize, 104usize, 116usize); +payload_add!(12usize, 105usize, 117usize); +payload_add!(12usize, 106usize, 118usize); +payload_add!(12usize, 107usize, 119usize); +payload_add!(12usize, 108usize, 120usize); +payload_add!(12usize, 109usize, 121usize); +payload_add!(12usize, 110usize, 122usize); +payload_add!(12usize, 111usize, 123usize); +payload_add!(12usize, 112usize, 124usize); +payload_add!(12usize, 113usize, 125usize); +payload_add!(12usize, 114usize, 126usize); +payload_add!(12usize, 115usize, 127usize); +payload_add!(12usize, 116usize, 128usize); +payload_add!(12usize, 117usize, 129usize); +payload_add!(12usize, 118usize, 130usize); +payload_add!(12usize, 119usize, 131usize); +payload_add!(12usize, 120usize, 132usize); +payload_add!(12usize, 121usize, 133usize); +payload_add!(12usize, 122usize, 134usize); +payload_add!(12usize, 123usize, 135usize); +payload_add!(12usize, 124usize, 136usize); +payload_add!(12usize, 125usize, 137usize); +payload_add!(12usize, 126usize, 138usize); +payload_add!(12usize, 127usize, 139usize); +payload_add!(12usize, 128usize, 140usize); +payload_add!(13usize, 1usize, 14usize); +payload_add!(13usize, 2usize, 15usize); +payload_add!(13usize, 3usize, 16usize); +payload_add!(13usize, 4usize, 17usize); +payload_add!(13usize, 5usize, 18usize); +payload_add!(13usize, 6usize, 19usize); +payload_add!(13usize, 7usize, 20usize); +payload_add!(13usize, 8usize, 21usize); +payload_add!(13usize, 9usize, 22usize); +payload_add!(13usize, 10usize, 23usize); +payload_add!(13usize, 11usize, 24usize); +payload_add!(13usize, 12usize, 25usize); +payload_add!(13usize, 13usize, 26usize); +payload_add!(13usize, 14usize, 27usize); +payload_add!(13usize, 15usize, 28usize); +payload_add!(13usize, 16usize, 29usize); +payload_add!(13usize, 17usize, 30usize); +payload_add!(13usize, 18usize, 31usize); +payload_add!(13usize, 19usize, 32usize); +payload_add!(13usize, 20usize, 33usize); +payload_add!(13usize, 21usize, 34usize); +payload_add!(13usize, 22usize, 35usize); +payload_add!(13usize, 23usize, 36usize); +payload_add!(13usize, 24usize, 37usize); +payload_add!(13usize, 25usize, 38usize); +payload_add!(13usize, 26usize, 39usize); +payload_add!(13usize, 27usize, 40usize); +payload_add!(13usize, 28usize, 41usize); +payload_add!(13usize, 29usize, 42usize); +payload_add!(13usize, 30usize, 43usize); +payload_add!(13usize, 31usize, 44usize); +payload_add!(13usize, 32usize, 45usize); +payload_add!(13usize, 33usize, 46usize); +payload_add!(13usize, 34usize, 47usize); +payload_add!(13usize, 35usize, 48usize); +payload_add!(13usize, 36usize, 49usize); +payload_add!(13usize, 37usize, 50usize); +payload_add!(13usize, 38usize, 51usize); +payload_add!(13usize, 39usize, 52usize); +payload_add!(13usize, 40usize, 53usize); +payload_add!(13usize, 41usize, 54usize); +payload_add!(13usize, 42usize, 55usize); +payload_add!(13usize, 43usize, 56usize); +payload_add!(13usize, 44usize, 57usize); +payload_add!(13usize, 45usize, 58usize); +payload_add!(13usize, 46usize, 59usize); +payload_add!(13usize, 47usize, 60usize); +payload_add!(13usize, 48usize, 61usize); +payload_add!(13usize, 49usize, 62usize); +payload_add!(13usize, 50usize, 63usize); +payload_add!(13usize, 51usize, 64usize); +payload_add!(13usize, 52usize, 65usize); +payload_add!(13usize, 53usize, 66usize); +payload_add!(13usize, 54usize, 67usize); +payload_add!(13usize, 55usize, 68usize); +payload_add!(13usize, 56usize, 69usize); +payload_add!(13usize, 57usize, 70usize); +payload_add!(13usize, 58usize, 71usize); +payload_add!(13usize, 59usize, 72usize); +payload_add!(13usize, 60usize, 73usize); +payload_add!(13usize, 61usize, 74usize); +payload_add!(13usize, 62usize, 75usize); +payload_add!(13usize, 63usize, 76usize); +payload_add!(13usize, 64usize, 77usize); +payload_add!(13usize, 65usize, 78usize); +payload_add!(13usize, 66usize, 79usize); +payload_add!(13usize, 67usize, 80usize); +payload_add!(13usize, 68usize, 81usize); +payload_add!(13usize, 69usize, 82usize); +payload_add!(13usize, 70usize, 83usize); +payload_add!(13usize, 71usize, 84usize); +payload_add!(13usize, 72usize, 85usize); +payload_add!(13usize, 73usize, 86usize); +payload_add!(13usize, 74usize, 87usize); +payload_add!(13usize, 75usize, 88usize); +payload_add!(13usize, 76usize, 89usize); +payload_add!(13usize, 77usize, 90usize); +payload_add!(13usize, 78usize, 91usize); +payload_add!(13usize, 79usize, 92usize); +payload_add!(13usize, 80usize, 93usize); +payload_add!(13usize, 81usize, 94usize); +payload_add!(13usize, 82usize, 95usize); +payload_add!(13usize, 83usize, 96usize); +payload_add!(13usize, 84usize, 97usize); +payload_add!(13usize, 85usize, 98usize); +payload_add!(13usize, 86usize, 99usize); +payload_add!(13usize, 87usize, 100usize); +payload_add!(13usize, 88usize, 101usize); +payload_add!(13usize, 89usize, 102usize); +payload_add!(13usize, 90usize, 103usize); +payload_add!(13usize, 91usize, 104usize); +payload_add!(13usize, 92usize, 105usize); +payload_add!(13usize, 93usize, 106usize); +payload_add!(13usize, 94usize, 107usize); +payload_add!(13usize, 95usize, 108usize); +payload_add!(13usize, 96usize, 109usize); +payload_add!(13usize, 97usize, 110usize); +payload_add!(13usize, 98usize, 111usize); +payload_add!(13usize, 99usize, 112usize); +payload_add!(13usize, 100usize, 113usize); +payload_add!(13usize, 101usize, 114usize); +payload_add!(13usize, 102usize, 115usize); +payload_add!(13usize, 103usize, 116usize); +payload_add!(13usize, 104usize, 117usize); +payload_add!(13usize, 105usize, 118usize); +payload_add!(13usize, 106usize, 119usize); +payload_add!(13usize, 107usize, 120usize); +payload_add!(13usize, 108usize, 121usize); +payload_add!(13usize, 109usize, 122usize); +payload_add!(13usize, 110usize, 123usize); +payload_add!(13usize, 111usize, 124usize); +payload_add!(13usize, 112usize, 125usize); +payload_add!(13usize, 113usize, 126usize); +payload_add!(13usize, 114usize, 127usize); +payload_add!(13usize, 115usize, 128usize); +payload_add!(13usize, 116usize, 129usize); +payload_add!(13usize, 117usize, 130usize); +payload_add!(13usize, 118usize, 131usize); +payload_add!(13usize, 119usize, 132usize); +payload_add!(13usize, 120usize, 133usize); +payload_add!(13usize, 121usize, 134usize); +payload_add!(13usize, 122usize, 135usize); +payload_add!(13usize, 123usize, 136usize); +payload_add!(13usize, 124usize, 137usize); +payload_add!(13usize, 125usize, 138usize); +payload_add!(13usize, 126usize, 139usize); +payload_add!(13usize, 127usize, 140usize); +payload_add!(13usize, 128usize, 141usize); +payload_add!(14usize, 1usize, 15usize); +payload_add!(14usize, 2usize, 16usize); +payload_add!(14usize, 3usize, 17usize); +payload_add!(14usize, 4usize, 18usize); +payload_add!(14usize, 5usize, 19usize); +payload_add!(14usize, 6usize, 20usize); +payload_add!(14usize, 7usize, 21usize); +payload_add!(14usize, 8usize, 22usize); +payload_add!(14usize, 9usize, 23usize); +payload_add!(14usize, 10usize, 24usize); +payload_add!(14usize, 11usize, 25usize); +payload_add!(14usize, 12usize, 26usize); +payload_add!(14usize, 13usize, 27usize); +payload_add!(14usize, 14usize, 28usize); +payload_add!(14usize, 15usize, 29usize); +payload_add!(14usize, 16usize, 30usize); +payload_add!(14usize, 17usize, 31usize); +payload_add!(14usize, 18usize, 32usize); +payload_add!(14usize, 19usize, 33usize); +payload_add!(14usize, 20usize, 34usize); +payload_add!(14usize, 21usize, 35usize); +payload_add!(14usize, 22usize, 36usize); +payload_add!(14usize, 23usize, 37usize); +payload_add!(14usize, 24usize, 38usize); +payload_add!(14usize, 25usize, 39usize); +payload_add!(14usize, 26usize, 40usize); +payload_add!(14usize, 27usize, 41usize); +payload_add!(14usize, 28usize, 42usize); +payload_add!(14usize, 29usize, 43usize); +payload_add!(14usize, 30usize, 44usize); +payload_add!(14usize, 31usize, 45usize); +payload_add!(14usize, 32usize, 46usize); +payload_add!(14usize, 33usize, 47usize); +payload_add!(14usize, 34usize, 48usize); +payload_add!(14usize, 35usize, 49usize); +payload_add!(14usize, 36usize, 50usize); +payload_add!(14usize, 37usize, 51usize); +payload_add!(14usize, 38usize, 52usize); +payload_add!(14usize, 39usize, 53usize); +payload_add!(14usize, 40usize, 54usize); +payload_add!(14usize, 41usize, 55usize); +payload_add!(14usize, 42usize, 56usize); +payload_add!(14usize, 43usize, 57usize); +payload_add!(14usize, 44usize, 58usize); +payload_add!(14usize, 45usize, 59usize); +payload_add!(14usize, 46usize, 60usize); +payload_add!(14usize, 47usize, 61usize); +payload_add!(14usize, 48usize, 62usize); +payload_add!(14usize, 49usize, 63usize); +payload_add!(14usize, 50usize, 64usize); +payload_add!(14usize, 51usize, 65usize); +payload_add!(14usize, 52usize, 66usize); +payload_add!(14usize, 53usize, 67usize); +payload_add!(14usize, 54usize, 68usize); +payload_add!(14usize, 55usize, 69usize); +payload_add!(14usize, 56usize, 70usize); +payload_add!(14usize, 57usize, 71usize); +payload_add!(14usize, 58usize, 72usize); +payload_add!(14usize, 59usize, 73usize); +payload_add!(14usize, 60usize, 74usize); +payload_add!(14usize, 61usize, 75usize); +payload_add!(14usize, 62usize, 76usize); +payload_add!(14usize, 63usize, 77usize); +payload_add!(14usize, 64usize, 78usize); +payload_add!(14usize, 65usize, 79usize); +payload_add!(14usize, 66usize, 80usize); +payload_add!(14usize, 67usize, 81usize); +payload_add!(14usize, 68usize, 82usize); +payload_add!(14usize, 69usize, 83usize); +payload_add!(14usize, 70usize, 84usize); +payload_add!(14usize, 71usize, 85usize); +payload_add!(14usize, 72usize, 86usize); +payload_add!(14usize, 73usize, 87usize); +payload_add!(14usize, 74usize, 88usize); +payload_add!(14usize, 75usize, 89usize); +payload_add!(14usize, 76usize, 90usize); +payload_add!(14usize, 77usize, 91usize); +payload_add!(14usize, 78usize, 92usize); +payload_add!(14usize, 79usize, 93usize); +payload_add!(14usize, 80usize, 94usize); +payload_add!(14usize, 81usize, 95usize); +payload_add!(14usize, 82usize, 96usize); +payload_add!(14usize, 83usize, 97usize); +payload_add!(14usize, 84usize, 98usize); +payload_add!(14usize, 85usize, 99usize); +payload_add!(14usize, 86usize, 100usize); +payload_add!(14usize, 87usize, 101usize); +payload_add!(14usize, 88usize, 102usize); +payload_add!(14usize, 89usize, 103usize); +payload_add!(14usize, 90usize, 104usize); +payload_add!(14usize, 91usize, 105usize); +payload_add!(14usize, 92usize, 106usize); +payload_add!(14usize, 93usize, 107usize); +payload_add!(14usize, 94usize, 108usize); +payload_add!(14usize, 95usize, 109usize); +payload_add!(14usize, 96usize, 110usize); +payload_add!(14usize, 97usize, 111usize); +payload_add!(14usize, 98usize, 112usize); +payload_add!(14usize, 99usize, 113usize); +payload_add!(14usize, 100usize, 114usize); +payload_add!(14usize, 101usize, 115usize); +payload_add!(14usize, 102usize, 116usize); +payload_add!(14usize, 103usize, 117usize); +payload_add!(14usize, 104usize, 118usize); +payload_add!(14usize, 105usize, 119usize); +payload_add!(14usize, 106usize, 120usize); +payload_add!(14usize, 107usize, 121usize); +payload_add!(14usize, 108usize, 122usize); +payload_add!(14usize, 109usize, 123usize); +payload_add!(14usize, 110usize, 124usize); +payload_add!(14usize, 111usize, 125usize); +payload_add!(14usize, 112usize, 126usize); +payload_add!(14usize, 113usize, 127usize); +payload_add!(14usize, 114usize, 128usize); +payload_add!(14usize, 115usize, 129usize); +payload_add!(14usize, 116usize, 130usize); +payload_add!(14usize, 117usize, 131usize); +payload_add!(14usize, 118usize, 132usize); +payload_add!(14usize, 119usize, 133usize); +payload_add!(14usize, 120usize, 134usize); +payload_add!(14usize, 121usize, 135usize); +payload_add!(14usize, 122usize, 136usize); +payload_add!(14usize, 123usize, 137usize); +payload_add!(14usize, 124usize, 138usize); +payload_add!(14usize, 125usize, 139usize); +payload_add!(14usize, 126usize, 140usize); +payload_add!(14usize, 127usize, 141usize); +payload_add!(14usize, 128usize, 142usize); +payload_add!(15usize, 1usize, 16usize); +payload_add!(15usize, 2usize, 17usize); +payload_add!(15usize, 3usize, 18usize); +payload_add!(15usize, 4usize, 19usize); +payload_add!(15usize, 5usize, 20usize); +payload_add!(15usize, 6usize, 21usize); +payload_add!(15usize, 7usize, 22usize); +payload_add!(15usize, 8usize, 23usize); +payload_add!(15usize, 9usize, 24usize); +payload_add!(15usize, 10usize, 25usize); +payload_add!(15usize, 11usize, 26usize); +payload_add!(15usize, 12usize, 27usize); +payload_add!(15usize, 13usize, 28usize); +payload_add!(15usize, 14usize, 29usize); +payload_add!(15usize, 15usize, 30usize); +payload_add!(15usize, 16usize, 31usize); +payload_add!(15usize, 17usize, 32usize); +payload_add!(15usize, 18usize, 33usize); +payload_add!(15usize, 19usize, 34usize); +payload_add!(15usize, 20usize, 35usize); +payload_add!(15usize, 21usize, 36usize); +payload_add!(15usize, 22usize, 37usize); +payload_add!(15usize, 23usize, 38usize); +payload_add!(15usize, 24usize, 39usize); +payload_add!(15usize, 25usize, 40usize); +payload_add!(15usize, 26usize, 41usize); +payload_add!(15usize, 27usize, 42usize); +payload_add!(15usize, 28usize, 43usize); +payload_add!(15usize, 29usize, 44usize); +payload_add!(15usize, 30usize, 45usize); +payload_add!(15usize, 31usize, 46usize); +payload_add!(15usize, 32usize, 47usize); +payload_add!(15usize, 33usize, 48usize); +payload_add!(15usize, 34usize, 49usize); +payload_add!(15usize, 35usize, 50usize); +payload_add!(15usize, 36usize, 51usize); +payload_add!(15usize, 37usize, 52usize); +payload_add!(15usize, 38usize, 53usize); +payload_add!(15usize, 39usize, 54usize); +payload_add!(15usize, 40usize, 55usize); +payload_add!(15usize, 41usize, 56usize); +payload_add!(15usize, 42usize, 57usize); +payload_add!(15usize, 43usize, 58usize); +payload_add!(15usize, 44usize, 59usize); +payload_add!(15usize, 45usize, 60usize); +payload_add!(15usize, 46usize, 61usize); +payload_add!(15usize, 47usize, 62usize); +payload_add!(15usize, 48usize, 63usize); +payload_add!(15usize, 49usize, 64usize); +payload_add!(15usize, 50usize, 65usize); +payload_add!(15usize, 51usize, 66usize); +payload_add!(15usize, 52usize, 67usize); +payload_add!(15usize, 53usize, 68usize); +payload_add!(15usize, 54usize, 69usize); +payload_add!(15usize, 55usize, 70usize); +payload_add!(15usize, 56usize, 71usize); +payload_add!(15usize, 57usize, 72usize); +payload_add!(15usize, 58usize, 73usize); +payload_add!(15usize, 59usize, 74usize); +payload_add!(15usize, 60usize, 75usize); +payload_add!(15usize, 61usize, 76usize); +payload_add!(15usize, 62usize, 77usize); +payload_add!(15usize, 63usize, 78usize); +payload_add!(15usize, 64usize, 79usize); +payload_add!(15usize, 65usize, 80usize); +payload_add!(15usize, 66usize, 81usize); +payload_add!(15usize, 67usize, 82usize); +payload_add!(15usize, 68usize, 83usize); +payload_add!(15usize, 69usize, 84usize); +payload_add!(15usize, 70usize, 85usize); +payload_add!(15usize, 71usize, 86usize); +payload_add!(15usize, 72usize, 87usize); +payload_add!(15usize, 73usize, 88usize); +payload_add!(15usize, 74usize, 89usize); +payload_add!(15usize, 75usize, 90usize); +payload_add!(15usize, 76usize, 91usize); +payload_add!(15usize, 77usize, 92usize); +payload_add!(15usize, 78usize, 93usize); +payload_add!(15usize, 79usize, 94usize); +payload_add!(15usize, 80usize, 95usize); +payload_add!(15usize, 81usize, 96usize); +payload_add!(15usize, 82usize, 97usize); +payload_add!(15usize, 83usize, 98usize); +payload_add!(15usize, 84usize, 99usize); +payload_add!(15usize, 85usize, 100usize); +payload_add!(15usize, 86usize, 101usize); +payload_add!(15usize, 87usize, 102usize); +payload_add!(15usize, 88usize, 103usize); +payload_add!(15usize, 89usize, 104usize); +payload_add!(15usize, 90usize, 105usize); +payload_add!(15usize, 91usize, 106usize); +payload_add!(15usize, 92usize, 107usize); +payload_add!(15usize, 93usize, 108usize); +payload_add!(15usize, 94usize, 109usize); +payload_add!(15usize, 95usize, 110usize); +payload_add!(15usize, 96usize, 111usize); +payload_add!(15usize, 97usize, 112usize); +payload_add!(15usize, 98usize, 113usize); +payload_add!(15usize, 99usize, 114usize); +payload_add!(15usize, 100usize, 115usize); +payload_add!(15usize, 101usize, 116usize); +payload_add!(15usize, 102usize, 117usize); +payload_add!(15usize, 103usize, 118usize); +payload_add!(15usize, 104usize, 119usize); +payload_add!(15usize, 105usize, 120usize); +payload_add!(15usize, 106usize, 121usize); +payload_add!(15usize, 107usize, 122usize); +payload_add!(15usize, 108usize, 123usize); +payload_add!(15usize, 109usize, 124usize); +payload_add!(15usize, 110usize, 125usize); +payload_add!(15usize, 111usize, 126usize); +payload_add!(15usize, 112usize, 127usize); +payload_add!(15usize, 113usize, 128usize); +payload_add!(15usize, 114usize, 129usize); +payload_add!(15usize, 115usize, 130usize); +payload_add!(15usize, 116usize, 131usize); +payload_add!(15usize, 117usize, 132usize); +payload_add!(15usize, 118usize, 133usize); +payload_add!(15usize, 119usize, 134usize); +payload_add!(15usize, 120usize, 135usize); +payload_add!(15usize, 121usize, 136usize); +payload_add!(15usize, 122usize, 137usize); +payload_add!(15usize, 123usize, 138usize); +payload_add!(15usize, 124usize, 139usize); +payload_add!(15usize, 125usize, 140usize); +payload_add!(15usize, 126usize, 141usize); +payload_add!(15usize, 127usize, 142usize); +payload_add!(15usize, 128usize, 143usize); +payload_add!(16usize, 1usize, 17usize); +payload_add!(16usize, 2usize, 18usize); +payload_add!(16usize, 3usize, 19usize); +payload_add!(16usize, 4usize, 20usize); +payload_add!(16usize, 5usize, 21usize); +payload_add!(16usize, 6usize, 22usize); +payload_add!(16usize, 7usize, 23usize); +payload_add!(16usize, 8usize, 24usize); +payload_add!(16usize, 9usize, 25usize); +payload_add!(16usize, 10usize, 26usize); +payload_add!(16usize, 11usize, 27usize); +payload_add!(16usize, 12usize, 28usize); +payload_add!(16usize, 13usize, 29usize); +payload_add!(16usize, 14usize, 30usize); +payload_add!(16usize, 15usize, 31usize); +payload_add!(16usize, 16usize, 32usize); +payload_add!(16usize, 17usize, 33usize); +payload_add!(16usize, 18usize, 34usize); +payload_add!(16usize, 19usize, 35usize); +payload_add!(16usize, 20usize, 36usize); +payload_add!(16usize, 21usize, 37usize); +payload_add!(16usize, 22usize, 38usize); +payload_add!(16usize, 23usize, 39usize); +payload_add!(16usize, 24usize, 40usize); +payload_add!(16usize, 25usize, 41usize); +payload_add!(16usize, 26usize, 42usize); +payload_add!(16usize, 27usize, 43usize); +payload_add!(16usize, 28usize, 44usize); +payload_add!(16usize, 29usize, 45usize); +payload_add!(16usize, 30usize, 46usize); +payload_add!(16usize, 31usize, 47usize); +payload_add!(16usize, 32usize, 48usize); +payload_add!(16usize, 33usize, 49usize); +payload_add!(16usize, 34usize, 50usize); +payload_add!(16usize, 35usize, 51usize); +payload_add!(16usize, 36usize, 52usize); +payload_add!(16usize, 37usize, 53usize); +payload_add!(16usize, 38usize, 54usize); +payload_add!(16usize, 39usize, 55usize); +payload_add!(16usize, 40usize, 56usize); +payload_add!(16usize, 41usize, 57usize); +payload_add!(16usize, 42usize, 58usize); +payload_add!(16usize, 43usize, 59usize); +payload_add!(16usize, 44usize, 60usize); +payload_add!(16usize, 45usize, 61usize); +payload_add!(16usize, 46usize, 62usize); +payload_add!(16usize, 47usize, 63usize); +payload_add!(16usize, 48usize, 64usize); +payload_add!(16usize, 49usize, 65usize); +payload_add!(16usize, 50usize, 66usize); +payload_add!(16usize, 51usize, 67usize); +payload_add!(16usize, 52usize, 68usize); +payload_add!(16usize, 53usize, 69usize); +payload_add!(16usize, 54usize, 70usize); +payload_add!(16usize, 55usize, 71usize); +payload_add!(16usize, 56usize, 72usize); +payload_add!(16usize, 57usize, 73usize); +payload_add!(16usize, 58usize, 74usize); +payload_add!(16usize, 59usize, 75usize); +payload_add!(16usize, 60usize, 76usize); +payload_add!(16usize, 61usize, 77usize); +payload_add!(16usize, 62usize, 78usize); +payload_add!(16usize, 63usize, 79usize); +payload_add!(16usize, 64usize, 80usize); +payload_add!(16usize, 65usize, 81usize); +payload_add!(16usize, 66usize, 82usize); +payload_add!(16usize, 67usize, 83usize); +payload_add!(16usize, 68usize, 84usize); +payload_add!(16usize, 69usize, 85usize); +payload_add!(16usize, 70usize, 86usize); +payload_add!(16usize, 71usize, 87usize); +payload_add!(16usize, 72usize, 88usize); +payload_add!(16usize, 73usize, 89usize); +payload_add!(16usize, 74usize, 90usize); +payload_add!(16usize, 75usize, 91usize); +payload_add!(16usize, 76usize, 92usize); +payload_add!(16usize, 77usize, 93usize); +payload_add!(16usize, 78usize, 94usize); +payload_add!(16usize, 79usize, 95usize); +payload_add!(16usize, 80usize, 96usize); +payload_add!(16usize, 81usize, 97usize); +payload_add!(16usize, 82usize, 98usize); +payload_add!(16usize, 83usize, 99usize); +payload_add!(16usize, 84usize, 100usize); +payload_add!(16usize, 85usize, 101usize); +payload_add!(16usize, 86usize, 102usize); +payload_add!(16usize, 87usize, 103usize); +payload_add!(16usize, 88usize, 104usize); +payload_add!(16usize, 89usize, 105usize); +payload_add!(16usize, 90usize, 106usize); +payload_add!(16usize, 91usize, 107usize); +payload_add!(16usize, 92usize, 108usize); +payload_add!(16usize, 93usize, 109usize); +payload_add!(16usize, 94usize, 110usize); +payload_add!(16usize, 95usize, 111usize); +payload_add!(16usize, 96usize, 112usize); +payload_add!(16usize, 97usize, 113usize); +payload_add!(16usize, 98usize, 114usize); +payload_add!(16usize, 99usize, 115usize); +payload_add!(16usize, 100usize, 116usize); +payload_add!(16usize, 101usize, 117usize); +payload_add!(16usize, 102usize, 118usize); +payload_add!(16usize, 103usize, 119usize); +payload_add!(16usize, 104usize, 120usize); +payload_add!(16usize, 105usize, 121usize); +payload_add!(16usize, 106usize, 122usize); +payload_add!(16usize, 107usize, 123usize); +payload_add!(16usize, 108usize, 124usize); +payload_add!(16usize, 109usize, 125usize); +payload_add!(16usize, 110usize, 126usize); +payload_add!(16usize, 111usize, 127usize); +payload_add!(16usize, 112usize, 128usize); +payload_add!(16usize, 113usize, 129usize); +payload_add!(16usize, 114usize, 130usize); +payload_add!(16usize, 115usize, 131usize); +payload_add!(16usize, 116usize, 132usize); +payload_add!(16usize, 117usize, 133usize); +payload_add!(16usize, 118usize, 134usize); +payload_add!(16usize, 119usize, 135usize); +payload_add!(16usize, 120usize, 136usize); +payload_add!(16usize, 121usize, 137usize); +payload_add!(16usize, 122usize, 138usize); +payload_add!(16usize, 123usize, 139usize); +payload_add!(16usize, 124usize, 140usize); +payload_add!(16usize, 125usize, 141usize); +payload_add!(16usize, 126usize, 142usize); +payload_add!(16usize, 127usize, 143usize); +payload_add!(16usize, 128usize, 144usize); +payload_add!(17usize, 1usize, 18usize); +payload_add!(17usize, 2usize, 19usize); +payload_add!(17usize, 3usize, 20usize); +payload_add!(17usize, 4usize, 21usize); +payload_add!(17usize, 5usize, 22usize); +payload_add!(17usize, 6usize, 23usize); +payload_add!(17usize, 7usize, 24usize); +payload_add!(17usize, 8usize, 25usize); +payload_add!(17usize, 9usize, 26usize); +payload_add!(17usize, 10usize, 27usize); +payload_add!(17usize, 11usize, 28usize); +payload_add!(17usize, 12usize, 29usize); +payload_add!(17usize, 13usize, 30usize); +payload_add!(17usize, 14usize, 31usize); +payload_add!(17usize, 15usize, 32usize); +payload_add!(17usize, 16usize, 33usize); +payload_add!(17usize, 17usize, 34usize); +payload_add!(17usize, 18usize, 35usize); +payload_add!(17usize, 19usize, 36usize); +payload_add!(17usize, 20usize, 37usize); +payload_add!(17usize, 21usize, 38usize); +payload_add!(17usize, 22usize, 39usize); +payload_add!(17usize, 23usize, 40usize); +payload_add!(17usize, 24usize, 41usize); +payload_add!(17usize, 25usize, 42usize); +payload_add!(17usize, 26usize, 43usize); +payload_add!(17usize, 27usize, 44usize); +payload_add!(17usize, 28usize, 45usize); +payload_add!(17usize, 29usize, 46usize); +payload_add!(17usize, 30usize, 47usize); +payload_add!(17usize, 31usize, 48usize); +payload_add!(17usize, 32usize, 49usize); +payload_add!(17usize, 33usize, 50usize); +payload_add!(17usize, 34usize, 51usize); +payload_add!(17usize, 35usize, 52usize); +payload_add!(17usize, 36usize, 53usize); +payload_add!(17usize, 37usize, 54usize); +payload_add!(17usize, 38usize, 55usize); +payload_add!(17usize, 39usize, 56usize); +payload_add!(17usize, 40usize, 57usize); +payload_add!(17usize, 41usize, 58usize); +payload_add!(17usize, 42usize, 59usize); +payload_add!(17usize, 43usize, 60usize); +payload_add!(17usize, 44usize, 61usize); +payload_add!(17usize, 45usize, 62usize); +payload_add!(17usize, 46usize, 63usize); +payload_add!(17usize, 47usize, 64usize); +payload_add!(17usize, 48usize, 65usize); +payload_add!(17usize, 49usize, 66usize); +payload_add!(17usize, 50usize, 67usize); +payload_add!(17usize, 51usize, 68usize); +payload_add!(17usize, 52usize, 69usize); +payload_add!(17usize, 53usize, 70usize); +payload_add!(17usize, 54usize, 71usize); +payload_add!(17usize, 55usize, 72usize); +payload_add!(17usize, 56usize, 73usize); +payload_add!(17usize, 57usize, 74usize); +payload_add!(17usize, 58usize, 75usize); +payload_add!(17usize, 59usize, 76usize); +payload_add!(17usize, 60usize, 77usize); +payload_add!(17usize, 61usize, 78usize); +payload_add!(17usize, 62usize, 79usize); +payload_add!(17usize, 63usize, 80usize); +payload_add!(17usize, 64usize, 81usize); +payload_add!(17usize, 65usize, 82usize); +payload_add!(17usize, 66usize, 83usize); +payload_add!(17usize, 67usize, 84usize); +payload_add!(17usize, 68usize, 85usize); +payload_add!(17usize, 69usize, 86usize); +payload_add!(17usize, 70usize, 87usize); +payload_add!(17usize, 71usize, 88usize); +payload_add!(17usize, 72usize, 89usize); +payload_add!(17usize, 73usize, 90usize); +payload_add!(17usize, 74usize, 91usize); +payload_add!(17usize, 75usize, 92usize); +payload_add!(17usize, 76usize, 93usize); +payload_add!(17usize, 77usize, 94usize); +payload_add!(17usize, 78usize, 95usize); +payload_add!(17usize, 79usize, 96usize); +payload_add!(17usize, 80usize, 97usize); +payload_add!(17usize, 81usize, 98usize); +payload_add!(17usize, 82usize, 99usize); +payload_add!(17usize, 83usize, 100usize); +payload_add!(17usize, 84usize, 101usize); +payload_add!(17usize, 85usize, 102usize); +payload_add!(17usize, 86usize, 103usize); +payload_add!(17usize, 87usize, 104usize); +payload_add!(17usize, 88usize, 105usize); +payload_add!(17usize, 89usize, 106usize); +payload_add!(17usize, 90usize, 107usize); +payload_add!(17usize, 91usize, 108usize); +payload_add!(17usize, 92usize, 109usize); +payload_add!(17usize, 93usize, 110usize); +payload_add!(17usize, 94usize, 111usize); +payload_add!(17usize, 95usize, 112usize); +payload_add!(17usize, 96usize, 113usize); +payload_add!(17usize, 97usize, 114usize); +payload_add!(17usize, 98usize, 115usize); +payload_add!(17usize, 99usize, 116usize); +payload_add!(17usize, 100usize, 117usize); +payload_add!(17usize, 101usize, 118usize); +payload_add!(17usize, 102usize, 119usize); +payload_add!(17usize, 103usize, 120usize); +payload_add!(17usize, 104usize, 121usize); +payload_add!(17usize, 105usize, 122usize); +payload_add!(17usize, 106usize, 123usize); +payload_add!(17usize, 107usize, 124usize); +payload_add!(17usize, 108usize, 125usize); +payload_add!(17usize, 109usize, 126usize); +payload_add!(17usize, 110usize, 127usize); +payload_add!(17usize, 111usize, 128usize); +payload_add!(17usize, 112usize, 129usize); +payload_add!(17usize, 113usize, 130usize); +payload_add!(17usize, 114usize, 131usize); +payload_add!(17usize, 115usize, 132usize); +payload_add!(17usize, 116usize, 133usize); +payload_add!(17usize, 117usize, 134usize); +payload_add!(17usize, 118usize, 135usize); +payload_add!(17usize, 119usize, 136usize); +payload_add!(17usize, 120usize, 137usize); +payload_add!(17usize, 121usize, 138usize); +payload_add!(17usize, 122usize, 139usize); +payload_add!(17usize, 123usize, 140usize); +payload_add!(17usize, 124usize, 141usize); +payload_add!(17usize, 125usize, 142usize); +payload_add!(17usize, 126usize, 143usize); +payload_add!(17usize, 127usize, 144usize); +payload_add!(17usize, 128usize, 145usize); +payload_add!(18usize, 1usize, 19usize); +payload_add!(18usize, 2usize, 20usize); +payload_add!(18usize, 3usize, 21usize); +payload_add!(18usize, 4usize, 22usize); +payload_add!(18usize, 5usize, 23usize); +payload_add!(18usize, 6usize, 24usize); +payload_add!(18usize, 7usize, 25usize); +payload_add!(18usize, 8usize, 26usize); +payload_add!(18usize, 9usize, 27usize); +payload_add!(18usize, 10usize, 28usize); +payload_add!(18usize, 11usize, 29usize); +payload_add!(18usize, 12usize, 30usize); +payload_add!(18usize, 13usize, 31usize); +payload_add!(18usize, 14usize, 32usize); +payload_add!(18usize, 15usize, 33usize); +payload_add!(18usize, 16usize, 34usize); +payload_add!(18usize, 17usize, 35usize); +payload_add!(18usize, 18usize, 36usize); +payload_add!(18usize, 19usize, 37usize); +payload_add!(18usize, 20usize, 38usize); +payload_add!(18usize, 21usize, 39usize); +payload_add!(18usize, 22usize, 40usize); +payload_add!(18usize, 23usize, 41usize); +payload_add!(18usize, 24usize, 42usize); +payload_add!(18usize, 25usize, 43usize); +payload_add!(18usize, 26usize, 44usize); +payload_add!(18usize, 27usize, 45usize); +payload_add!(18usize, 28usize, 46usize); +payload_add!(18usize, 29usize, 47usize); +payload_add!(18usize, 30usize, 48usize); +payload_add!(18usize, 31usize, 49usize); +payload_add!(18usize, 32usize, 50usize); +payload_add!(18usize, 33usize, 51usize); +payload_add!(18usize, 34usize, 52usize); +payload_add!(18usize, 35usize, 53usize); +payload_add!(18usize, 36usize, 54usize); +payload_add!(18usize, 37usize, 55usize); +payload_add!(18usize, 38usize, 56usize); +payload_add!(18usize, 39usize, 57usize); +payload_add!(18usize, 40usize, 58usize); +payload_add!(18usize, 41usize, 59usize); +payload_add!(18usize, 42usize, 60usize); +payload_add!(18usize, 43usize, 61usize); +payload_add!(18usize, 44usize, 62usize); +payload_add!(18usize, 45usize, 63usize); +payload_add!(18usize, 46usize, 64usize); +payload_add!(18usize, 47usize, 65usize); +payload_add!(18usize, 48usize, 66usize); +payload_add!(18usize, 49usize, 67usize); +payload_add!(18usize, 50usize, 68usize); +payload_add!(18usize, 51usize, 69usize); +payload_add!(18usize, 52usize, 70usize); +payload_add!(18usize, 53usize, 71usize); +payload_add!(18usize, 54usize, 72usize); +payload_add!(18usize, 55usize, 73usize); +payload_add!(18usize, 56usize, 74usize); +payload_add!(18usize, 57usize, 75usize); +payload_add!(18usize, 58usize, 76usize); +payload_add!(18usize, 59usize, 77usize); +payload_add!(18usize, 60usize, 78usize); +payload_add!(18usize, 61usize, 79usize); +payload_add!(18usize, 62usize, 80usize); +payload_add!(18usize, 63usize, 81usize); +payload_add!(18usize, 64usize, 82usize); +payload_add!(18usize, 65usize, 83usize); +payload_add!(18usize, 66usize, 84usize); +payload_add!(18usize, 67usize, 85usize); +payload_add!(18usize, 68usize, 86usize); +payload_add!(18usize, 69usize, 87usize); +payload_add!(18usize, 70usize, 88usize); +payload_add!(18usize, 71usize, 89usize); +payload_add!(18usize, 72usize, 90usize); +payload_add!(18usize, 73usize, 91usize); +payload_add!(18usize, 74usize, 92usize); +payload_add!(18usize, 75usize, 93usize); +payload_add!(18usize, 76usize, 94usize); +payload_add!(18usize, 77usize, 95usize); +payload_add!(18usize, 78usize, 96usize); +payload_add!(18usize, 79usize, 97usize); +payload_add!(18usize, 80usize, 98usize); +payload_add!(18usize, 81usize, 99usize); +payload_add!(18usize, 82usize, 100usize); +payload_add!(18usize, 83usize, 101usize); +payload_add!(18usize, 84usize, 102usize); +payload_add!(18usize, 85usize, 103usize); +payload_add!(18usize, 86usize, 104usize); +payload_add!(18usize, 87usize, 105usize); +payload_add!(18usize, 88usize, 106usize); +payload_add!(18usize, 89usize, 107usize); +payload_add!(18usize, 90usize, 108usize); +payload_add!(18usize, 91usize, 109usize); +payload_add!(18usize, 92usize, 110usize); +payload_add!(18usize, 93usize, 111usize); +payload_add!(18usize, 94usize, 112usize); +payload_add!(18usize, 95usize, 113usize); +payload_add!(18usize, 96usize, 114usize); +payload_add!(18usize, 97usize, 115usize); +payload_add!(18usize, 98usize, 116usize); +payload_add!(18usize, 99usize, 117usize); +payload_add!(18usize, 100usize, 118usize); +payload_add!(18usize, 101usize, 119usize); +payload_add!(18usize, 102usize, 120usize); +payload_add!(18usize, 103usize, 121usize); +payload_add!(18usize, 104usize, 122usize); +payload_add!(18usize, 105usize, 123usize); +payload_add!(18usize, 106usize, 124usize); +payload_add!(18usize, 107usize, 125usize); +payload_add!(18usize, 108usize, 126usize); +payload_add!(18usize, 109usize, 127usize); +payload_add!(18usize, 110usize, 128usize); +payload_add!(18usize, 111usize, 129usize); +payload_add!(18usize, 112usize, 130usize); +payload_add!(18usize, 113usize, 131usize); +payload_add!(18usize, 114usize, 132usize); +payload_add!(18usize, 115usize, 133usize); +payload_add!(18usize, 116usize, 134usize); +payload_add!(18usize, 117usize, 135usize); +payload_add!(18usize, 118usize, 136usize); +payload_add!(18usize, 119usize, 137usize); +payload_add!(18usize, 120usize, 138usize); +payload_add!(18usize, 121usize, 139usize); +payload_add!(18usize, 122usize, 140usize); +payload_add!(18usize, 123usize, 141usize); +payload_add!(18usize, 124usize, 142usize); +payload_add!(18usize, 125usize, 143usize); +payload_add!(18usize, 126usize, 144usize); +payload_add!(18usize, 127usize, 145usize); +payload_add!(18usize, 128usize, 146usize); +payload_add!(19usize, 1usize, 20usize); +payload_add!(19usize, 2usize, 21usize); +payload_add!(19usize, 3usize, 22usize); +payload_add!(19usize, 4usize, 23usize); +payload_add!(19usize, 5usize, 24usize); +payload_add!(19usize, 6usize, 25usize); +payload_add!(19usize, 7usize, 26usize); +payload_add!(19usize, 8usize, 27usize); +payload_add!(19usize, 9usize, 28usize); +payload_add!(19usize, 10usize, 29usize); +payload_add!(19usize, 11usize, 30usize); +payload_add!(19usize, 12usize, 31usize); +payload_add!(19usize, 13usize, 32usize); +payload_add!(19usize, 14usize, 33usize); +payload_add!(19usize, 15usize, 34usize); +payload_add!(19usize, 16usize, 35usize); +payload_add!(19usize, 17usize, 36usize); +payload_add!(19usize, 18usize, 37usize); +payload_add!(19usize, 19usize, 38usize); +payload_add!(19usize, 20usize, 39usize); +payload_add!(19usize, 21usize, 40usize); +payload_add!(19usize, 22usize, 41usize); +payload_add!(19usize, 23usize, 42usize); +payload_add!(19usize, 24usize, 43usize); +payload_add!(19usize, 25usize, 44usize); +payload_add!(19usize, 26usize, 45usize); +payload_add!(19usize, 27usize, 46usize); +payload_add!(19usize, 28usize, 47usize); +payload_add!(19usize, 29usize, 48usize); +payload_add!(19usize, 30usize, 49usize); +payload_add!(19usize, 31usize, 50usize); +payload_add!(19usize, 32usize, 51usize); +payload_add!(19usize, 33usize, 52usize); +payload_add!(19usize, 34usize, 53usize); +payload_add!(19usize, 35usize, 54usize); +payload_add!(19usize, 36usize, 55usize); +payload_add!(19usize, 37usize, 56usize); +payload_add!(19usize, 38usize, 57usize); +payload_add!(19usize, 39usize, 58usize); +payload_add!(19usize, 40usize, 59usize); +payload_add!(19usize, 41usize, 60usize); +payload_add!(19usize, 42usize, 61usize); +payload_add!(19usize, 43usize, 62usize); +payload_add!(19usize, 44usize, 63usize); +payload_add!(19usize, 45usize, 64usize); +payload_add!(19usize, 46usize, 65usize); +payload_add!(19usize, 47usize, 66usize); +payload_add!(19usize, 48usize, 67usize); +payload_add!(19usize, 49usize, 68usize); +payload_add!(19usize, 50usize, 69usize); +payload_add!(19usize, 51usize, 70usize); +payload_add!(19usize, 52usize, 71usize); +payload_add!(19usize, 53usize, 72usize); +payload_add!(19usize, 54usize, 73usize); +payload_add!(19usize, 55usize, 74usize); +payload_add!(19usize, 56usize, 75usize); +payload_add!(19usize, 57usize, 76usize); +payload_add!(19usize, 58usize, 77usize); +payload_add!(19usize, 59usize, 78usize); +payload_add!(19usize, 60usize, 79usize); +payload_add!(19usize, 61usize, 80usize); +payload_add!(19usize, 62usize, 81usize); +payload_add!(19usize, 63usize, 82usize); +payload_add!(19usize, 64usize, 83usize); +payload_add!(19usize, 65usize, 84usize); +payload_add!(19usize, 66usize, 85usize); +payload_add!(19usize, 67usize, 86usize); +payload_add!(19usize, 68usize, 87usize); +payload_add!(19usize, 69usize, 88usize); +payload_add!(19usize, 70usize, 89usize); +payload_add!(19usize, 71usize, 90usize); +payload_add!(19usize, 72usize, 91usize); +payload_add!(19usize, 73usize, 92usize); +payload_add!(19usize, 74usize, 93usize); +payload_add!(19usize, 75usize, 94usize); +payload_add!(19usize, 76usize, 95usize); +payload_add!(19usize, 77usize, 96usize); +payload_add!(19usize, 78usize, 97usize); +payload_add!(19usize, 79usize, 98usize); +payload_add!(19usize, 80usize, 99usize); +payload_add!(19usize, 81usize, 100usize); +payload_add!(19usize, 82usize, 101usize); +payload_add!(19usize, 83usize, 102usize); +payload_add!(19usize, 84usize, 103usize); +payload_add!(19usize, 85usize, 104usize); +payload_add!(19usize, 86usize, 105usize); +payload_add!(19usize, 87usize, 106usize); +payload_add!(19usize, 88usize, 107usize); +payload_add!(19usize, 89usize, 108usize); +payload_add!(19usize, 90usize, 109usize); +payload_add!(19usize, 91usize, 110usize); +payload_add!(19usize, 92usize, 111usize); +payload_add!(19usize, 93usize, 112usize); +payload_add!(19usize, 94usize, 113usize); +payload_add!(19usize, 95usize, 114usize); +payload_add!(19usize, 96usize, 115usize); +payload_add!(19usize, 97usize, 116usize); +payload_add!(19usize, 98usize, 117usize); +payload_add!(19usize, 99usize, 118usize); +payload_add!(19usize, 100usize, 119usize); +payload_add!(19usize, 101usize, 120usize); +payload_add!(19usize, 102usize, 121usize); +payload_add!(19usize, 103usize, 122usize); +payload_add!(19usize, 104usize, 123usize); +payload_add!(19usize, 105usize, 124usize); +payload_add!(19usize, 106usize, 125usize); +payload_add!(19usize, 107usize, 126usize); +payload_add!(19usize, 108usize, 127usize); +payload_add!(19usize, 109usize, 128usize); +payload_add!(19usize, 110usize, 129usize); +payload_add!(19usize, 111usize, 130usize); +payload_add!(19usize, 112usize, 131usize); +payload_add!(19usize, 113usize, 132usize); +payload_add!(19usize, 114usize, 133usize); +payload_add!(19usize, 115usize, 134usize); +payload_add!(19usize, 116usize, 135usize); +payload_add!(19usize, 117usize, 136usize); +payload_add!(19usize, 118usize, 137usize); +payload_add!(19usize, 119usize, 138usize); +payload_add!(19usize, 120usize, 139usize); +payload_add!(19usize, 121usize, 140usize); +payload_add!(19usize, 122usize, 141usize); +payload_add!(19usize, 123usize, 142usize); +payload_add!(19usize, 124usize, 143usize); +payload_add!(19usize, 125usize, 144usize); +payload_add!(19usize, 126usize, 145usize); +payload_add!(19usize, 127usize, 146usize); +payload_add!(19usize, 128usize, 147usize); +payload_add!(20usize, 1usize, 21usize); +payload_add!(20usize, 2usize, 22usize); +payload_add!(20usize, 3usize, 23usize); +payload_add!(20usize, 4usize, 24usize); +payload_add!(20usize, 5usize, 25usize); +payload_add!(20usize, 6usize, 26usize); +payload_add!(20usize, 7usize, 27usize); +payload_add!(20usize, 8usize, 28usize); +payload_add!(20usize, 9usize, 29usize); +payload_add!(20usize, 10usize, 30usize); +payload_add!(20usize, 11usize, 31usize); +payload_add!(20usize, 12usize, 32usize); +payload_add!(20usize, 13usize, 33usize); +payload_add!(20usize, 14usize, 34usize); +payload_add!(20usize, 15usize, 35usize); +payload_add!(20usize, 16usize, 36usize); +payload_add!(20usize, 17usize, 37usize); +payload_add!(20usize, 18usize, 38usize); +payload_add!(20usize, 19usize, 39usize); +payload_add!(20usize, 20usize, 40usize); +payload_add!(20usize, 21usize, 41usize); +payload_add!(20usize, 22usize, 42usize); +payload_add!(20usize, 23usize, 43usize); +payload_add!(20usize, 24usize, 44usize); +payload_add!(20usize, 25usize, 45usize); +payload_add!(20usize, 26usize, 46usize); +payload_add!(20usize, 27usize, 47usize); +payload_add!(20usize, 28usize, 48usize); +payload_add!(20usize, 29usize, 49usize); +payload_add!(20usize, 30usize, 50usize); +payload_add!(20usize, 31usize, 51usize); +payload_add!(20usize, 32usize, 52usize); +payload_add!(20usize, 33usize, 53usize); +payload_add!(20usize, 34usize, 54usize); +payload_add!(20usize, 35usize, 55usize); +payload_add!(20usize, 36usize, 56usize); +payload_add!(20usize, 37usize, 57usize); +payload_add!(20usize, 38usize, 58usize); +payload_add!(20usize, 39usize, 59usize); +payload_add!(20usize, 40usize, 60usize); +payload_add!(20usize, 41usize, 61usize); +payload_add!(20usize, 42usize, 62usize); +payload_add!(20usize, 43usize, 63usize); +payload_add!(20usize, 44usize, 64usize); +payload_add!(20usize, 45usize, 65usize); +payload_add!(20usize, 46usize, 66usize); +payload_add!(20usize, 47usize, 67usize); +payload_add!(20usize, 48usize, 68usize); +payload_add!(20usize, 49usize, 69usize); +payload_add!(20usize, 50usize, 70usize); +payload_add!(20usize, 51usize, 71usize); +payload_add!(20usize, 52usize, 72usize); +payload_add!(20usize, 53usize, 73usize); +payload_add!(20usize, 54usize, 74usize); +payload_add!(20usize, 55usize, 75usize); +payload_add!(20usize, 56usize, 76usize); +payload_add!(20usize, 57usize, 77usize); +payload_add!(20usize, 58usize, 78usize); +payload_add!(20usize, 59usize, 79usize); +payload_add!(20usize, 60usize, 80usize); +payload_add!(20usize, 61usize, 81usize); +payload_add!(20usize, 62usize, 82usize); +payload_add!(20usize, 63usize, 83usize); +payload_add!(20usize, 64usize, 84usize); +payload_add!(20usize, 65usize, 85usize); +payload_add!(20usize, 66usize, 86usize); +payload_add!(20usize, 67usize, 87usize); +payload_add!(20usize, 68usize, 88usize); +payload_add!(20usize, 69usize, 89usize); +payload_add!(20usize, 70usize, 90usize); +payload_add!(20usize, 71usize, 91usize); +payload_add!(20usize, 72usize, 92usize); +payload_add!(20usize, 73usize, 93usize); +payload_add!(20usize, 74usize, 94usize); +payload_add!(20usize, 75usize, 95usize); +payload_add!(20usize, 76usize, 96usize); +payload_add!(20usize, 77usize, 97usize); +payload_add!(20usize, 78usize, 98usize); +payload_add!(20usize, 79usize, 99usize); +payload_add!(20usize, 80usize, 100usize); +payload_add!(20usize, 81usize, 101usize); +payload_add!(20usize, 82usize, 102usize); +payload_add!(20usize, 83usize, 103usize); +payload_add!(20usize, 84usize, 104usize); +payload_add!(20usize, 85usize, 105usize); +payload_add!(20usize, 86usize, 106usize); +payload_add!(20usize, 87usize, 107usize); +payload_add!(20usize, 88usize, 108usize); +payload_add!(20usize, 89usize, 109usize); +payload_add!(20usize, 90usize, 110usize); +payload_add!(20usize, 91usize, 111usize); +payload_add!(20usize, 92usize, 112usize); +payload_add!(20usize, 93usize, 113usize); +payload_add!(20usize, 94usize, 114usize); +payload_add!(20usize, 95usize, 115usize); +payload_add!(20usize, 96usize, 116usize); +payload_add!(20usize, 97usize, 117usize); +payload_add!(20usize, 98usize, 118usize); +payload_add!(20usize, 99usize, 119usize); +payload_add!(20usize, 100usize, 120usize); +payload_add!(20usize, 101usize, 121usize); +payload_add!(20usize, 102usize, 122usize); +payload_add!(20usize, 103usize, 123usize); +payload_add!(20usize, 104usize, 124usize); +payload_add!(20usize, 105usize, 125usize); +payload_add!(20usize, 106usize, 126usize); +payload_add!(20usize, 107usize, 127usize); +payload_add!(20usize, 108usize, 128usize); +payload_add!(20usize, 109usize, 129usize); +payload_add!(20usize, 110usize, 130usize); +payload_add!(20usize, 111usize, 131usize); +payload_add!(20usize, 112usize, 132usize); +payload_add!(20usize, 113usize, 133usize); +payload_add!(20usize, 114usize, 134usize); +payload_add!(20usize, 115usize, 135usize); +payload_add!(20usize, 116usize, 136usize); +payload_add!(20usize, 117usize, 137usize); +payload_add!(20usize, 118usize, 138usize); +payload_add!(20usize, 119usize, 139usize); +payload_add!(20usize, 120usize, 140usize); +payload_add!(20usize, 121usize, 141usize); +payload_add!(20usize, 122usize, 142usize); +payload_add!(20usize, 123usize, 143usize); +payload_add!(20usize, 124usize, 144usize); +payload_add!(20usize, 125usize, 145usize); +payload_add!(20usize, 126usize, 146usize); +payload_add!(20usize, 127usize, 147usize); +payload_add!(20usize, 128usize, 148usize); +payload_add!(21usize, 1usize, 22usize); +payload_add!(21usize, 2usize, 23usize); +payload_add!(21usize, 3usize, 24usize); +payload_add!(21usize, 4usize, 25usize); +payload_add!(21usize, 5usize, 26usize); +payload_add!(21usize, 6usize, 27usize); +payload_add!(21usize, 7usize, 28usize); +payload_add!(21usize, 8usize, 29usize); +payload_add!(21usize, 9usize, 30usize); +payload_add!(21usize, 10usize, 31usize); +payload_add!(21usize, 11usize, 32usize); +payload_add!(21usize, 12usize, 33usize); +payload_add!(21usize, 13usize, 34usize); +payload_add!(21usize, 14usize, 35usize); +payload_add!(21usize, 15usize, 36usize); +payload_add!(21usize, 16usize, 37usize); +payload_add!(21usize, 17usize, 38usize); +payload_add!(21usize, 18usize, 39usize); +payload_add!(21usize, 19usize, 40usize); +payload_add!(21usize, 20usize, 41usize); +payload_add!(21usize, 21usize, 42usize); +payload_add!(21usize, 22usize, 43usize); +payload_add!(21usize, 23usize, 44usize); +payload_add!(21usize, 24usize, 45usize); +payload_add!(21usize, 25usize, 46usize); +payload_add!(21usize, 26usize, 47usize); +payload_add!(21usize, 27usize, 48usize); +payload_add!(21usize, 28usize, 49usize); +payload_add!(21usize, 29usize, 50usize); +payload_add!(21usize, 30usize, 51usize); +payload_add!(21usize, 31usize, 52usize); +payload_add!(21usize, 32usize, 53usize); +payload_add!(21usize, 33usize, 54usize); +payload_add!(21usize, 34usize, 55usize); +payload_add!(21usize, 35usize, 56usize); +payload_add!(21usize, 36usize, 57usize); +payload_add!(21usize, 37usize, 58usize); +payload_add!(21usize, 38usize, 59usize); +payload_add!(21usize, 39usize, 60usize); +payload_add!(21usize, 40usize, 61usize); +payload_add!(21usize, 41usize, 62usize); +payload_add!(21usize, 42usize, 63usize); +payload_add!(21usize, 43usize, 64usize); +payload_add!(21usize, 44usize, 65usize); +payload_add!(21usize, 45usize, 66usize); +payload_add!(21usize, 46usize, 67usize); +payload_add!(21usize, 47usize, 68usize); +payload_add!(21usize, 48usize, 69usize); +payload_add!(21usize, 49usize, 70usize); +payload_add!(21usize, 50usize, 71usize); +payload_add!(21usize, 51usize, 72usize); +payload_add!(21usize, 52usize, 73usize); +payload_add!(21usize, 53usize, 74usize); +payload_add!(21usize, 54usize, 75usize); +payload_add!(21usize, 55usize, 76usize); +payload_add!(21usize, 56usize, 77usize); +payload_add!(21usize, 57usize, 78usize); +payload_add!(21usize, 58usize, 79usize); +payload_add!(21usize, 59usize, 80usize); +payload_add!(21usize, 60usize, 81usize); +payload_add!(21usize, 61usize, 82usize); +payload_add!(21usize, 62usize, 83usize); +payload_add!(21usize, 63usize, 84usize); +payload_add!(21usize, 64usize, 85usize); +payload_add!(21usize, 65usize, 86usize); +payload_add!(21usize, 66usize, 87usize); +payload_add!(21usize, 67usize, 88usize); +payload_add!(21usize, 68usize, 89usize); +payload_add!(21usize, 69usize, 90usize); +payload_add!(21usize, 70usize, 91usize); +payload_add!(21usize, 71usize, 92usize); +payload_add!(21usize, 72usize, 93usize); +payload_add!(21usize, 73usize, 94usize); +payload_add!(21usize, 74usize, 95usize); +payload_add!(21usize, 75usize, 96usize); +payload_add!(21usize, 76usize, 97usize); +payload_add!(21usize, 77usize, 98usize); +payload_add!(21usize, 78usize, 99usize); +payload_add!(21usize, 79usize, 100usize); +payload_add!(21usize, 80usize, 101usize); +payload_add!(21usize, 81usize, 102usize); +payload_add!(21usize, 82usize, 103usize); +payload_add!(21usize, 83usize, 104usize); +payload_add!(21usize, 84usize, 105usize); +payload_add!(21usize, 85usize, 106usize); +payload_add!(21usize, 86usize, 107usize); +payload_add!(21usize, 87usize, 108usize); +payload_add!(21usize, 88usize, 109usize); +payload_add!(21usize, 89usize, 110usize); +payload_add!(21usize, 90usize, 111usize); +payload_add!(21usize, 91usize, 112usize); +payload_add!(21usize, 92usize, 113usize); +payload_add!(21usize, 93usize, 114usize); +payload_add!(21usize, 94usize, 115usize); +payload_add!(21usize, 95usize, 116usize); +payload_add!(21usize, 96usize, 117usize); +payload_add!(21usize, 97usize, 118usize); +payload_add!(21usize, 98usize, 119usize); +payload_add!(21usize, 99usize, 120usize); +payload_add!(21usize, 100usize, 121usize); +payload_add!(21usize, 101usize, 122usize); +payload_add!(21usize, 102usize, 123usize); +payload_add!(21usize, 103usize, 124usize); +payload_add!(21usize, 104usize, 125usize); +payload_add!(21usize, 105usize, 126usize); +payload_add!(21usize, 106usize, 127usize); +payload_add!(21usize, 107usize, 128usize); +payload_add!(21usize, 108usize, 129usize); +payload_add!(21usize, 109usize, 130usize); +payload_add!(21usize, 110usize, 131usize); +payload_add!(21usize, 111usize, 132usize); +payload_add!(21usize, 112usize, 133usize); +payload_add!(21usize, 113usize, 134usize); +payload_add!(21usize, 114usize, 135usize); +payload_add!(21usize, 115usize, 136usize); +payload_add!(21usize, 116usize, 137usize); +payload_add!(21usize, 117usize, 138usize); +payload_add!(21usize, 118usize, 139usize); +payload_add!(21usize, 119usize, 140usize); +payload_add!(21usize, 120usize, 141usize); +payload_add!(21usize, 121usize, 142usize); +payload_add!(21usize, 122usize, 143usize); +payload_add!(21usize, 123usize, 144usize); +payload_add!(21usize, 124usize, 145usize); +payload_add!(21usize, 125usize, 146usize); +payload_add!(21usize, 126usize, 147usize); +payload_add!(21usize, 127usize, 148usize); +payload_add!(21usize, 128usize, 149usize); +payload_add!(22usize, 1usize, 23usize); +payload_add!(22usize, 2usize, 24usize); +payload_add!(22usize, 3usize, 25usize); +payload_add!(22usize, 4usize, 26usize); +payload_add!(22usize, 5usize, 27usize); +payload_add!(22usize, 6usize, 28usize); +payload_add!(22usize, 7usize, 29usize); +payload_add!(22usize, 8usize, 30usize); +payload_add!(22usize, 9usize, 31usize); +payload_add!(22usize, 10usize, 32usize); +payload_add!(22usize, 11usize, 33usize); +payload_add!(22usize, 12usize, 34usize); +payload_add!(22usize, 13usize, 35usize); +payload_add!(22usize, 14usize, 36usize); +payload_add!(22usize, 15usize, 37usize); +payload_add!(22usize, 16usize, 38usize); +payload_add!(22usize, 17usize, 39usize); +payload_add!(22usize, 18usize, 40usize); +payload_add!(22usize, 19usize, 41usize); +payload_add!(22usize, 20usize, 42usize); +payload_add!(22usize, 21usize, 43usize); +payload_add!(22usize, 22usize, 44usize); +payload_add!(22usize, 23usize, 45usize); +payload_add!(22usize, 24usize, 46usize); +payload_add!(22usize, 25usize, 47usize); +payload_add!(22usize, 26usize, 48usize); +payload_add!(22usize, 27usize, 49usize); +payload_add!(22usize, 28usize, 50usize); +payload_add!(22usize, 29usize, 51usize); +payload_add!(22usize, 30usize, 52usize); +payload_add!(22usize, 31usize, 53usize); +payload_add!(22usize, 32usize, 54usize); +payload_add!(22usize, 33usize, 55usize); +payload_add!(22usize, 34usize, 56usize); +payload_add!(22usize, 35usize, 57usize); +payload_add!(22usize, 36usize, 58usize); +payload_add!(22usize, 37usize, 59usize); +payload_add!(22usize, 38usize, 60usize); +payload_add!(22usize, 39usize, 61usize); +payload_add!(22usize, 40usize, 62usize); +payload_add!(22usize, 41usize, 63usize); +payload_add!(22usize, 42usize, 64usize); +payload_add!(22usize, 43usize, 65usize); +payload_add!(22usize, 44usize, 66usize); +payload_add!(22usize, 45usize, 67usize); +payload_add!(22usize, 46usize, 68usize); +payload_add!(22usize, 47usize, 69usize); +payload_add!(22usize, 48usize, 70usize); +payload_add!(22usize, 49usize, 71usize); +payload_add!(22usize, 50usize, 72usize); +payload_add!(22usize, 51usize, 73usize); +payload_add!(22usize, 52usize, 74usize); +payload_add!(22usize, 53usize, 75usize); +payload_add!(22usize, 54usize, 76usize); +payload_add!(22usize, 55usize, 77usize); +payload_add!(22usize, 56usize, 78usize); +payload_add!(22usize, 57usize, 79usize); +payload_add!(22usize, 58usize, 80usize); +payload_add!(22usize, 59usize, 81usize); +payload_add!(22usize, 60usize, 82usize); +payload_add!(22usize, 61usize, 83usize); +payload_add!(22usize, 62usize, 84usize); +payload_add!(22usize, 63usize, 85usize); +payload_add!(22usize, 64usize, 86usize); +payload_add!(22usize, 65usize, 87usize); +payload_add!(22usize, 66usize, 88usize); +payload_add!(22usize, 67usize, 89usize); +payload_add!(22usize, 68usize, 90usize); +payload_add!(22usize, 69usize, 91usize); +payload_add!(22usize, 70usize, 92usize); +payload_add!(22usize, 71usize, 93usize); +payload_add!(22usize, 72usize, 94usize); +payload_add!(22usize, 73usize, 95usize); +payload_add!(22usize, 74usize, 96usize); +payload_add!(22usize, 75usize, 97usize); +payload_add!(22usize, 76usize, 98usize); +payload_add!(22usize, 77usize, 99usize); +payload_add!(22usize, 78usize, 100usize); +payload_add!(22usize, 79usize, 101usize); +payload_add!(22usize, 80usize, 102usize); +payload_add!(22usize, 81usize, 103usize); +payload_add!(22usize, 82usize, 104usize); +payload_add!(22usize, 83usize, 105usize); +payload_add!(22usize, 84usize, 106usize); +payload_add!(22usize, 85usize, 107usize); +payload_add!(22usize, 86usize, 108usize); +payload_add!(22usize, 87usize, 109usize); +payload_add!(22usize, 88usize, 110usize); +payload_add!(22usize, 89usize, 111usize); +payload_add!(22usize, 90usize, 112usize); +payload_add!(22usize, 91usize, 113usize); +payload_add!(22usize, 92usize, 114usize); +payload_add!(22usize, 93usize, 115usize); +payload_add!(22usize, 94usize, 116usize); +payload_add!(22usize, 95usize, 117usize); +payload_add!(22usize, 96usize, 118usize); +payload_add!(22usize, 97usize, 119usize); +payload_add!(22usize, 98usize, 120usize); +payload_add!(22usize, 99usize, 121usize); +payload_add!(22usize, 100usize, 122usize); +payload_add!(22usize, 101usize, 123usize); +payload_add!(22usize, 102usize, 124usize); +payload_add!(22usize, 103usize, 125usize); +payload_add!(22usize, 104usize, 126usize); +payload_add!(22usize, 105usize, 127usize); +payload_add!(22usize, 106usize, 128usize); +payload_add!(22usize, 107usize, 129usize); +payload_add!(22usize, 108usize, 130usize); +payload_add!(22usize, 109usize, 131usize); +payload_add!(22usize, 110usize, 132usize); +payload_add!(22usize, 111usize, 133usize); +payload_add!(22usize, 112usize, 134usize); +payload_add!(22usize, 113usize, 135usize); +payload_add!(22usize, 114usize, 136usize); +payload_add!(22usize, 115usize, 137usize); +payload_add!(22usize, 116usize, 138usize); +payload_add!(22usize, 117usize, 139usize); +payload_add!(22usize, 118usize, 140usize); +payload_add!(22usize, 119usize, 141usize); +payload_add!(22usize, 120usize, 142usize); +payload_add!(22usize, 121usize, 143usize); +payload_add!(22usize, 122usize, 144usize); +payload_add!(22usize, 123usize, 145usize); +payload_add!(22usize, 124usize, 146usize); +payload_add!(22usize, 125usize, 147usize); +payload_add!(22usize, 126usize, 148usize); +payload_add!(22usize, 127usize, 149usize); +payload_add!(22usize, 128usize, 150usize); +payload_add!(23usize, 1usize, 24usize); +payload_add!(23usize, 2usize, 25usize); +payload_add!(23usize, 3usize, 26usize); +payload_add!(23usize, 4usize, 27usize); +payload_add!(23usize, 5usize, 28usize); +payload_add!(23usize, 6usize, 29usize); +payload_add!(23usize, 7usize, 30usize); +payload_add!(23usize, 8usize, 31usize); +payload_add!(23usize, 9usize, 32usize); +payload_add!(23usize, 10usize, 33usize); +payload_add!(23usize, 11usize, 34usize); +payload_add!(23usize, 12usize, 35usize); +payload_add!(23usize, 13usize, 36usize); +payload_add!(23usize, 14usize, 37usize); +payload_add!(23usize, 15usize, 38usize); +payload_add!(23usize, 16usize, 39usize); +payload_add!(23usize, 17usize, 40usize); +payload_add!(23usize, 18usize, 41usize); +payload_add!(23usize, 19usize, 42usize); +payload_add!(23usize, 20usize, 43usize); +payload_add!(23usize, 21usize, 44usize); +payload_add!(23usize, 22usize, 45usize); +payload_add!(23usize, 23usize, 46usize); +payload_add!(23usize, 24usize, 47usize); +payload_add!(23usize, 25usize, 48usize); +payload_add!(23usize, 26usize, 49usize); +payload_add!(23usize, 27usize, 50usize); +payload_add!(23usize, 28usize, 51usize); +payload_add!(23usize, 29usize, 52usize); +payload_add!(23usize, 30usize, 53usize); +payload_add!(23usize, 31usize, 54usize); +payload_add!(23usize, 32usize, 55usize); +payload_add!(23usize, 33usize, 56usize); +payload_add!(23usize, 34usize, 57usize); +payload_add!(23usize, 35usize, 58usize); +payload_add!(23usize, 36usize, 59usize); +payload_add!(23usize, 37usize, 60usize); +payload_add!(23usize, 38usize, 61usize); +payload_add!(23usize, 39usize, 62usize); +payload_add!(23usize, 40usize, 63usize); +payload_add!(23usize, 41usize, 64usize); +payload_add!(23usize, 42usize, 65usize); +payload_add!(23usize, 43usize, 66usize); +payload_add!(23usize, 44usize, 67usize); +payload_add!(23usize, 45usize, 68usize); +payload_add!(23usize, 46usize, 69usize); +payload_add!(23usize, 47usize, 70usize); +payload_add!(23usize, 48usize, 71usize); +payload_add!(23usize, 49usize, 72usize); +payload_add!(23usize, 50usize, 73usize); +payload_add!(23usize, 51usize, 74usize); +payload_add!(23usize, 52usize, 75usize); +payload_add!(23usize, 53usize, 76usize); +payload_add!(23usize, 54usize, 77usize); +payload_add!(23usize, 55usize, 78usize); +payload_add!(23usize, 56usize, 79usize); +payload_add!(23usize, 57usize, 80usize); +payload_add!(23usize, 58usize, 81usize); +payload_add!(23usize, 59usize, 82usize); +payload_add!(23usize, 60usize, 83usize); +payload_add!(23usize, 61usize, 84usize); +payload_add!(23usize, 62usize, 85usize); +payload_add!(23usize, 63usize, 86usize); +payload_add!(23usize, 64usize, 87usize); +payload_add!(23usize, 65usize, 88usize); +payload_add!(23usize, 66usize, 89usize); +payload_add!(23usize, 67usize, 90usize); +payload_add!(23usize, 68usize, 91usize); +payload_add!(23usize, 69usize, 92usize); +payload_add!(23usize, 70usize, 93usize); +payload_add!(23usize, 71usize, 94usize); +payload_add!(23usize, 72usize, 95usize); +payload_add!(23usize, 73usize, 96usize); +payload_add!(23usize, 74usize, 97usize); +payload_add!(23usize, 75usize, 98usize); +payload_add!(23usize, 76usize, 99usize); +payload_add!(23usize, 77usize, 100usize); +payload_add!(23usize, 78usize, 101usize); +payload_add!(23usize, 79usize, 102usize); +payload_add!(23usize, 80usize, 103usize); +payload_add!(23usize, 81usize, 104usize); +payload_add!(23usize, 82usize, 105usize); +payload_add!(23usize, 83usize, 106usize); +payload_add!(23usize, 84usize, 107usize); +payload_add!(23usize, 85usize, 108usize); +payload_add!(23usize, 86usize, 109usize); +payload_add!(23usize, 87usize, 110usize); +payload_add!(23usize, 88usize, 111usize); +payload_add!(23usize, 89usize, 112usize); +payload_add!(23usize, 90usize, 113usize); +payload_add!(23usize, 91usize, 114usize); +payload_add!(23usize, 92usize, 115usize); +payload_add!(23usize, 93usize, 116usize); +payload_add!(23usize, 94usize, 117usize); +payload_add!(23usize, 95usize, 118usize); +payload_add!(23usize, 96usize, 119usize); +payload_add!(23usize, 97usize, 120usize); +payload_add!(23usize, 98usize, 121usize); +payload_add!(23usize, 99usize, 122usize); +payload_add!(23usize, 100usize, 123usize); +payload_add!(23usize, 101usize, 124usize); +payload_add!(23usize, 102usize, 125usize); +payload_add!(23usize, 103usize, 126usize); +payload_add!(23usize, 104usize, 127usize); +payload_add!(23usize, 105usize, 128usize); +payload_add!(23usize, 106usize, 129usize); +payload_add!(23usize, 107usize, 130usize); +payload_add!(23usize, 108usize, 131usize); +payload_add!(23usize, 109usize, 132usize); +payload_add!(23usize, 110usize, 133usize); +payload_add!(23usize, 111usize, 134usize); +payload_add!(23usize, 112usize, 135usize); +payload_add!(23usize, 113usize, 136usize); +payload_add!(23usize, 114usize, 137usize); +payload_add!(23usize, 115usize, 138usize); +payload_add!(23usize, 116usize, 139usize); +payload_add!(23usize, 117usize, 140usize); +payload_add!(23usize, 118usize, 141usize); +payload_add!(23usize, 119usize, 142usize); +payload_add!(23usize, 120usize, 143usize); +payload_add!(23usize, 121usize, 144usize); +payload_add!(23usize, 122usize, 145usize); +payload_add!(23usize, 123usize, 146usize); +payload_add!(23usize, 124usize, 147usize); +payload_add!(23usize, 125usize, 148usize); +payload_add!(23usize, 126usize, 149usize); +payload_add!(23usize, 127usize, 150usize); +payload_add!(23usize, 128usize, 151usize); +payload_add!(24usize, 1usize, 25usize); +payload_add!(24usize, 2usize, 26usize); +payload_add!(24usize, 3usize, 27usize); +payload_add!(24usize, 4usize, 28usize); +payload_add!(24usize, 5usize, 29usize); +payload_add!(24usize, 6usize, 30usize); +payload_add!(24usize, 7usize, 31usize); +payload_add!(24usize, 8usize, 32usize); +payload_add!(24usize, 9usize, 33usize); +payload_add!(24usize, 10usize, 34usize); +payload_add!(24usize, 11usize, 35usize); +payload_add!(24usize, 12usize, 36usize); +payload_add!(24usize, 13usize, 37usize); +payload_add!(24usize, 14usize, 38usize); +payload_add!(24usize, 15usize, 39usize); +payload_add!(24usize, 16usize, 40usize); +payload_add!(24usize, 17usize, 41usize); +payload_add!(24usize, 18usize, 42usize); +payload_add!(24usize, 19usize, 43usize); +payload_add!(24usize, 20usize, 44usize); +payload_add!(24usize, 21usize, 45usize); +payload_add!(24usize, 22usize, 46usize); +payload_add!(24usize, 23usize, 47usize); +payload_add!(24usize, 24usize, 48usize); +payload_add!(24usize, 25usize, 49usize); +payload_add!(24usize, 26usize, 50usize); +payload_add!(24usize, 27usize, 51usize); +payload_add!(24usize, 28usize, 52usize); +payload_add!(24usize, 29usize, 53usize); +payload_add!(24usize, 30usize, 54usize); +payload_add!(24usize, 31usize, 55usize); +payload_add!(24usize, 32usize, 56usize); +payload_add!(24usize, 33usize, 57usize); +payload_add!(24usize, 34usize, 58usize); +payload_add!(24usize, 35usize, 59usize); +payload_add!(24usize, 36usize, 60usize); +payload_add!(24usize, 37usize, 61usize); +payload_add!(24usize, 38usize, 62usize); +payload_add!(24usize, 39usize, 63usize); +payload_add!(24usize, 40usize, 64usize); +payload_add!(24usize, 41usize, 65usize); +payload_add!(24usize, 42usize, 66usize); +payload_add!(24usize, 43usize, 67usize); +payload_add!(24usize, 44usize, 68usize); +payload_add!(24usize, 45usize, 69usize); +payload_add!(24usize, 46usize, 70usize); +payload_add!(24usize, 47usize, 71usize); +payload_add!(24usize, 48usize, 72usize); +payload_add!(24usize, 49usize, 73usize); +payload_add!(24usize, 50usize, 74usize); +payload_add!(24usize, 51usize, 75usize); +payload_add!(24usize, 52usize, 76usize); +payload_add!(24usize, 53usize, 77usize); +payload_add!(24usize, 54usize, 78usize); +payload_add!(24usize, 55usize, 79usize); +payload_add!(24usize, 56usize, 80usize); +payload_add!(24usize, 57usize, 81usize); +payload_add!(24usize, 58usize, 82usize); +payload_add!(24usize, 59usize, 83usize); +payload_add!(24usize, 60usize, 84usize); +payload_add!(24usize, 61usize, 85usize); +payload_add!(24usize, 62usize, 86usize); +payload_add!(24usize, 63usize, 87usize); +payload_add!(24usize, 64usize, 88usize); +payload_add!(24usize, 65usize, 89usize); +payload_add!(24usize, 66usize, 90usize); +payload_add!(24usize, 67usize, 91usize); +payload_add!(24usize, 68usize, 92usize); +payload_add!(24usize, 69usize, 93usize); +payload_add!(24usize, 70usize, 94usize); +payload_add!(24usize, 71usize, 95usize); +payload_add!(24usize, 72usize, 96usize); +payload_add!(24usize, 73usize, 97usize); +payload_add!(24usize, 74usize, 98usize); +payload_add!(24usize, 75usize, 99usize); +payload_add!(24usize, 76usize, 100usize); +payload_add!(24usize, 77usize, 101usize); +payload_add!(24usize, 78usize, 102usize); +payload_add!(24usize, 79usize, 103usize); +payload_add!(24usize, 80usize, 104usize); +payload_add!(24usize, 81usize, 105usize); +payload_add!(24usize, 82usize, 106usize); +payload_add!(24usize, 83usize, 107usize); +payload_add!(24usize, 84usize, 108usize); +payload_add!(24usize, 85usize, 109usize); +payload_add!(24usize, 86usize, 110usize); +payload_add!(24usize, 87usize, 111usize); +payload_add!(24usize, 88usize, 112usize); +payload_add!(24usize, 89usize, 113usize); +payload_add!(24usize, 90usize, 114usize); +payload_add!(24usize, 91usize, 115usize); +payload_add!(24usize, 92usize, 116usize); +payload_add!(24usize, 93usize, 117usize); +payload_add!(24usize, 94usize, 118usize); +payload_add!(24usize, 95usize, 119usize); +payload_add!(24usize, 96usize, 120usize); +payload_add!(24usize, 97usize, 121usize); +payload_add!(24usize, 98usize, 122usize); +payload_add!(24usize, 99usize, 123usize); +payload_add!(24usize, 100usize, 124usize); +payload_add!(24usize, 101usize, 125usize); +payload_add!(24usize, 102usize, 126usize); +payload_add!(24usize, 103usize, 127usize); +payload_add!(24usize, 104usize, 128usize); +payload_add!(24usize, 105usize, 129usize); +payload_add!(24usize, 106usize, 130usize); +payload_add!(24usize, 107usize, 131usize); +payload_add!(24usize, 108usize, 132usize); +payload_add!(24usize, 109usize, 133usize); +payload_add!(24usize, 110usize, 134usize); +payload_add!(24usize, 111usize, 135usize); +payload_add!(24usize, 112usize, 136usize); +payload_add!(24usize, 113usize, 137usize); +payload_add!(24usize, 114usize, 138usize); +payload_add!(24usize, 115usize, 139usize); +payload_add!(24usize, 116usize, 140usize); +payload_add!(24usize, 117usize, 141usize); +payload_add!(24usize, 118usize, 142usize); +payload_add!(24usize, 119usize, 143usize); +payload_add!(24usize, 120usize, 144usize); +payload_add!(24usize, 121usize, 145usize); +payload_add!(24usize, 122usize, 146usize); +payload_add!(24usize, 123usize, 147usize); +payload_add!(24usize, 124usize, 148usize); +payload_add!(24usize, 125usize, 149usize); +payload_add!(24usize, 126usize, 150usize); +payload_add!(24usize, 127usize, 151usize); +payload_add!(24usize, 128usize, 152usize); +payload_add!(25usize, 1usize, 26usize); +payload_add!(25usize, 2usize, 27usize); +payload_add!(25usize, 3usize, 28usize); +payload_add!(25usize, 4usize, 29usize); +payload_add!(25usize, 5usize, 30usize); +payload_add!(25usize, 6usize, 31usize); +payload_add!(25usize, 7usize, 32usize); +payload_add!(25usize, 8usize, 33usize); +payload_add!(25usize, 9usize, 34usize); +payload_add!(25usize, 10usize, 35usize); +payload_add!(25usize, 11usize, 36usize); +payload_add!(25usize, 12usize, 37usize); +payload_add!(25usize, 13usize, 38usize); +payload_add!(25usize, 14usize, 39usize); +payload_add!(25usize, 15usize, 40usize); +payload_add!(25usize, 16usize, 41usize); +payload_add!(25usize, 17usize, 42usize); +payload_add!(25usize, 18usize, 43usize); +payload_add!(25usize, 19usize, 44usize); +payload_add!(25usize, 20usize, 45usize); +payload_add!(25usize, 21usize, 46usize); +payload_add!(25usize, 22usize, 47usize); +payload_add!(25usize, 23usize, 48usize); +payload_add!(25usize, 24usize, 49usize); +payload_add!(25usize, 25usize, 50usize); +payload_add!(25usize, 26usize, 51usize); +payload_add!(25usize, 27usize, 52usize); +payload_add!(25usize, 28usize, 53usize); +payload_add!(25usize, 29usize, 54usize); +payload_add!(25usize, 30usize, 55usize); +payload_add!(25usize, 31usize, 56usize); +payload_add!(25usize, 32usize, 57usize); +payload_add!(25usize, 33usize, 58usize); +payload_add!(25usize, 34usize, 59usize); +payload_add!(25usize, 35usize, 60usize); +payload_add!(25usize, 36usize, 61usize); +payload_add!(25usize, 37usize, 62usize); +payload_add!(25usize, 38usize, 63usize); +payload_add!(25usize, 39usize, 64usize); +payload_add!(25usize, 40usize, 65usize); +payload_add!(25usize, 41usize, 66usize); +payload_add!(25usize, 42usize, 67usize); +payload_add!(25usize, 43usize, 68usize); +payload_add!(25usize, 44usize, 69usize); +payload_add!(25usize, 45usize, 70usize); +payload_add!(25usize, 46usize, 71usize); +payload_add!(25usize, 47usize, 72usize); +payload_add!(25usize, 48usize, 73usize); +payload_add!(25usize, 49usize, 74usize); +payload_add!(25usize, 50usize, 75usize); +payload_add!(25usize, 51usize, 76usize); +payload_add!(25usize, 52usize, 77usize); +payload_add!(25usize, 53usize, 78usize); +payload_add!(25usize, 54usize, 79usize); +payload_add!(25usize, 55usize, 80usize); +payload_add!(25usize, 56usize, 81usize); +payload_add!(25usize, 57usize, 82usize); +payload_add!(25usize, 58usize, 83usize); +payload_add!(25usize, 59usize, 84usize); +payload_add!(25usize, 60usize, 85usize); +payload_add!(25usize, 61usize, 86usize); +payload_add!(25usize, 62usize, 87usize); +payload_add!(25usize, 63usize, 88usize); +payload_add!(25usize, 64usize, 89usize); +payload_add!(25usize, 65usize, 90usize); +payload_add!(25usize, 66usize, 91usize); +payload_add!(25usize, 67usize, 92usize); +payload_add!(25usize, 68usize, 93usize); +payload_add!(25usize, 69usize, 94usize); +payload_add!(25usize, 70usize, 95usize); +payload_add!(25usize, 71usize, 96usize); +payload_add!(25usize, 72usize, 97usize); +payload_add!(25usize, 73usize, 98usize); +payload_add!(25usize, 74usize, 99usize); +payload_add!(25usize, 75usize, 100usize); +payload_add!(25usize, 76usize, 101usize); +payload_add!(25usize, 77usize, 102usize); +payload_add!(25usize, 78usize, 103usize); +payload_add!(25usize, 79usize, 104usize); +payload_add!(25usize, 80usize, 105usize); +payload_add!(25usize, 81usize, 106usize); +payload_add!(25usize, 82usize, 107usize); +payload_add!(25usize, 83usize, 108usize); +payload_add!(25usize, 84usize, 109usize); +payload_add!(25usize, 85usize, 110usize); +payload_add!(25usize, 86usize, 111usize); +payload_add!(25usize, 87usize, 112usize); +payload_add!(25usize, 88usize, 113usize); +payload_add!(25usize, 89usize, 114usize); +payload_add!(25usize, 90usize, 115usize); +payload_add!(25usize, 91usize, 116usize); +payload_add!(25usize, 92usize, 117usize); +payload_add!(25usize, 93usize, 118usize); +payload_add!(25usize, 94usize, 119usize); +payload_add!(25usize, 95usize, 120usize); +payload_add!(25usize, 96usize, 121usize); +payload_add!(25usize, 97usize, 122usize); +payload_add!(25usize, 98usize, 123usize); +payload_add!(25usize, 99usize, 124usize); +payload_add!(25usize, 100usize, 125usize); +payload_add!(25usize, 101usize, 126usize); +payload_add!(25usize, 102usize, 127usize); +payload_add!(25usize, 103usize, 128usize); +payload_add!(25usize, 104usize, 129usize); +payload_add!(25usize, 105usize, 130usize); +payload_add!(25usize, 106usize, 131usize); +payload_add!(25usize, 107usize, 132usize); +payload_add!(25usize, 108usize, 133usize); +payload_add!(25usize, 109usize, 134usize); +payload_add!(25usize, 110usize, 135usize); +payload_add!(25usize, 111usize, 136usize); +payload_add!(25usize, 112usize, 137usize); +payload_add!(25usize, 113usize, 138usize); +payload_add!(25usize, 114usize, 139usize); +payload_add!(25usize, 115usize, 140usize); +payload_add!(25usize, 116usize, 141usize); +payload_add!(25usize, 117usize, 142usize); +payload_add!(25usize, 118usize, 143usize); +payload_add!(25usize, 119usize, 144usize); +payload_add!(25usize, 120usize, 145usize); +payload_add!(25usize, 121usize, 146usize); +payload_add!(25usize, 122usize, 147usize); +payload_add!(25usize, 123usize, 148usize); +payload_add!(25usize, 124usize, 149usize); +payload_add!(25usize, 125usize, 150usize); +payload_add!(25usize, 126usize, 151usize); +payload_add!(25usize, 127usize, 152usize); +payload_add!(25usize, 128usize, 153usize); +payload_add!(26usize, 1usize, 27usize); +payload_add!(26usize, 2usize, 28usize); +payload_add!(26usize, 3usize, 29usize); +payload_add!(26usize, 4usize, 30usize); +payload_add!(26usize, 5usize, 31usize); +payload_add!(26usize, 6usize, 32usize); +payload_add!(26usize, 7usize, 33usize); +payload_add!(26usize, 8usize, 34usize); +payload_add!(26usize, 9usize, 35usize); +payload_add!(26usize, 10usize, 36usize); +payload_add!(26usize, 11usize, 37usize); +payload_add!(26usize, 12usize, 38usize); +payload_add!(26usize, 13usize, 39usize); +payload_add!(26usize, 14usize, 40usize); +payload_add!(26usize, 15usize, 41usize); +payload_add!(26usize, 16usize, 42usize); +payload_add!(26usize, 17usize, 43usize); +payload_add!(26usize, 18usize, 44usize); +payload_add!(26usize, 19usize, 45usize); +payload_add!(26usize, 20usize, 46usize); +payload_add!(26usize, 21usize, 47usize); +payload_add!(26usize, 22usize, 48usize); +payload_add!(26usize, 23usize, 49usize); +payload_add!(26usize, 24usize, 50usize); +payload_add!(26usize, 25usize, 51usize); +payload_add!(26usize, 26usize, 52usize); +payload_add!(26usize, 27usize, 53usize); +payload_add!(26usize, 28usize, 54usize); +payload_add!(26usize, 29usize, 55usize); +payload_add!(26usize, 30usize, 56usize); +payload_add!(26usize, 31usize, 57usize); +payload_add!(26usize, 32usize, 58usize); +payload_add!(26usize, 33usize, 59usize); +payload_add!(26usize, 34usize, 60usize); +payload_add!(26usize, 35usize, 61usize); +payload_add!(26usize, 36usize, 62usize); +payload_add!(26usize, 37usize, 63usize); +payload_add!(26usize, 38usize, 64usize); +payload_add!(26usize, 39usize, 65usize); +payload_add!(26usize, 40usize, 66usize); +payload_add!(26usize, 41usize, 67usize); +payload_add!(26usize, 42usize, 68usize); +payload_add!(26usize, 43usize, 69usize); +payload_add!(26usize, 44usize, 70usize); +payload_add!(26usize, 45usize, 71usize); +payload_add!(26usize, 46usize, 72usize); +payload_add!(26usize, 47usize, 73usize); +payload_add!(26usize, 48usize, 74usize); +payload_add!(26usize, 49usize, 75usize); +payload_add!(26usize, 50usize, 76usize); +payload_add!(26usize, 51usize, 77usize); +payload_add!(26usize, 52usize, 78usize); +payload_add!(26usize, 53usize, 79usize); +payload_add!(26usize, 54usize, 80usize); +payload_add!(26usize, 55usize, 81usize); +payload_add!(26usize, 56usize, 82usize); +payload_add!(26usize, 57usize, 83usize); +payload_add!(26usize, 58usize, 84usize); +payload_add!(26usize, 59usize, 85usize); +payload_add!(26usize, 60usize, 86usize); +payload_add!(26usize, 61usize, 87usize); +payload_add!(26usize, 62usize, 88usize); +payload_add!(26usize, 63usize, 89usize); +payload_add!(26usize, 64usize, 90usize); +payload_add!(26usize, 65usize, 91usize); +payload_add!(26usize, 66usize, 92usize); +payload_add!(26usize, 67usize, 93usize); +payload_add!(26usize, 68usize, 94usize); +payload_add!(26usize, 69usize, 95usize); +payload_add!(26usize, 70usize, 96usize); +payload_add!(26usize, 71usize, 97usize); +payload_add!(26usize, 72usize, 98usize); +payload_add!(26usize, 73usize, 99usize); +payload_add!(26usize, 74usize, 100usize); +payload_add!(26usize, 75usize, 101usize); +payload_add!(26usize, 76usize, 102usize); +payload_add!(26usize, 77usize, 103usize); +payload_add!(26usize, 78usize, 104usize); +payload_add!(26usize, 79usize, 105usize); +payload_add!(26usize, 80usize, 106usize); +payload_add!(26usize, 81usize, 107usize); +payload_add!(26usize, 82usize, 108usize); +payload_add!(26usize, 83usize, 109usize); +payload_add!(26usize, 84usize, 110usize); +payload_add!(26usize, 85usize, 111usize); +payload_add!(26usize, 86usize, 112usize); +payload_add!(26usize, 87usize, 113usize); +payload_add!(26usize, 88usize, 114usize); +payload_add!(26usize, 89usize, 115usize); +payload_add!(26usize, 90usize, 116usize); +payload_add!(26usize, 91usize, 117usize); +payload_add!(26usize, 92usize, 118usize); +payload_add!(26usize, 93usize, 119usize); +payload_add!(26usize, 94usize, 120usize); +payload_add!(26usize, 95usize, 121usize); +payload_add!(26usize, 96usize, 122usize); +payload_add!(26usize, 97usize, 123usize); +payload_add!(26usize, 98usize, 124usize); +payload_add!(26usize, 99usize, 125usize); +payload_add!(26usize, 100usize, 126usize); +payload_add!(26usize, 101usize, 127usize); +payload_add!(26usize, 102usize, 128usize); +payload_add!(26usize, 103usize, 129usize); +payload_add!(26usize, 104usize, 130usize); +payload_add!(26usize, 105usize, 131usize); +payload_add!(26usize, 106usize, 132usize); +payload_add!(26usize, 107usize, 133usize); +payload_add!(26usize, 108usize, 134usize); +payload_add!(26usize, 109usize, 135usize); +payload_add!(26usize, 110usize, 136usize); +payload_add!(26usize, 111usize, 137usize); +payload_add!(26usize, 112usize, 138usize); +payload_add!(26usize, 113usize, 139usize); +payload_add!(26usize, 114usize, 140usize); +payload_add!(26usize, 115usize, 141usize); +payload_add!(26usize, 116usize, 142usize); +payload_add!(26usize, 117usize, 143usize); +payload_add!(26usize, 118usize, 144usize); +payload_add!(26usize, 119usize, 145usize); +payload_add!(26usize, 120usize, 146usize); +payload_add!(26usize, 121usize, 147usize); +payload_add!(26usize, 122usize, 148usize); +payload_add!(26usize, 123usize, 149usize); +payload_add!(26usize, 124usize, 150usize); +payload_add!(26usize, 125usize, 151usize); +payload_add!(26usize, 126usize, 152usize); +payload_add!(26usize, 127usize, 153usize); +payload_add!(26usize, 128usize, 154usize); +payload_add!(27usize, 1usize, 28usize); +payload_add!(27usize, 2usize, 29usize); +payload_add!(27usize, 3usize, 30usize); +payload_add!(27usize, 4usize, 31usize); +payload_add!(27usize, 5usize, 32usize); +payload_add!(27usize, 6usize, 33usize); +payload_add!(27usize, 7usize, 34usize); +payload_add!(27usize, 8usize, 35usize); +payload_add!(27usize, 9usize, 36usize); +payload_add!(27usize, 10usize, 37usize); +payload_add!(27usize, 11usize, 38usize); +payload_add!(27usize, 12usize, 39usize); +payload_add!(27usize, 13usize, 40usize); +payload_add!(27usize, 14usize, 41usize); +payload_add!(27usize, 15usize, 42usize); +payload_add!(27usize, 16usize, 43usize); +payload_add!(27usize, 17usize, 44usize); +payload_add!(27usize, 18usize, 45usize); +payload_add!(27usize, 19usize, 46usize); +payload_add!(27usize, 20usize, 47usize); +payload_add!(27usize, 21usize, 48usize); +payload_add!(27usize, 22usize, 49usize); +payload_add!(27usize, 23usize, 50usize); +payload_add!(27usize, 24usize, 51usize); +payload_add!(27usize, 25usize, 52usize); +payload_add!(27usize, 26usize, 53usize); +payload_add!(27usize, 27usize, 54usize); +payload_add!(27usize, 28usize, 55usize); +payload_add!(27usize, 29usize, 56usize); +payload_add!(27usize, 30usize, 57usize); +payload_add!(27usize, 31usize, 58usize); +payload_add!(27usize, 32usize, 59usize); +payload_add!(27usize, 33usize, 60usize); +payload_add!(27usize, 34usize, 61usize); +payload_add!(27usize, 35usize, 62usize); +payload_add!(27usize, 36usize, 63usize); +payload_add!(27usize, 37usize, 64usize); +payload_add!(27usize, 38usize, 65usize); +payload_add!(27usize, 39usize, 66usize); +payload_add!(27usize, 40usize, 67usize); +payload_add!(27usize, 41usize, 68usize); +payload_add!(27usize, 42usize, 69usize); +payload_add!(27usize, 43usize, 70usize); +payload_add!(27usize, 44usize, 71usize); +payload_add!(27usize, 45usize, 72usize); +payload_add!(27usize, 46usize, 73usize); +payload_add!(27usize, 47usize, 74usize); +payload_add!(27usize, 48usize, 75usize); +payload_add!(27usize, 49usize, 76usize); +payload_add!(27usize, 50usize, 77usize); +payload_add!(27usize, 51usize, 78usize); +payload_add!(27usize, 52usize, 79usize); +payload_add!(27usize, 53usize, 80usize); +payload_add!(27usize, 54usize, 81usize); +payload_add!(27usize, 55usize, 82usize); +payload_add!(27usize, 56usize, 83usize); +payload_add!(27usize, 57usize, 84usize); +payload_add!(27usize, 58usize, 85usize); +payload_add!(27usize, 59usize, 86usize); +payload_add!(27usize, 60usize, 87usize); +payload_add!(27usize, 61usize, 88usize); +payload_add!(27usize, 62usize, 89usize); +payload_add!(27usize, 63usize, 90usize); +payload_add!(27usize, 64usize, 91usize); +payload_add!(27usize, 65usize, 92usize); +payload_add!(27usize, 66usize, 93usize); +payload_add!(27usize, 67usize, 94usize); +payload_add!(27usize, 68usize, 95usize); +payload_add!(27usize, 69usize, 96usize); +payload_add!(27usize, 70usize, 97usize); +payload_add!(27usize, 71usize, 98usize); +payload_add!(27usize, 72usize, 99usize); +payload_add!(27usize, 73usize, 100usize); +payload_add!(27usize, 74usize, 101usize); +payload_add!(27usize, 75usize, 102usize); +payload_add!(27usize, 76usize, 103usize); +payload_add!(27usize, 77usize, 104usize); +payload_add!(27usize, 78usize, 105usize); +payload_add!(27usize, 79usize, 106usize); +payload_add!(27usize, 80usize, 107usize); +payload_add!(27usize, 81usize, 108usize); +payload_add!(27usize, 82usize, 109usize); +payload_add!(27usize, 83usize, 110usize); +payload_add!(27usize, 84usize, 111usize); +payload_add!(27usize, 85usize, 112usize); +payload_add!(27usize, 86usize, 113usize); +payload_add!(27usize, 87usize, 114usize); +payload_add!(27usize, 88usize, 115usize); +payload_add!(27usize, 89usize, 116usize); +payload_add!(27usize, 90usize, 117usize); +payload_add!(27usize, 91usize, 118usize); +payload_add!(27usize, 92usize, 119usize); +payload_add!(27usize, 93usize, 120usize); +payload_add!(27usize, 94usize, 121usize); +payload_add!(27usize, 95usize, 122usize); +payload_add!(27usize, 96usize, 123usize); +payload_add!(27usize, 97usize, 124usize); +payload_add!(27usize, 98usize, 125usize); +payload_add!(27usize, 99usize, 126usize); +payload_add!(27usize, 100usize, 127usize); +payload_add!(27usize, 101usize, 128usize); +payload_add!(27usize, 102usize, 129usize); +payload_add!(27usize, 103usize, 130usize); +payload_add!(27usize, 104usize, 131usize); +payload_add!(27usize, 105usize, 132usize); +payload_add!(27usize, 106usize, 133usize); +payload_add!(27usize, 107usize, 134usize); +payload_add!(27usize, 108usize, 135usize); +payload_add!(27usize, 109usize, 136usize); +payload_add!(27usize, 110usize, 137usize); +payload_add!(27usize, 111usize, 138usize); +payload_add!(27usize, 112usize, 139usize); +payload_add!(27usize, 113usize, 140usize); +payload_add!(27usize, 114usize, 141usize); +payload_add!(27usize, 115usize, 142usize); +payload_add!(27usize, 116usize, 143usize); +payload_add!(27usize, 117usize, 144usize); +payload_add!(27usize, 118usize, 145usize); +payload_add!(27usize, 119usize, 146usize); +payload_add!(27usize, 120usize, 147usize); +payload_add!(27usize, 121usize, 148usize); +payload_add!(27usize, 122usize, 149usize); +payload_add!(27usize, 123usize, 150usize); +payload_add!(27usize, 124usize, 151usize); +payload_add!(27usize, 125usize, 152usize); +payload_add!(27usize, 126usize, 153usize); +payload_add!(27usize, 127usize, 154usize); +payload_add!(27usize, 128usize, 155usize); +payload_add!(28usize, 1usize, 29usize); +payload_add!(28usize, 2usize, 30usize); +payload_add!(28usize, 3usize, 31usize); +payload_add!(28usize, 4usize, 32usize); +payload_add!(28usize, 5usize, 33usize); +payload_add!(28usize, 6usize, 34usize); +payload_add!(28usize, 7usize, 35usize); +payload_add!(28usize, 8usize, 36usize); +payload_add!(28usize, 9usize, 37usize); +payload_add!(28usize, 10usize, 38usize); +payload_add!(28usize, 11usize, 39usize); +payload_add!(28usize, 12usize, 40usize); +payload_add!(28usize, 13usize, 41usize); +payload_add!(28usize, 14usize, 42usize); +payload_add!(28usize, 15usize, 43usize); +payload_add!(28usize, 16usize, 44usize); +payload_add!(28usize, 17usize, 45usize); +payload_add!(28usize, 18usize, 46usize); +payload_add!(28usize, 19usize, 47usize); +payload_add!(28usize, 20usize, 48usize); +payload_add!(28usize, 21usize, 49usize); +payload_add!(28usize, 22usize, 50usize); +payload_add!(28usize, 23usize, 51usize); +payload_add!(28usize, 24usize, 52usize); +payload_add!(28usize, 25usize, 53usize); +payload_add!(28usize, 26usize, 54usize); +payload_add!(28usize, 27usize, 55usize); +payload_add!(28usize, 28usize, 56usize); +payload_add!(28usize, 29usize, 57usize); +payload_add!(28usize, 30usize, 58usize); +payload_add!(28usize, 31usize, 59usize); +payload_add!(28usize, 32usize, 60usize); +payload_add!(28usize, 33usize, 61usize); +payload_add!(28usize, 34usize, 62usize); +payload_add!(28usize, 35usize, 63usize); +payload_add!(28usize, 36usize, 64usize); +payload_add!(28usize, 37usize, 65usize); +payload_add!(28usize, 38usize, 66usize); +payload_add!(28usize, 39usize, 67usize); +payload_add!(28usize, 40usize, 68usize); +payload_add!(28usize, 41usize, 69usize); +payload_add!(28usize, 42usize, 70usize); +payload_add!(28usize, 43usize, 71usize); +payload_add!(28usize, 44usize, 72usize); +payload_add!(28usize, 45usize, 73usize); +payload_add!(28usize, 46usize, 74usize); +payload_add!(28usize, 47usize, 75usize); +payload_add!(28usize, 48usize, 76usize); +payload_add!(28usize, 49usize, 77usize); +payload_add!(28usize, 50usize, 78usize); +payload_add!(28usize, 51usize, 79usize); +payload_add!(28usize, 52usize, 80usize); +payload_add!(28usize, 53usize, 81usize); +payload_add!(28usize, 54usize, 82usize); +payload_add!(28usize, 55usize, 83usize); +payload_add!(28usize, 56usize, 84usize); +payload_add!(28usize, 57usize, 85usize); +payload_add!(28usize, 58usize, 86usize); +payload_add!(28usize, 59usize, 87usize); +payload_add!(28usize, 60usize, 88usize); +payload_add!(28usize, 61usize, 89usize); +payload_add!(28usize, 62usize, 90usize); +payload_add!(28usize, 63usize, 91usize); +payload_add!(28usize, 64usize, 92usize); +payload_add!(28usize, 65usize, 93usize); +payload_add!(28usize, 66usize, 94usize); +payload_add!(28usize, 67usize, 95usize); +payload_add!(28usize, 68usize, 96usize); +payload_add!(28usize, 69usize, 97usize); +payload_add!(28usize, 70usize, 98usize); +payload_add!(28usize, 71usize, 99usize); +payload_add!(28usize, 72usize, 100usize); +payload_add!(28usize, 73usize, 101usize); +payload_add!(28usize, 74usize, 102usize); +payload_add!(28usize, 75usize, 103usize); +payload_add!(28usize, 76usize, 104usize); +payload_add!(28usize, 77usize, 105usize); +payload_add!(28usize, 78usize, 106usize); +payload_add!(28usize, 79usize, 107usize); +payload_add!(28usize, 80usize, 108usize); +payload_add!(28usize, 81usize, 109usize); +payload_add!(28usize, 82usize, 110usize); +payload_add!(28usize, 83usize, 111usize); +payload_add!(28usize, 84usize, 112usize); +payload_add!(28usize, 85usize, 113usize); +payload_add!(28usize, 86usize, 114usize); +payload_add!(28usize, 87usize, 115usize); +payload_add!(28usize, 88usize, 116usize); +payload_add!(28usize, 89usize, 117usize); +payload_add!(28usize, 90usize, 118usize); +payload_add!(28usize, 91usize, 119usize); +payload_add!(28usize, 92usize, 120usize); +payload_add!(28usize, 93usize, 121usize); +payload_add!(28usize, 94usize, 122usize); +payload_add!(28usize, 95usize, 123usize); +payload_add!(28usize, 96usize, 124usize); +payload_add!(28usize, 97usize, 125usize); +payload_add!(28usize, 98usize, 126usize); +payload_add!(28usize, 99usize, 127usize); +payload_add!(28usize, 100usize, 128usize); +payload_add!(28usize, 101usize, 129usize); +payload_add!(28usize, 102usize, 130usize); +payload_add!(28usize, 103usize, 131usize); +payload_add!(28usize, 104usize, 132usize); +payload_add!(28usize, 105usize, 133usize); +payload_add!(28usize, 106usize, 134usize); +payload_add!(28usize, 107usize, 135usize); +payload_add!(28usize, 108usize, 136usize); +payload_add!(28usize, 109usize, 137usize); +payload_add!(28usize, 110usize, 138usize); +payload_add!(28usize, 111usize, 139usize); +payload_add!(28usize, 112usize, 140usize); +payload_add!(28usize, 113usize, 141usize); +payload_add!(28usize, 114usize, 142usize); +payload_add!(28usize, 115usize, 143usize); +payload_add!(28usize, 116usize, 144usize); +payload_add!(28usize, 117usize, 145usize); +payload_add!(28usize, 118usize, 146usize); +payload_add!(28usize, 119usize, 147usize); +payload_add!(28usize, 120usize, 148usize); +payload_add!(28usize, 121usize, 149usize); +payload_add!(28usize, 122usize, 150usize); +payload_add!(28usize, 123usize, 151usize); +payload_add!(28usize, 124usize, 152usize); +payload_add!(28usize, 125usize, 153usize); +payload_add!(28usize, 126usize, 154usize); +payload_add!(28usize, 127usize, 155usize); +payload_add!(28usize, 128usize, 156usize); +payload_add!(29usize, 1usize, 30usize); +payload_add!(29usize, 2usize, 31usize); +payload_add!(29usize, 3usize, 32usize); +payload_add!(29usize, 4usize, 33usize); +payload_add!(29usize, 5usize, 34usize); +payload_add!(29usize, 6usize, 35usize); +payload_add!(29usize, 7usize, 36usize); +payload_add!(29usize, 8usize, 37usize); +payload_add!(29usize, 9usize, 38usize); +payload_add!(29usize, 10usize, 39usize); +payload_add!(29usize, 11usize, 40usize); +payload_add!(29usize, 12usize, 41usize); +payload_add!(29usize, 13usize, 42usize); +payload_add!(29usize, 14usize, 43usize); +payload_add!(29usize, 15usize, 44usize); +payload_add!(29usize, 16usize, 45usize); +payload_add!(29usize, 17usize, 46usize); +payload_add!(29usize, 18usize, 47usize); +payload_add!(29usize, 19usize, 48usize); +payload_add!(29usize, 20usize, 49usize); +payload_add!(29usize, 21usize, 50usize); +payload_add!(29usize, 22usize, 51usize); +payload_add!(29usize, 23usize, 52usize); +payload_add!(29usize, 24usize, 53usize); +payload_add!(29usize, 25usize, 54usize); +payload_add!(29usize, 26usize, 55usize); +payload_add!(29usize, 27usize, 56usize); +payload_add!(29usize, 28usize, 57usize); +payload_add!(29usize, 29usize, 58usize); +payload_add!(29usize, 30usize, 59usize); +payload_add!(29usize, 31usize, 60usize); +payload_add!(29usize, 32usize, 61usize); +payload_add!(29usize, 33usize, 62usize); +payload_add!(29usize, 34usize, 63usize); +payload_add!(29usize, 35usize, 64usize); +payload_add!(29usize, 36usize, 65usize); +payload_add!(29usize, 37usize, 66usize); +payload_add!(29usize, 38usize, 67usize); +payload_add!(29usize, 39usize, 68usize); +payload_add!(29usize, 40usize, 69usize); +payload_add!(29usize, 41usize, 70usize); +payload_add!(29usize, 42usize, 71usize); +payload_add!(29usize, 43usize, 72usize); +payload_add!(29usize, 44usize, 73usize); +payload_add!(29usize, 45usize, 74usize); +payload_add!(29usize, 46usize, 75usize); +payload_add!(29usize, 47usize, 76usize); +payload_add!(29usize, 48usize, 77usize); +payload_add!(29usize, 49usize, 78usize); +payload_add!(29usize, 50usize, 79usize); +payload_add!(29usize, 51usize, 80usize); +payload_add!(29usize, 52usize, 81usize); +payload_add!(29usize, 53usize, 82usize); +payload_add!(29usize, 54usize, 83usize); +payload_add!(29usize, 55usize, 84usize); +payload_add!(29usize, 56usize, 85usize); +payload_add!(29usize, 57usize, 86usize); +payload_add!(29usize, 58usize, 87usize); +payload_add!(29usize, 59usize, 88usize); +payload_add!(29usize, 60usize, 89usize); +payload_add!(29usize, 61usize, 90usize); +payload_add!(29usize, 62usize, 91usize); +payload_add!(29usize, 63usize, 92usize); +payload_add!(29usize, 64usize, 93usize); +payload_add!(29usize, 65usize, 94usize); +payload_add!(29usize, 66usize, 95usize); +payload_add!(29usize, 67usize, 96usize); +payload_add!(29usize, 68usize, 97usize); +payload_add!(29usize, 69usize, 98usize); +payload_add!(29usize, 70usize, 99usize); +payload_add!(29usize, 71usize, 100usize); +payload_add!(29usize, 72usize, 101usize); +payload_add!(29usize, 73usize, 102usize); +payload_add!(29usize, 74usize, 103usize); +payload_add!(29usize, 75usize, 104usize); +payload_add!(29usize, 76usize, 105usize); +payload_add!(29usize, 77usize, 106usize); +payload_add!(29usize, 78usize, 107usize); +payload_add!(29usize, 79usize, 108usize); +payload_add!(29usize, 80usize, 109usize); +payload_add!(29usize, 81usize, 110usize); +payload_add!(29usize, 82usize, 111usize); +payload_add!(29usize, 83usize, 112usize); +payload_add!(29usize, 84usize, 113usize); +payload_add!(29usize, 85usize, 114usize); +payload_add!(29usize, 86usize, 115usize); +payload_add!(29usize, 87usize, 116usize); +payload_add!(29usize, 88usize, 117usize); +payload_add!(29usize, 89usize, 118usize); +payload_add!(29usize, 90usize, 119usize); +payload_add!(29usize, 91usize, 120usize); +payload_add!(29usize, 92usize, 121usize); +payload_add!(29usize, 93usize, 122usize); +payload_add!(29usize, 94usize, 123usize); +payload_add!(29usize, 95usize, 124usize); +payload_add!(29usize, 96usize, 125usize); +payload_add!(29usize, 97usize, 126usize); +payload_add!(29usize, 98usize, 127usize); +payload_add!(29usize, 99usize, 128usize); +payload_add!(29usize, 100usize, 129usize); +payload_add!(29usize, 101usize, 130usize); +payload_add!(29usize, 102usize, 131usize); +payload_add!(29usize, 103usize, 132usize); +payload_add!(29usize, 104usize, 133usize); +payload_add!(29usize, 105usize, 134usize); +payload_add!(29usize, 106usize, 135usize); +payload_add!(29usize, 107usize, 136usize); +payload_add!(29usize, 108usize, 137usize); +payload_add!(29usize, 109usize, 138usize); +payload_add!(29usize, 110usize, 139usize); +payload_add!(29usize, 111usize, 140usize); +payload_add!(29usize, 112usize, 141usize); +payload_add!(29usize, 113usize, 142usize); +payload_add!(29usize, 114usize, 143usize); +payload_add!(29usize, 115usize, 144usize); +payload_add!(29usize, 116usize, 145usize); +payload_add!(29usize, 117usize, 146usize); +payload_add!(29usize, 118usize, 147usize); +payload_add!(29usize, 119usize, 148usize); +payload_add!(29usize, 120usize, 149usize); +payload_add!(29usize, 121usize, 150usize); +payload_add!(29usize, 122usize, 151usize); +payload_add!(29usize, 123usize, 152usize); +payload_add!(29usize, 124usize, 153usize); +payload_add!(29usize, 125usize, 154usize); +payload_add!(29usize, 126usize, 155usize); +payload_add!(29usize, 127usize, 156usize); +payload_add!(29usize, 128usize, 157usize); +payload_add!(30usize, 1usize, 31usize); +payload_add!(30usize, 2usize, 32usize); +payload_add!(30usize, 3usize, 33usize); +payload_add!(30usize, 4usize, 34usize); +payload_add!(30usize, 5usize, 35usize); +payload_add!(30usize, 6usize, 36usize); +payload_add!(30usize, 7usize, 37usize); +payload_add!(30usize, 8usize, 38usize); +payload_add!(30usize, 9usize, 39usize); +payload_add!(30usize, 10usize, 40usize); +payload_add!(30usize, 11usize, 41usize); +payload_add!(30usize, 12usize, 42usize); +payload_add!(30usize, 13usize, 43usize); +payload_add!(30usize, 14usize, 44usize); +payload_add!(30usize, 15usize, 45usize); +payload_add!(30usize, 16usize, 46usize); +payload_add!(30usize, 17usize, 47usize); +payload_add!(30usize, 18usize, 48usize); +payload_add!(30usize, 19usize, 49usize); +payload_add!(30usize, 20usize, 50usize); +payload_add!(30usize, 21usize, 51usize); +payload_add!(30usize, 22usize, 52usize); +payload_add!(30usize, 23usize, 53usize); +payload_add!(30usize, 24usize, 54usize); +payload_add!(30usize, 25usize, 55usize); +payload_add!(30usize, 26usize, 56usize); +payload_add!(30usize, 27usize, 57usize); +payload_add!(30usize, 28usize, 58usize); +payload_add!(30usize, 29usize, 59usize); +payload_add!(30usize, 30usize, 60usize); +payload_add!(30usize, 31usize, 61usize); +payload_add!(30usize, 32usize, 62usize); +payload_add!(30usize, 33usize, 63usize); +payload_add!(30usize, 34usize, 64usize); +payload_add!(30usize, 35usize, 65usize); +payload_add!(30usize, 36usize, 66usize); +payload_add!(30usize, 37usize, 67usize); +payload_add!(30usize, 38usize, 68usize); +payload_add!(30usize, 39usize, 69usize); +payload_add!(30usize, 40usize, 70usize); +payload_add!(30usize, 41usize, 71usize); +payload_add!(30usize, 42usize, 72usize); +payload_add!(30usize, 43usize, 73usize); +payload_add!(30usize, 44usize, 74usize); +payload_add!(30usize, 45usize, 75usize); +payload_add!(30usize, 46usize, 76usize); +payload_add!(30usize, 47usize, 77usize); +payload_add!(30usize, 48usize, 78usize); +payload_add!(30usize, 49usize, 79usize); +payload_add!(30usize, 50usize, 80usize); +payload_add!(30usize, 51usize, 81usize); +payload_add!(30usize, 52usize, 82usize); +payload_add!(30usize, 53usize, 83usize); +payload_add!(30usize, 54usize, 84usize); +payload_add!(30usize, 55usize, 85usize); +payload_add!(30usize, 56usize, 86usize); +payload_add!(30usize, 57usize, 87usize); +payload_add!(30usize, 58usize, 88usize); +payload_add!(30usize, 59usize, 89usize); +payload_add!(30usize, 60usize, 90usize); +payload_add!(30usize, 61usize, 91usize); +payload_add!(30usize, 62usize, 92usize); +payload_add!(30usize, 63usize, 93usize); +payload_add!(30usize, 64usize, 94usize); +payload_add!(30usize, 65usize, 95usize); +payload_add!(30usize, 66usize, 96usize); +payload_add!(30usize, 67usize, 97usize); +payload_add!(30usize, 68usize, 98usize); +payload_add!(30usize, 69usize, 99usize); +payload_add!(30usize, 70usize, 100usize); +payload_add!(30usize, 71usize, 101usize); +payload_add!(30usize, 72usize, 102usize); +payload_add!(30usize, 73usize, 103usize); +payload_add!(30usize, 74usize, 104usize); +payload_add!(30usize, 75usize, 105usize); +payload_add!(30usize, 76usize, 106usize); +payload_add!(30usize, 77usize, 107usize); +payload_add!(30usize, 78usize, 108usize); +payload_add!(30usize, 79usize, 109usize); +payload_add!(30usize, 80usize, 110usize); +payload_add!(30usize, 81usize, 111usize); +payload_add!(30usize, 82usize, 112usize); +payload_add!(30usize, 83usize, 113usize); +payload_add!(30usize, 84usize, 114usize); +payload_add!(30usize, 85usize, 115usize); +payload_add!(30usize, 86usize, 116usize); +payload_add!(30usize, 87usize, 117usize); +payload_add!(30usize, 88usize, 118usize); +payload_add!(30usize, 89usize, 119usize); +payload_add!(30usize, 90usize, 120usize); +payload_add!(30usize, 91usize, 121usize); +payload_add!(30usize, 92usize, 122usize); +payload_add!(30usize, 93usize, 123usize); +payload_add!(30usize, 94usize, 124usize); +payload_add!(30usize, 95usize, 125usize); +payload_add!(30usize, 96usize, 126usize); +payload_add!(30usize, 97usize, 127usize); +payload_add!(30usize, 98usize, 128usize); +payload_add!(30usize, 99usize, 129usize); +payload_add!(30usize, 100usize, 130usize); +payload_add!(30usize, 101usize, 131usize); +payload_add!(30usize, 102usize, 132usize); +payload_add!(30usize, 103usize, 133usize); +payload_add!(30usize, 104usize, 134usize); +payload_add!(30usize, 105usize, 135usize); +payload_add!(30usize, 106usize, 136usize); +payload_add!(30usize, 107usize, 137usize); +payload_add!(30usize, 108usize, 138usize); +payload_add!(30usize, 109usize, 139usize); +payload_add!(30usize, 110usize, 140usize); +payload_add!(30usize, 111usize, 141usize); +payload_add!(30usize, 112usize, 142usize); +payload_add!(30usize, 113usize, 143usize); +payload_add!(30usize, 114usize, 144usize); +payload_add!(30usize, 115usize, 145usize); +payload_add!(30usize, 116usize, 146usize); +payload_add!(30usize, 117usize, 147usize); +payload_add!(30usize, 118usize, 148usize); +payload_add!(30usize, 119usize, 149usize); +payload_add!(30usize, 120usize, 150usize); +payload_add!(30usize, 121usize, 151usize); +payload_add!(30usize, 122usize, 152usize); +payload_add!(30usize, 123usize, 153usize); +payload_add!(30usize, 124usize, 154usize); +payload_add!(30usize, 125usize, 155usize); +payload_add!(30usize, 126usize, 156usize); +payload_add!(30usize, 127usize, 157usize); +payload_add!(30usize, 128usize, 158usize); +payload_add!(31usize, 1usize, 32usize); +payload_add!(31usize, 2usize, 33usize); +payload_add!(31usize, 3usize, 34usize); +payload_add!(31usize, 4usize, 35usize); +payload_add!(31usize, 5usize, 36usize); +payload_add!(31usize, 6usize, 37usize); +payload_add!(31usize, 7usize, 38usize); +payload_add!(31usize, 8usize, 39usize); +payload_add!(31usize, 9usize, 40usize); +payload_add!(31usize, 10usize, 41usize); +payload_add!(31usize, 11usize, 42usize); +payload_add!(31usize, 12usize, 43usize); +payload_add!(31usize, 13usize, 44usize); +payload_add!(31usize, 14usize, 45usize); +payload_add!(31usize, 15usize, 46usize); +payload_add!(31usize, 16usize, 47usize); +payload_add!(31usize, 17usize, 48usize); +payload_add!(31usize, 18usize, 49usize); +payload_add!(31usize, 19usize, 50usize); +payload_add!(31usize, 20usize, 51usize); +payload_add!(31usize, 21usize, 52usize); +payload_add!(31usize, 22usize, 53usize); +payload_add!(31usize, 23usize, 54usize); +payload_add!(31usize, 24usize, 55usize); +payload_add!(31usize, 25usize, 56usize); +payload_add!(31usize, 26usize, 57usize); +payload_add!(31usize, 27usize, 58usize); +payload_add!(31usize, 28usize, 59usize); +payload_add!(31usize, 29usize, 60usize); +payload_add!(31usize, 30usize, 61usize); +payload_add!(31usize, 31usize, 62usize); +payload_add!(31usize, 32usize, 63usize); +payload_add!(31usize, 33usize, 64usize); +payload_add!(31usize, 34usize, 65usize); +payload_add!(31usize, 35usize, 66usize); +payload_add!(31usize, 36usize, 67usize); +payload_add!(31usize, 37usize, 68usize); +payload_add!(31usize, 38usize, 69usize); +payload_add!(31usize, 39usize, 70usize); +payload_add!(31usize, 40usize, 71usize); +payload_add!(31usize, 41usize, 72usize); +payload_add!(31usize, 42usize, 73usize); +payload_add!(31usize, 43usize, 74usize); +payload_add!(31usize, 44usize, 75usize); +payload_add!(31usize, 45usize, 76usize); +payload_add!(31usize, 46usize, 77usize); +payload_add!(31usize, 47usize, 78usize); +payload_add!(31usize, 48usize, 79usize); +payload_add!(31usize, 49usize, 80usize); +payload_add!(31usize, 50usize, 81usize); +payload_add!(31usize, 51usize, 82usize); +payload_add!(31usize, 52usize, 83usize); +payload_add!(31usize, 53usize, 84usize); +payload_add!(31usize, 54usize, 85usize); +payload_add!(31usize, 55usize, 86usize); +payload_add!(31usize, 56usize, 87usize); +payload_add!(31usize, 57usize, 88usize); +payload_add!(31usize, 58usize, 89usize); +payload_add!(31usize, 59usize, 90usize); +payload_add!(31usize, 60usize, 91usize); +payload_add!(31usize, 61usize, 92usize); +payload_add!(31usize, 62usize, 93usize); +payload_add!(31usize, 63usize, 94usize); +payload_add!(31usize, 64usize, 95usize); +payload_add!(31usize, 65usize, 96usize); +payload_add!(31usize, 66usize, 97usize); +payload_add!(31usize, 67usize, 98usize); +payload_add!(31usize, 68usize, 99usize); +payload_add!(31usize, 69usize, 100usize); +payload_add!(31usize, 70usize, 101usize); +payload_add!(31usize, 71usize, 102usize); +payload_add!(31usize, 72usize, 103usize); +payload_add!(31usize, 73usize, 104usize); +payload_add!(31usize, 74usize, 105usize); +payload_add!(31usize, 75usize, 106usize); +payload_add!(31usize, 76usize, 107usize); +payload_add!(31usize, 77usize, 108usize); +payload_add!(31usize, 78usize, 109usize); +payload_add!(31usize, 79usize, 110usize); +payload_add!(31usize, 80usize, 111usize); +payload_add!(31usize, 81usize, 112usize); +payload_add!(31usize, 82usize, 113usize); +payload_add!(31usize, 83usize, 114usize); +payload_add!(31usize, 84usize, 115usize); +payload_add!(31usize, 85usize, 116usize); +payload_add!(31usize, 86usize, 117usize); +payload_add!(31usize, 87usize, 118usize); +payload_add!(31usize, 88usize, 119usize); +payload_add!(31usize, 89usize, 120usize); +payload_add!(31usize, 90usize, 121usize); +payload_add!(31usize, 91usize, 122usize); +payload_add!(31usize, 92usize, 123usize); +payload_add!(31usize, 93usize, 124usize); +payload_add!(31usize, 94usize, 125usize); +payload_add!(31usize, 95usize, 126usize); +payload_add!(31usize, 96usize, 127usize); +payload_add!(31usize, 97usize, 128usize); +payload_add!(31usize, 98usize, 129usize); +payload_add!(31usize, 99usize, 130usize); +payload_add!(31usize, 100usize, 131usize); +payload_add!(31usize, 101usize, 132usize); +payload_add!(31usize, 102usize, 133usize); +payload_add!(31usize, 103usize, 134usize); +payload_add!(31usize, 104usize, 135usize); +payload_add!(31usize, 105usize, 136usize); +payload_add!(31usize, 106usize, 137usize); +payload_add!(31usize, 107usize, 138usize); +payload_add!(31usize, 108usize, 139usize); +payload_add!(31usize, 109usize, 140usize); +payload_add!(31usize, 110usize, 141usize); +payload_add!(31usize, 111usize, 142usize); +payload_add!(31usize, 112usize, 143usize); +payload_add!(31usize, 113usize, 144usize); +payload_add!(31usize, 114usize, 145usize); +payload_add!(31usize, 115usize, 146usize); +payload_add!(31usize, 116usize, 147usize); +payload_add!(31usize, 117usize, 148usize); +payload_add!(31usize, 118usize, 149usize); +payload_add!(31usize, 119usize, 150usize); +payload_add!(31usize, 120usize, 151usize); +payload_add!(31usize, 121usize, 152usize); +payload_add!(31usize, 122usize, 153usize); +payload_add!(31usize, 123usize, 154usize); +payload_add!(31usize, 124usize, 155usize); +payload_add!(31usize, 125usize, 156usize); +payload_add!(31usize, 126usize, 157usize); +payload_add!(31usize, 127usize, 158usize); +payload_add!(31usize, 128usize, 159usize); +payload_add!(32usize, 1usize, 33usize); +payload_add!(32usize, 2usize, 34usize); +payload_add!(32usize, 3usize, 35usize); +payload_add!(32usize, 4usize, 36usize); +payload_add!(32usize, 5usize, 37usize); +payload_add!(32usize, 6usize, 38usize); +payload_add!(32usize, 7usize, 39usize); +payload_add!(32usize, 8usize, 40usize); +payload_add!(32usize, 9usize, 41usize); +payload_add!(32usize, 10usize, 42usize); +payload_add!(32usize, 11usize, 43usize); +payload_add!(32usize, 12usize, 44usize); +payload_add!(32usize, 13usize, 45usize); +payload_add!(32usize, 14usize, 46usize); +payload_add!(32usize, 15usize, 47usize); +payload_add!(32usize, 16usize, 48usize); +payload_add!(32usize, 17usize, 49usize); +payload_add!(32usize, 18usize, 50usize); +payload_add!(32usize, 19usize, 51usize); +payload_add!(32usize, 20usize, 52usize); +payload_add!(32usize, 21usize, 53usize); +payload_add!(32usize, 22usize, 54usize); +payload_add!(32usize, 23usize, 55usize); +payload_add!(32usize, 24usize, 56usize); +payload_add!(32usize, 25usize, 57usize); +payload_add!(32usize, 26usize, 58usize); +payload_add!(32usize, 27usize, 59usize); +payload_add!(32usize, 28usize, 60usize); +payload_add!(32usize, 29usize, 61usize); +payload_add!(32usize, 30usize, 62usize); +payload_add!(32usize, 31usize, 63usize); +payload_add!(32usize, 32usize, 64usize); +payload_add!(32usize, 33usize, 65usize); +payload_add!(32usize, 34usize, 66usize); +payload_add!(32usize, 35usize, 67usize); +payload_add!(32usize, 36usize, 68usize); +payload_add!(32usize, 37usize, 69usize); +payload_add!(32usize, 38usize, 70usize); +payload_add!(32usize, 39usize, 71usize); +payload_add!(32usize, 40usize, 72usize); +payload_add!(32usize, 41usize, 73usize); +payload_add!(32usize, 42usize, 74usize); +payload_add!(32usize, 43usize, 75usize); +payload_add!(32usize, 44usize, 76usize); +payload_add!(32usize, 45usize, 77usize); +payload_add!(32usize, 46usize, 78usize); +payload_add!(32usize, 47usize, 79usize); +payload_add!(32usize, 48usize, 80usize); +payload_add!(32usize, 49usize, 81usize); +payload_add!(32usize, 50usize, 82usize); +payload_add!(32usize, 51usize, 83usize); +payload_add!(32usize, 52usize, 84usize); +payload_add!(32usize, 53usize, 85usize); +payload_add!(32usize, 54usize, 86usize); +payload_add!(32usize, 55usize, 87usize); +payload_add!(32usize, 56usize, 88usize); +payload_add!(32usize, 57usize, 89usize); +payload_add!(32usize, 58usize, 90usize); +payload_add!(32usize, 59usize, 91usize); +payload_add!(32usize, 60usize, 92usize); +payload_add!(32usize, 61usize, 93usize); +payload_add!(32usize, 62usize, 94usize); +payload_add!(32usize, 63usize, 95usize); +payload_add!(32usize, 64usize, 96usize); +payload_add!(32usize, 65usize, 97usize); +payload_add!(32usize, 66usize, 98usize); +payload_add!(32usize, 67usize, 99usize); +payload_add!(32usize, 68usize, 100usize); +payload_add!(32usize, 69usize, 101usize); +payload_add!(32usize, 70usize, 102usize); +payload_add!(32usize, 71usize, 103usize); +payload_add!(32usize, 72usize, 104usize); +payload_add!(32usize, 73usize, 105usize); +payload_add!(32usize, 74usize, 106usize); +payload_add!(32usize, 75usize, 107usize); +payload_add!(32usize, 76usize, 108usize); +payload_add!(32usize, 77usize, 109usize); +payload_add!(32usize, 78usize, 110usize); +payload_add!(32usize, 79usize, 111usize); +payload_add!(32usize, 80usize, 112usize); +payload_add!(32usize, 81usize, 113usize); +payload_add!(32usize, 82usize, 114usize); +payload_add!(32usize, 83usize, 115usize); +payload_add!(32usize, 84usize, 116usize); +payload_add!(32usize, 85usize, 117usize); +payload_add!(32usize, 86usize, 118usize); +payload_add!(32usize, 87usize, 119usize); +payload_add!(32usize, 88usize, 120usize); +payload_add!(32usize, 89usize, 121usize); +payload_add!(32usize, 90usize, 122usize); +payload_add!(32usize, 91usize, 123usize); +payload_add!(32usize, 92usize, 124usize); +payload_add!(32usize, 93usize, 125usize); +payload_add!(32usize, 94usize, 126usize); +payload_add!(32usize, 95usize, 127usize); +payload_add!(32usize, 96usize, 128usize); +payload_add!(32usize, 97usize, 129usize); +payload_add!(32usize, 98usize, 130usize); +payload_add!(32usize, 99usize, 131usize); +payload_add!(32usize, 100usize, 132usize); +payload_add!(32usize, 101usize, 133usize); +payload_add!(32usize, 102usize, 134usize); +payload_add!(32usize, 103usize, 135usize); +payload_add!(32usize, 104usize, 136usize); +payload_add!(32usize, 105usize, 137usize); +payload_add!(32usize, 106usize, 138usize); +payload_add!(32usize, 107usize, 139usize); +payload_add!(32usize, 108usize, 140usize); +payload_add!(32usize, 109usize, 141usize); +payload_add!(32usize, 110usize, 142usize); +payload_add!(32usize, 111usize, 143usize); +payload_add!(32usize, 112usize, 144usize); +payload_add!(32usize, 113usize, 145usize); +payload_add!(32usize, 114usize, 146usize); +payload_add!(32usize, 115usize, 147usize); +payload_add!(32usize, 116usize, 148usize); +payload_add!(32usize, 117usize, 149usize); +payload_add!(32usize, 118usize, 150usize); +payload_add!(32usize, 119usize, 151usize); +payload_add!(32usize, 120usize, 152usize); +payload_add!(32usize, 121usize, 153usize); +payload_add!(32usize, 122usize, 154usize); +payload_add!(32usize, 123usize, 155usize); +payload_add!(32usize, 124usize, 156usize); +payload_add!(32usize, 125usize, 157usize); +payload_add!(32usize, 126usize, 158usize); +payload_add!(32usize, 127usize, 159usize); +payload_add!(32usize, 128usize, 160usize); +payload_add!(33usize, 1usize, 34usize); +payload_add!(33usize, 2usize, 35usize); +payload_add!(33usize, 3usize, 36usize); +payload_add!(33usize, 4usize, 37usize); +payload_add!(33usize, 5usize, 38usize); +payload_add!(33usize, 6usize, 39usize); +payload_add!(33usize, 7usize, 40usize); +payload_add!(33usize, 8usize, 41usize); +payload_add!(33usize, 9usize, 42usize); +payload_add!(33usize, 10usize, 43usize); +payload_add!(33usize, 11usize, 44usize); +payload_add!(33usize, 12usize, 45usize); +payload_add!(33usize, 13usize, 46usize); +payload_add!(33usize, 14usize, 47usize); +payload_add!(33usize, 15usize, 48usize); +payload_add!(33usize, 16usize, 49usize); +payload_add!(33usize, 17usize, 50usize); +payload_add!(33usize, 18usize, 51usize); +payload_add!(33usize, 19usize, 52usize); +payload_add!(33usize, 20usize, 53usize); +payload_add!(33usize, 21usize, 54usize); +payload_add!(33usize, 22usize, 55usize); +payload_add!(33usize, 23usize, 56usize); +payload_add!(33usize, 24usize, 57usize); +payload_add!(33usize, 25usize, 58usize); +payload_add!(33usize, 26usize, 59usize); +payload_add!(33usize, 27usize, 60usize); +payload_add!(33usize, 28usize, 61usize); +payload_add!(33usize, 29usize, 62usize); +payload_add!(33usize, 30usize, 63usize); +payload_add!(33usize, 31usize, 64usize); +payload_add!(33usize, 32usize, 65usize); +payload_add!(33usize, 33usize, 66usize); +payload_add!(33usize, 34usize, 67usize); +payload_add!(33usize, 35usize, 68usize); +payload_add!(33usize, 36usize, 69usize); +payload_add!(33usize, 37usize, 70usize); +payload_add!(33usize, 38usize, 71usize); +payload_add!(33usize, 39usize, 72usize); +payload_add!(33usize, 40usize, 73usize); +payload_add!(33usize, 41usize, 74usize); +payload_add!(33usize, 42usize, 75usize); +payload_add!(33usize, 43usize, 76usize); +payload_add!(33usize, 44usize, 77usize); +payload_add!(33usize, 45usize, 78usize); +payload_add!(33usize, 46usize, 79usize); +payload_add!(33usize, 47usize, 80usize); +payload_add!(33usize, 48usize, 81usize); +payload_add!(33usize, 49usize, 82usize); +payload_add!(33usize, 50usize, 83usize); +payload_add!(33usize, 51usize, 84usize); +payload_add!(33usize, 52usize, 85usize); +payload_add!(33usize, 53usize, 86usize); +payload_add!(33usize, 54usize, 87usize); +payload_add!(33usize, 55usize, 88usize); +payload_add!(33usize, 56usize, 89usize); +payload_add!(33usize, 57usize, 90usize); +payload_add!(33usize, 58usize, 91usize); +payload_add!(33usize, 59usize, 92usize); +payload_add!(33usize, 60usize, 93usize); +payload_add!(33usize, 61usize, 94usize); +payload_add!(33usize, 62usize, 95usize); +payload_add!(33usize, 63usize, 96usize); +payload_add!(33usize, 64usize, 97usize); +payload_add!(33usize, 65usize, 98usize); +payload_add!(33usize, 66usize, 99usize); +payload_add!(33usize, 67usize, 100usize); +payload_add!(33usize, 68usize, 101usize); +payload_add!(33usize, 69usize, 102usize); +payload_add!(33usize, 70usize, 103usize); +payload_add!(33usize, 71usize, 104usize); +payload_add!(33usize, 72usize, 105usize); +payload_add!(33usize, 73usize, 106usize); +payload_add!(33usize, 74usize, 107usize); +payload_add!(33usize, 75usize, 108usize); +payload_add!(33usize, 76usize, 109usize); +payload_add!(33usize, 77usize, 110usize); +payload_add!(33usize, 78usize, 111usize); +payload_add!(33usize, 79usize, 112usize); +payload_add!(33usize, 80usize, 113usize); +payload_add!(33usize, 81usize, 114usize); +payload_add!(33usize, 82usize, 115usize); +payload_add!(33usize, 83usize, 116usize); +payload_add!(33usize, 84usize, 117usize); +payload_add!(33usize, 85usize, 118usize); +payload_add!(33usize, 86usize, 119usize); +payload_add!(33usize, 87usize, 120usize); +payload_add!(33usize, 88usize, 121usize); +payload_add!(33usize, 89usize, 122usize); +payload_add!(33usize, 90usize, 123usize); +payload_add!(33usize, 91usize, 124usize); +payload_add!(33usize, 92usize, 125usize); +payload_add!(33usize, 93usize, 126usize); +payload_add!(33usize, 94usize, 127usize); +payload_add!(33usize, 95usize, 128usize); +payload_add!(33usize, 96usize, 129usize); +payload_add!(33usize, 97usize, 130usize); +payload_add!(33usize, 98usize, 131usize); +payload_add!(33usize, 99usize, 132usize); +payload_add!(33usize, 100usize, 133usize); +payload_add!(33usize, 101usize, 134usize); +payload_add!(33usize, 102usize, 135usize); +payload_add!(33usize, 103usize, 136usize); +payload_add!(33usize, 104usize, 137usize); +payload_add!(33usize, 105usize, 138usize); +payload_add!(33usize, 106usize, 139usize); +payload_add!(33usize, 107usize, 140usize); +payload_add!(33usize, 108usize, 141usize); +payload_add!(33usize, 109usize, 142usize); +payload_add!(33usize, 110usize, 143usize); +payload_add!(33usize, 111usize, 144usize); +payload_add!(33usize, 112usize, 145usize); +payload_add!(33usize, 113usize, 146usize); +payload_add!(33usize, 114usize, 147usize); +payload_add!(33usize, 115usize, 148usize); +payload_add!(33usize, 116usize, 149usize); +payload_add!(33usize, 117usize, 150usize); +payload_add!(33usize, 118usize, 151usize); +payload_add!(33usize, 119usize, 152usize); +payload_add!(33usize, 120usize, 153usize); +payload_add!(33usize, 121usize, 154usize); +payload_add!(33usize, 122usize, 155usize); +payload_add!(33usize, 123usize, 156usize); +payload_add!(33usize, 124usize, 157usize); +payload_add!(33usize, 125usize, 158usize); +payload_add!(33usize, 126usize, 159usize); +payload_add!(33usize, 127usize, 160usize); +payload_add!(33usize, 128usize, 161usize); +payload_add!(34usize, 1usize, 35usize); +payload_add!(34usize, 2usize, 36usize); +payload_add!(34usize, 3usize, 37usize); +payload_add!(34usize, 4usize, 38usize); +payload_add!(34usize, 5usize, 39usize); +payload_add!(34usize, 6usize, 40usize); +payload_add!(34usize, 7usize, 41usize); +payload_add!(34usize, 8usize, 42usize); +payload_add!(34usize, 9usize, 43usize); +payload_add!(34usize, 10usize, 44usize); +payload_add!(34usize, 11usize, 45usize); +payload_add!(34usize, 12usize, 46usize); +payload_add!(34usize, 13usize, 47usize); +payload_add!(34usize, 14usize, 48usize); +payload_add!(34usize, 15usize, 49usize); +payload_add!(34usize, 16usize, 50usize); +payload_add!(34usize, 17usize, 51usize); +payload_add!(34usize, 18usize, 52usize); +payload_add!(34usize, 19usize, 53usize); +payload_add!(34usize, 20usize, 54usize); +payload_add!(34usize, 21usize, 55usize); +payload_add!(34usize, 22usize, 56usize); +payload_add!(34usize, 23usize, 57usize); +payload_add!(34usize, 24usize, 58usize); +payload_add!(34usize, 25usize, 59usize); +payload_add!(34usize, 26usize, 60usize); +payload_add!(34usize, 27usize, 61usize); +payload_add!(34usize, 28usize, 62usize); +payload_add!(34usize, 29usize, 63usize); +payload_add!(34usize, 30usize, 64usize); +payload_add!(34usize, 31usize, 65usize); +payload_add!(34usize, 32usize, 66usize); +payload_add!(34usize, 33usize, 67usize); +payload_add!(34usize, 34usize, 68usize); +payload_add!(34usize, 35usize, 69usize); +payload_add!(34usize, 36usize, 70usize); +payload_add!(34usize, 37usize, 71usize); +payload_add!(34usize, 38usize, 72usize); +payload_add!(34usize, 39usize, 73usize); +payload_add!(34usize, 40usize, 74usize); +payload_add!(34usize, 41usize, 75usize); +payload_add!(34usize, 42usize, 76usize); +payload_add!(34usize, 43usize, 77usize); +payload_add!(34usize, 44usize, 78usize); +payload_add!(34usize, 45usize, 79usize); +payload_add!(34usize, 46usize, 80usize); +payload_add!(34usize, 47usize, 81usize); +payload_add!(34usize, 48usize, 82usize); +payload_add!(34usize, 49usize, 83usize); +payload_add!(34usize, 50usize, 84usize); +payload_add!(34usize, 51usize, 85usize); +payload_add!(34usize, 52usize, 86usize); +payload_add!(34usize, 53usize, 87usize); +payload_add!(34usize, 54usize, 88usize); +payload_add!(34usize, 55usize, 89usize); +payload_add!(34usize, 56usize, 90usize); +payload_add!(34usize, 57usize, 91usize); +payload_add!(34usize, 58usize, 92usize); +payload_add!(34usize, 59usize, 93usize); +payload_add!(34usize, 60usize, 94usize); +payload_add!(34usize, 61usize, 95usize); +payload_add!(34usize, 62usize, 96usize); +payload_add!(34usize, 63usize, 97usize); +payload_add!(34usize, 64usize, 98usize); +payload_add!(34usize, 65usize, 99usize); +payload_add!(34usize, 66usize, 100usize); +payload_add!(34usize, 67usize, 101usize); +payload_add!(34usize, 68usize, 102usize); +payload_add!(34usize, 69usize, 103usize); +payload_add!(34usize, 70usize, 104usize); +payload_add!(34usize, 71usize, 105usize); +payload_add!(34usize, 72usize, 106usize); +payload_add!(34usize, 73usize, 107usize); +payload_add!(34usize, 74usize, 108usize); +payload_add!(34usize, 75usize, 109usize); +payload_add!(34usize, 76usize, 110usize); +payload_add!(34usize, 77usize, 111usize); +payload_add!(34usize, 78usize, 112usize); +payload_add!(34usize, 79usize, 113usize); +payload_add!(34usize, 80usize, 114usize); +payload_add!(34usize, 81usize, 115usize); +payload_add!(34usize, 82usize, 116usize); +payload_add!(34usize, 83usize, 117usize); +payload_add!(34usize, 84usize, 118usize); +payload_add!(34usize, 85usize, 119usize); +payload_add!(34usize, 86usize, 120usize); +payload_add!(34usize, 87usize, 121usize); +payload_add!(34usize, 88usize, 122usize); +payload_add!(34usize, 89usize, 123usize); +payload_add!(34usize, 90usize, 124usize); +payload_add!(34usize, 91usize, 125usize); +payload_add!(34usize, 92usize, 126usize); +payload_add!(34usize, 93usize, 127usize); +payload_add!(34usize, 94usize, 128usize); +payload_add!(34usize, 95usize, 129usize); +payload_add!(34usize, 96usize, 130usize); +payload_add!(34usize, 97usize, 131usize); +payload_add!(34usize, 98usize, 132usize); +payload_add!(34usize, 99usize, 133usize); +payload_add!(34usize, 100usize, 134usize); +payload_add!(34usize, 101usize, 135usize); +payload_add!(34usize, 102usize, 136usize); +payload_add!(34usize, 103usize, 137usize); +payload_add!(34usize, 104usize, 138usize); +payload_add!(34usize, 105usize, 139usize); +payload_add!(34usize, 106usize, 140usize); +payload_add!(34usize, 107usize, 141usize); +payload_add!(34usize, 108usize, 142usize); +payload_add!(34usize, 109usize, 143usize); +payload_add!(34usize, 110usize, 144usize); +payload_add!(34usize, 111usize, 145usize); +payload_add!(34usize, 112usize, 146usize); +payload_add!(34usize, 113usize, 147usize); +payload_add!(34usize, 114usize, 148usize); +payload_add!(34usize, 115usize, 149usize); +payload_add!(34usize, 116usize, 150usize); +payload_add!(34usize, 117usize, 151usize); +payload_add!(34usize, 118usize, 152usize); +payload_add!(34usize, 119usize, 153usize); +payload_add!(34usize, 120usize, 154usize); +payload_add!(34usize, 121usize, 155usize); +payload_add!(34usize, 122usize, 156usize); +payload_add!(34usize, 123usize, 157usize); +payload_add!(34usize, 124usize, 158usize); +payload_add!(34usize, 125usize, 159usize); +payload_add!(34usize, 126usize, 160usize); +payload_add!(34usize, 127usize, 161usize); +payload_add!(34usize, 128usize, 162usize); +payload_add!(35usize, 1usize, 36usize); +payload_add!(35usize, 2usize, 37usize); +payload_add!(35usize, 3usize, 38usize); +payload_add!(35usize, 4usize, 39usize); +payload_add!(35usize, 5usize, 40usize); +payload_add!(35usize, 6usize, 41usize); +payload_add!(35usize, 7usize, 42usize); +payload_add!(35usize, 8usize, 43usize); +payload_add!(35usize, 9usize, 44usize); +payload_add!(35usize, 10usize, 45usize); +payload_add!(35usize, 11usize, 46usize); +payload_add!(35usize, 12usize, 47usize); +payload_add!(35usize, 13usize, 48usize); +payload_add!(35usize, 14usize, 49usize); +payload_add!(35usize, 15usize, 50usize); +payload_add!(35usize, 16usize, 51usize); +payload_add!(35usize, 17usize, 52usize); +payload_add!(35usize, 18usize, 53usize); +payload_add!(35usize, 19usize, 54usize); +payload_add!(35usize, 20usize, 55usize); +payload_add!(35usize, 21usize, 56usize); +payload_add!(35usize, 22usize, 57usize); +payload_add!(35usize, 23usize, 58usize); +payload_add!(35usize, 24usize, 59usize); +payload_add!(35usize, 25usize, 60usize); +payload_add!(35usize, 26usize, 61usize); +payload_add!(35usize, 27usize, 62usize); +payload_add!(35usize, 28usize, 63usize); +payload_add!(35usize, 29usize, 64usize); +payload_add!(35usize, 30usize, 65usize); +payload_add!(35usize, 31usize, 66usize); +payload_add!(35usize, 32usize, 67usize); +payload_add!(35usize, 33usize, 68usize); +payload_add!(35usize, 34usize, 69usize); +payload_add!(35usize, 35usize, 70usize); +payload_add!(35usize, 36usize, 71usize); +payload_add!(35usize, 37usize, 72usize); +payload_add!(35usize, 38usize, 73usize); +payload_add!(35usize, 39usize, 74usize); +payload_add!(35usize, 40usize, 75usize); +payload_add!(35usize, 41usize, 76usize); +payload_add!(35usize, 42usize, 77usize); +payload_add!(35usize, 43usize, 78usize); +payload_add!(35usize, 44usize, 79usize); +payload_add!(35usize, 45usize, 80usize); +payload_add!(35usize, 46usize, 81usize); +payload_add!(35usize, 47usize, 82usize); +payload_add!(35usize, 48usize, 83usize); +payload_add!(35usize, 49usize, 84usize); +payload_add!(35usize, 50usize, 85usize); +payload_add!(35usize, 51usize, 86usize); +payload_add!(35usize, 52usize, 87usize); +payload_add!(35usize, 53usize, 88usize); +payload_add!(35usize, 54usize, 89usize); +payload_add!(35usize, 55usize, 90usize); +payload_add!(35usize, 56usize, 91usize); +payload_add!(35usize, 57usize, 92usize); +payload_add!(35usize, 58usize, 93usize); +payload_add!(35usize, 59usize, 94usize); +payload_add!(35usize, 60usize, 95usize); +payload_add!(35usize, 61usize, 96usize); +payload_add!(35usize, 62usize, 97usize); +payload_add!(35usize, 63usize, 98usize); +payload_add!(35usize, 64usize, 99usize); +payload_add!(35usize, 65usize, 100usize); +payload_add!(35usize, 66usize, 101usize); +payload_add!(35usize, 67usize, 102usize); +payload_add!(35usize, 68usize, 103usize); +payload_add!(35usize, 69usize, 104usize); +payload_add!(35usize, 70usize, 105usize); +payload_add!(35usize, 71usize, 106usize); +payload_add!(35usize, 72usize, 107usize); +payload_add!(35usize, 73usize, 108usize); +payload_add!(35usize, 74usize, 109usize); +payload_add!(35usize, 75usize, 110usize); +payload_add!(35usize, 76usize, 111usize); +payload_add!(35usize, 77usize, 112usize); +payload_add!(35usize, 78usize, 113usize); +payload_add!(35usize, 79usize, 114usize); +payload_add!(35usize, 80usize, 115usize); +payload_add!(35usize, 81usize, 116usize); +payload_add!(35usize, 82usize, 117usize); +payload_add!(35usize, 83usize, 118usize); +payload_add!(35usize, 84usize, 119usize); +payload_add!(35usize, 85usize, 120usize); +payload_add!(35usize, 86usize, 121usize); +payload_add!(35usize, 87usize, 122usize); +payload_add!(35usize, 88usize, 123usize); +payload_add!(35usize, 89usize, 124usize); +payload_add!(35usize, 90usize, 125usize); +payload_add!(35usize, 91usize, 126usize); +payload_add!(35usize, 92usize, 127usize); +payload_add!(35usize, 93usize, 128usize); +payload_add!(35usize, 94usize, 129usize); +payload_add!(35usize, 95usize, 130usize); +payload_add!(35usize, 96usize, 131usize); +payload_add!(35usize, 97usize, 132usize); +payload_add!(35usize, 98usize, 133usize); +payload_add!(35usize, 99usize, 134usize); +payload_add!(35usize, 100usize, 135usize); +payload_add!(35usize, 101usize, 136usize); +payload_add!(35usize, 102usize, 137usize); +payload_add!(35usize, 103usize, 138usize); +payload_add!(35usize, 104usize, 139usize); +payload_add!(35usize, 105usize, 140usize); +payload_add!(35usize, 106usize, 141usize); +payload_add!(35usize, 107usize, 142usize); +payload_add!(35usize, 108usize, 143usize); +payload_add!(35usize, 109usize, 144usize); +payload_add!(35usize, 110usize, 145usize); +payload_add!(35usize, 111usize, 146usize); +payload_add!(35usize, 112usize, 147usize); +payload_add!(35usize, 113usize, 148usize); +payload_add!(35usize, 114usize, 149usize); +payload_add!(35usize, 115usize, 150usize); +payload_add!(35usize, 116usize, 151usize); +payload_add!(35usize, 117usize, 152usize); +payload_add!(35usize, 118usize, 153usize); +payload_add!(35usize, 119usize, 154usize); +payload_add!(35usize, 120usize, 155usize); +payload_add!(35usize, 121usize, 156usize); +payload_add!(35usize, 122usize, 157usize); +payload_add!(35usize, 123usize, 158usize); +payload_add!(35usize, 124usize, 159usize); +payload_add!(35usize, 125usize, 160usize); +payload_add!(35usize, 126usize, 161usize); +payload_add!(35usize, 127usize, 162usize); +payload_add!(35usize, 128usize, 163usize); +payload_add!(36usize, 1usize, 37usize); +payload_add!(36usize, 2usize, 38usize); +payload_add!(36usize, 3usize, 39usize); +payload_add!(36usize, 4usize, 40usize); +payload_add!(36usize, 5usize, 41usize); +payload_add!(36usize, 6usize, 42usize); +payload_add!(36usize, 7usize, 43usize); +payload_add!(36usize, 8usize, 44usize); +payload_add!(36usize, 9usize, 45usize); +payload_add!(36usize, 10usize, 46usize); +payload_add!(36usize, 11usize, 47usize); +payload_add!(36usize, 12usize, 48usize); +payload_add!(36usize, 13usize, 49usize); +payload_add!(36usize, 14usize, 50usize); +payload_add!(36usize, 15usize, 51usize); +payload_add!(36usize, 16usize, 52usize); +payload_add!(36usize, 17usize, 53usize); +payload_add!(36usize, 18usize, 54usize); +payload_add!(36usize, 19usize, 55usize); +payload_add!(36usize, 20usize, 56usize); +payload_add!(36usize, 21usize, 57usize); +payload_add!(36usize, 22usize, 58usize); +payload_add!(36usize, 23usize, 59usize); +payload_add!(36usize, 24usize, 60usize); +payload_add!(36usize, 25usize, 61usize); +payload_add!(36usize, 26usize, 62usize); +payload_add!(36usize, 27usize, 63usize); +payload_add!(36usize, 28usize, 64usize); +payload_add!(36usize, 29usize, 65usize); +payload_add!(36usize, 30usize, 66usize); +payload_add!(36usize, 31usize, 67usize); +payload_add!(36usize, 32usize, 68usize); +payload_add!(36usize, 33usize, 69usize); +payload_add!(36usize, 34usize, 70usize); +payload_add!(36usize, 35usize, 71usize); +payload_add!(36usize, 36usize, 72usize); +payload_add!(36usize, 37usize, 73usize); +payload_add!(36usize, 38usize, 74usize); +payload_add!(36usize, 39usize, 75usize); +payload_add!(36usize, 40usize, 76usize); +payload_add!(36usize, 41usize, 77usize); +payload_add!(36usize, 42usize, 78usize); +payload_add!(36usize, 43usize, 79usize); +payload_add!(36usize, 44usize, 80usize); +payload_add!(36usize, 45usize, 81usize); +payload_add!(36usize, 46usize, 82usize); +payload_add!(36usize, 47usize, 83usize); +payload_add!(36usize, 48usize, 84usize); +payload_add!(36usize, 49usize, 85usize); +payload_add!(36usize, 50usize, 86usize); +payload_add!(36usize, 51usize, 87usize); +payload_add!(36usize, 52usize, 88usize); +payload_add!(36usize, 53usize, 89usize); +payload_add!(36usize, 54usize, 90usize); +payload_add!(36usize, 55usize, 91usize); +payload_add!(36usize, 56usize, 92usize); +payload_add!(36usize, 57usize, 93usize); +payload_add!(36usize, 58usize, 94usize); +payload_add!(36usize, 59usize, 95usize); +payload_add!(36usize, 60usize, 96usize); +payload_add!(36usize, 61usize, 97usize); +payload_add!(36usize, 62usize, 98usize); +payload_add!(36usize, 63usize, 99usize); +payload_add!(36usize, 64usize, 100usize); +payload_add!(36usize, 65usize, 101usize); +payload_add!(36usize, 66usize, 102usize); +payload_add!(36usize, 67usize, 103usize); +payload_add!(36usize, 68usize, 104usize); +payload_add!(36usize, 69usize, 105usize); +payload_add!(36usize, 70usize, 106usize); +payload_add!(36usize, 71usize, 107usize); +payload_add!(36usize, 72usize, 108usize); +payload_add!(36usize, 73usize, 109usize); +payload_add!(36usize, 74usize, 110usize); +payload_add!(36usize, 75usize, 111usize); +payload_add!(36usize, 76usize, 112usize); +payload_add!(36usize, 77usize, 113usize); +payload_add!(36usize, 78usize, 114usize); +payload_add!(36usize, 79usize, 115usize); +payload_add!(36usize, 80usize, 116usize); +payload_add!(36usize, 81usize, 117usize); +payload_add!(36usize, 82usize, 118usize); +payload_add!(36usize, 83usize, 119usize); +payload_add!(36usize, 84usize, 120usize); +payload_add!(36usize, 85usize, 121usize); +payload_add!(36usize, 86usize, 122usize); +payload_add!(36usize, 87usize, 123usize); +payload_add!(36usize, 88usize, 124usize); +payload_add!(36usize, 89usize, 125usize); +payload_add!(36usize, 90usize, 126usize); +payload_add!(36usize, 91usize, 127usize); +payload_add!(36usize, 92usize, 128usize); +payload_add!(36usize, 93usize, 129usize); +payload_add!(36usize, 94usize, 130usize); +payload_add!(36usize, 95usize, 131usize); +payload_add!(36usize, 96usize, 132usize); +payload_add!(36usize, 97usize, 133usize); +payload_add!(36usize, 98usize, 134usize); +payload_add!(36usize, 99usize, 135usize); +payload_add!(36usize, 100usize, 136usize); +payload_add!(36usize, 101usize, 137usize); +payload_add!(36usize, 102usize, 138usize); +payload_add!(36usize, 103usize, 139usize); +payload_add!(36usize, 104usize, 140usize); +payload_add!(36usize, 105usize, 141usize); +payload_add!(36usize, 106usize, 142usize); +payload_add!(36usize, 107usize, 143usize); +payload_add!(36usize, 108usize, 144usize); +payload_add!(36usize, 109usize, 145usize); +payload_add!(36usize, 110usize, 146usize); +payload_add!(36usize, 111usize, 147usize); +payload_add!(36usize, 112usize, 148usize); +payload_add!(36usize, 113usize, 149usize); +payload_add!(36usize, 114usize, 150usize); +payload_add!(36usize, 115usize, 151usize); +payload_add!(36usize, 116usize, 152usize); +payload_add!(36usize, 117usize, 153usize); +payload_add!(36usize, 118usize, 154usize); +payload_add!(36usize, 119usize, 155usize); +payload_add!(36usize, 120usize, 156usize); +payload_add!(36usize, 121usize, 157usize); +payload_add!(36usize, 122usize, 158usize); +payload_add!(36usize, 123usize, 159usize); +payload_add!(36usize, 124usize, 160usize); +payload_add!(36usize, 125usize, 161usize); +payload_add!(36usize, 126usize, 162usize); +payload_add!(36usize, 127usize, 163usize); +payload_add!(36usize, 128usize, 164usize); +payload_add!(37usize, 1usize, 38usize); +payload_add!(37usize, 2usize, 39usize); +payload_add!(37usize, 3usize, 40usize); +payload_add!(37usize, 4usize, 41usize); +payload_add!(37usize, 5usize, 42usize); +payload_add!(37usize, 6usize, 43usize); +payload_add!(37usize, 7usize, 44usize); +payload_add!(37usize, 8usize, 45usize); +payload_add!(37usize, 9usize, 46usize); +payload_add!(37usize, 10usize, 47usize); +payload_add!(37usize, 11usize, 48usize); +payload_add!(37usize, 12usize, 49usize); +payload_add!(37usize, 13usize, 50usize); +payload_add!(37usize, 14usize, 51usize); +payload_add!(37usize, 15usize, 52usize); +payload_add!(37usize, 16usize, 53usize); +payload_add!(37usize, 17usize, 54usize); +payload_add!(37usize, 18usize, 55usize); +payload_add!(37usize, 19usize, 56usize); +payload_add!(37usize, 20usize, 57usize); +payload_add!(37usize, 21usize, 58usize); +payload_add!(37usize, 22usize, 59usize); +payload_add!(37usize, 23usize, 60usize); +payload_add!(37usize, 24usize, 61usize); +payload_add!(37usize, 25usize, 62usize); +payload_add!(37usize, 26usize, 63usize); +payload_add!(37usize, 27usize, 64usize); +payload_add!(37usize, 28usize, 65usize); +payload_add!(37usize, 29usize, 66usize); +payload_add!(37usize, 30usize, 67usize); +payload_add!(37usize, 31usize, 68usize); +payload_add!(37usize, 32usize, 69usize); +payload_add!(37usize, 33usize, 70usize); +payload_add!(37usize, 34usize, 71usize); +payload_add!(37usize, 35usize, 72usize); +payload_add!(37usize, 36usize, 73usize); +payload_add!(37usize, 37usize, 74usize); +payload_add!(37usize, 38usize, 75usize); +payload_add!(37usize, 39usize, 76usize); +payload_add!(37usize, 40usize, 77usize); +payload_add!(37usize, 41usize, 78usize); +payload_add!(37usize, 42usize, 79usize); +payload_add!(37usize, 43usize, 80usize); +payload_add!(37usize, 44usize, 81usize); +payload_add!(37usize, 45usize, 82usize); +payload_add!(37usize, 46usize, 83usize); +payload_add!(37usize, 47usize, 84usize); +payload_add!(37usize, 48usize, 85usize); +payload_add!(37usize, 49usize, 86usize); +payload_add!(37usize, 50usize, 87usize); +payload_add!(37usize, 51usize, 88usize); +payload_add!(37usize, 52usize, 89usize); +payload_add!(37usize, 53usize, 90usize); +payload_add!(37usize, 54usize, 91usize); +payload_add!(37usize, 55usize, 92usize); +payload_add!(37usize, 56usize, 93usize); +payload_add!(37usize, 57usize, 94usize); +payload_add!(37usize, 58usize, 95usize); +payload_add!(37usize, 59usize, 96usize); +payload_add!(37usize, 60usize, 97usize); +payload_add!(37usize, 61usize, 98usize); +payload_add!(37usize, 62usize, 99usize); +payload_add!(37usize, 63usize, 100usize); +payload_add!(37usize, 64usize, 101usize); +payload_add!(37usize, 65usize, 102usize); +payload_add!(37usize, 66usize, 103usize); +payload_add!(37usize, 67usize, 104usize); +payload_add!(37usize, 68usize, 105usize); +payload_add!(37usize, 69usize, 106usize); +payload_add!(37usize, 70usize, 107usize); +payload_add!(37usize, 71usize, 108usize); +payload_add!(37usize, 72usize, 109usize); +payload_add!(37usize, 73usize, 110usize); +payload_add!(37usize, 74usize, 111usize); +payload_add!(37usize, 75usize, 112usize); +payload_add!(37usize, 76usize, 113usize); +payload_add!(37usize, 77usize, 114usize); +payload_add!(37usize, 78usize, 115usize); +payload_add!(37usize, 79usize, 116usize); +payload_add!(37usize, 80usize, 117usize); +payload_add!(37usize, 81usize, 118usize); +payload_add!(37usize, 82usize, 119usize); +payload_add!(37usize, 83usize, 120usize); +payload_add!(37usize, 84usize, 121usize); +payload_add!(37usize, 85usize, 122usize); +payload_add!(37usize, 86usize, 123usize); +payload_add!(37usize, 87usize, 124usize); +payload_add!(37usize, 88usize, 125usize); +payload_add!(37usize, 89usize, 126usize); +payload_add!(37usize, 90usize, 127usize); +payload_add!(37usize, 91usize, 128usize); +payload_add!(37usize, 92usize, 129usize); +payload_add!(37usize, 93usize, 130usize); +payload_add!(37usize, 94usize, 131usize); +payload_add!(37usize, 95usize, 132usize); +payload_add!(37usize, 96usize, 133usize); +payload_add!(37usize, 97usize, 134usize); +payload_add!(37usize, 98usize, 135usize); +payload_add!(37usize, 99usize, 136usize); +payload_add!(37usize, 100usize, 137usize); +payload_add!(37usize, 101usize, 138usize); +payload_add!(37usize, 102usize, 139usize); +payload_add!(37usize, 103usize, 140usize); +payload_add!(37usize, 104usize, 141usize); +payload_add!(37usize, 105usize, 142usize); +payload_add!(37usize, 106usize, 143usize); +payload_add!(37usize, 107usize, 144usize); +payload_add!(37usize, 108usize, 145usize); +payload_add!(37usize, 109usize, 146usize); +payload_add!(37usize, 110usize, 147usize); +payload_add!(37usize, 111usize, 148usize); +payload_add!(37usize, 112usize, 149usize); +payload_add!(37usize, 113usize, 150usize); +payload_add!(37usize, 114usize, 151usize); +payload_add!(37usize, 115usize, 152usize); +payload_add!(37usize, 116usize, 153usize); +payload_add!(37usize, 117usize, 154usize); +payload_add!(37usize, 118usize, 155usize); +payload_add!(37usize, 119usize, 156usize); +payload_add!(37usize, 120usize, 157usize); +payload_add!(37usize, 121usize, 158usize); +payload_add!(37usize, 122usize, 159usize); +payload_add!(37usize, 123usize, 160usize); +payload_add!(37usize, 124usize, 161usize); +payload_add!(37usize, 125usize, 162usize); +payload_add!(37usize, 126usize, 163usize); +payload_add!(37usize, 127usize, 164usize); +payload_add!(37usize, 128usize, 165usize); +payload_add!(38usize, 1usize, 39usize); +payload_add!(38usize, 2usize, 40usize); +payload_add!(38usize, 3usize, 41usize); +payload_add!(38usize, 4usize, 42usize); +payload_add!(38usize, 5usize, 43usize); +payload_add!(38usize, 6usize, 44usize); +payload_add!(38usize, 7usize, 45usize); +payload_add!(38usize, 8usize, 46usize); +payload_add!(38usize, 9usize, 47usize); +payload_add!(38usize, 10usize, 48usize); +payload_add!(38usize, 11usize, 49usize); +payload_add!(38usize, 12usize, 50usize); +payload_add!(38usize, 13usize, 51usize); +payload_add!(38usize, 14usize, 52usize); +payload_add!(38usize, 15usize, 53usize); +payload_add!(38usize, 16usize, 54usize); +payload_add!(38usize, 17usize, 55usize); +payload_add!(38usize, 18usize, 56usize); +payload_add!(38usize, 19usize, 57usize); +payload_add!(38usize, 20usize, 58usize); +payload_add!(38usize, 21usize, 59usize); +payload_add!(38usize, 22usize, 60usize); +payload_add!(38usize, 23usize, 61usize); +payload_add!(38usize, 24usize, 62usize); +payload_add!(38usize, 25usize, 63usize); +payload_add!(38usize, 26usize, 64usize); +payload_add!(38usize, 27usize, 65usize); +payload_add!(38usize, 28usize, 66usize); +payload_add!(38usize, 29usize, 67usize); +payload_add!(38usize, 30usize, 68usize); +payload_add!(38usize, 31usize, 69usize); +payload_add!(38usize, 32usize, 70usize); +payload_add!(38usize, 33usize, 71usize); +payload_add!(38usize, 34usize, 72usize); +payload_add!(38usize, 35usize, 73usize); +payload_add!(38usize, 36usize, 74usize); +payload_add!(38usize, 37usize, 75usize); +payload_add!(38usize, 38usize, 76usize); +payload_add!(38usize, 39usize, 77usize); +payload_add!(38usize, 40usize, 78usize); +payload_add!(38usize, 41usize, 79usize); +payload_add!(38usize, 42usize, 80usize); +payload_add!(38usize, 43usize, 81usize); +payload_add!(38usize, 44usize, 82usize); +payload_add!(38usize, 45usize, 83usize); +payload_add!(38usize, 46usize, 84usize); +payload_add!(38usize, 47usize, 85usize); +payload_add!(38usize, 48usize, 86usize); +payload_add!(38usize, 49usize, 87usize); +payload_add!(38usize, 50usize, 88usize); +payload_add!(38usize, 51usize, 89usize); +payload_add!(38usize, 52usize, 90usize); +payload_add!(38usize, 53usize, 91usize); +payload_add!(38usize, 54usize, 92usize); +payload_add!(38usize, 55usize, 93usize); +payload_add!(38usize, 56usize, 94usize); +payload_add!(38usize, 57usize, 95usize); +payload_add!(38usize, 58usize, 96usize); +payload_add!(38usize, 59usize, 97usize); +payload_add!(38usize, 60usize, 98usize); +payload_add!(38usize, 61usize, 99usize); +payload_add!(38usize, 62usize, 100usize); +payload_add!(38usize, 63usize, 101usize); +payload_add!(38usize, 64usize, 102usize); +payload_add!(38usize, 65usize, 103usize); +payload_add!(38usize, 66usize, 104usize); +payload_add!(38usize, 67usize, 105usize); +payload_add!(38usize, 68usize, 106usize); +payload_add!(38usize, 69usize, 107usize); +payload_add!(38usize, 70usize, 108usize); +payload_add!(38usize, 71usize, 109usize); +payload_add!(38usize, 72usize, 110usize); +payload_add!(38usize, 73usize, 111usize); +payload_add!(38usize, 74usize, 112usize); +payload_add!(38usize, 75usize, 113usize); +payload_add!(38usize, 76usize, 114usize); +payload_add!(38usize, 77usize, 115usize); +payload_add!(38usize, 78usize, 116usize); +payload_add!(38usize, 79usize, 117usize); +payload_add!(38usize, 80usize, 118usize); +payload_add!(38usize, 81usize, 119usize); +payload_add!(38usize, 82usize, 120usize); +payload_add!(38usize, 83usize, 121usize); +payload_add!(38usize, 84usize, 122usize); +payload_add!(38usize, 85usize, 123usize); +payload_add!(38usize, 86usize, 124usize); +payload_add!(38usize, 87usize, 125usize); +payload_add!(38usize, 88usize, 126usize); +payload_add!(38usize, 89usize, 127usize); +payload_add!(38usize, 90usize, 128usize); +payload_add!(38usize, 91usize, 129usize); +payload_add!(38usize, 92usize, 130usize); +payload_add!(38usize, 93usize, 131usize); +payload_add!(38usize, 94usize, 132usize); +payload_add!(38usize, 95usize, 133usize); +payload_add!(38usize, 96usize, 134usize); +payload_add!(38usize, 97usize, 135usize); +payload_add!(38usize, 98usize, 136usize); +payload_add!(38usize, 99usize, 137usize); +payload_add!(38usize, 100usize, 138usize); +payload_add!(38usize, 101usize, 139usize); +payload_add!(38usize, 102usize, 140usize); +payload_add!(38usize, 103usize, 141usize); +payload_add!(38usize, 104usize, 142usize); +payload_add!(38usize, 105usize, 143usize); +payload_add!(38usize, 106usize, 144usize); +payload_add!(38usize, 107usize, 145usize); +payload_add!(38usize, 108usize, 146usize); +payload_add!(38usize, 109usize, 147usize); +payload_add!(38usize, 110usize, 148usize); +payload_add!(38usize, 111usize, 149usize); +payload_add!(38usize, 112usize, 150usize); +payload_add!(38usize, 113usize, 151usize); +payload_add!(38usize, 114usize, 152usize); +payload_add!(38usize, 115usize, 153usize); +payload_add!(38usize, 116usize, 154usize); +payload_add!(38usize, 117usize, 155usize); +payload_add!(38usize, 118usize, 156usize); +payload_add!(38usize, 119usize, 157usize); +payload_add!(38usize, 120usize, 158usize); +payload_add!(38usize, 121usize, 159usize); +payload_add!(38usize, 122usize, 160usize); +payload_add!(38usize, 123usize, 161usize); +payload_add!(38usize, 124usize, 162usize); +payload_add!(38usize, 125usize, 163usize); +payload_add!(38usize, 126usize, 164usize); +payload_add!(38usize, 127usize, 165usize); +payload_add!(38usize, 128usize, 166usize); +payload_add!(39usize, 1usize, 40usize); +payload_add!(39usize, 2usize, 41usize); +payload_add!(39usize, 3usize, 42usize); +payload_add!(39usize, 4usize, 43usize); +payload_add!(39usize, 5usize, 44usize); +payload_add!(39usize, 6usize, 45usize); +payload_add!(39usize, 7usize, 46usize); +payload_add!(39usize, 8usize, 47usize); +payload_add!(39usize, 9usize, 48usize); +payload_add!(39usize, 10usize, 49usize); +payload_add!(39usize, 11usize, 50usize); +payload_add!(39usize, 12usize, 51usize); +payload_add!(39usize, 13usize, 52usize); +payload_add!(39usize, 14usize, 53usize); +payload_add!(39usize, 15usize, 54usize); +payload_add!(39usize, 16usize, 55usize); +payload_add!(39usize, 17usize, 56usize); +payload_add!(39usize, 18usize, 57usize); +payload_add!(39usize, 19usize, 58usize); +payload_add!(39usize, 20usize, 59usize); +payload_add!(39usize, 21usize, 60usize); +payload_add!(39usize, 22usize, 61usize); +payload_add!(39usize, 23usize, 62usize); +payload_add!(39usize, 24usize, 63usize); +payload_add!(39usize, 25usize, 64usize); +payload_add!(39usize, 26usize, 65usize); +payload_add!(39usize, 27usize, 66usize); +payload_add!(39usize, 28usize, 67usize); +payload_add!(39usize, 29usize, 68usize); +payload_add!(39usize, 30usize, 69usize); +payload_add!(39usize, 31usize, 70usize); +payload_add!(39usize, 32usize, 71usize); +payload_add!(39usize, 33usize, 72usize); +payload_add!(39usize, 34usize, 73usize); +payload_add!(39usize, 35usize, 74usize); +payload_add!(39usize, 36usize, 75usize); +payload_add!(39usize, 37usize, 76usize); +payload_add!(39usize, 38usize, 77usize); +payload_add!(39usize, 39usize, 78usize); +payload_add!(39usize, 40usize, 79usize); +payload_add!(39usize, 41usize, 80usize); +payload_add!(39usize, 42usize, 81usize); +payload_add!(39usize, 43usize, 82usize); +payload_add!(39usize, 44usize, 83usize); +payload_add!(39usize, 45usize, 84usize); +payload_add!(39usize, 46usize, 85usize); +payload_add!(39usize, 47usize, 86usize); +payload_add!(39usize, 48usize, 87usize); +payload_add!(39usize, 49usize, 88usize); +payload_add!(39usize, 50usize, 89usize); +payload_add!(39usize, 51usize, 90usize); +payload_add!(39usize, 52usize, 91usize); +payload_add!(39usize, 53usize, 92usize); +payload_add!(39usize, 54usize, 93usize); +payload_add!(39usize, 55usize, 94usize); +payload_add!(39usize, 56usize, 95usize); +payload_add!(39usize, 57usize, 96usize); +payload_add!(39usize, 58usize, 97usize); +payload_add!(39usize, 59usize, 98usize); +payload_add!(39usize, 60usize, 99usize); +payload_add!(39usize, 61usize, 100usize); +payload_add!(39usize, 62usize, 101usize); +payload_add!(39usize, 63usize, 102usize); +payload_add!(39usize, 64usize, 103usize); +payload_add!(39usize, 65usize, 104usize); +payload_add!(39usize, 66usize, 105usize); +payload_add!(39usize, 67usize, 106usize); +payload_add!(39usize, 68usize, 107usize); +payload_add!(39usize, 69usize, 108usize); +payload_add!(39usize, 70usize, 109usize); +payload_add!(39usize, 71usize, 110usize); +payload_add!(39usize, 72usize, 111usize); +payload_add!(39usize, 73usize, 112usize); +payload_add!(39usize, 74usize, 113usize); +payload_add!(39usize, 75usize, 114usize); +payload_add!(39usize, 76usize, 115usize); +payload_add!(39usize, 77usize, 116usize); +payload_add!(39usize, 78usize, 117usize); +payload_add!(39usize, 79usize, 118usize); +payload_add!(39usize, 80usize, 119usize); +payload_add!(39usize, 81usize, 120usize); +payload_add!(39usize, 82usize, 121usize); +payload_add!(39usize, 83usize, 122usize); +payload_add!(39usize, 84usize, 123usize); +payload_add!(39usize, 85usize, 124usize); +payload_add!(39usize, 86usize, 125usize); +payload_add!(39usize, 87usize, 126usize); +payload_add!(39usize, 88usize, 127usize); +payload_add!(39usize, 89usize, 128usize); +payload_add!(39usize, 90usize, 129usize); +payload_add!(39usize, 91usize, 130usize); +payload_add!(39usize, 92usize, 131usize); +payload_add!(39usize, 93usize, 132usize); +payload_add!(39usize, 94usize, 133usize); +payload_add!(39usize, 95usize, 134usize); +payload_add!(39usize, 96usize, 135usize); +payload_add!(39usize, 97usize, 136usize); +payload_add!(39usize, 98usize, 137usize); +payload_add!(39usize, 99usize, 138usize); +payload_add!(39usize, 100usize, 139usize); +payload_add!(39usize, 101usize, 140usize); +payload_add!(39usize, 102usize, 141usize); +payload_add!(39usize, 103usize, 142usize); +payload_add!(39usize, 104usize, 143usize); +payload_add!(39usize, 105usize, 144usize); +payload_add!(39usize, 106usize, 145usize); +payload_add!(39usize, 107usize, 146usize); +payload_add!(39usize, 108usize, 147usize); +payload_add!(39usize, 109usize, 148usize); +payload_add!(39usize, 110usize, 149usize); +payload_add!(39usize, 111usize, 150usize); +payload_add!(39usize, 112usize, 151usize); +payload_add!(39usize, 113usize, 152usize); +payload_add!(39usize, 114usize, 153usize); +payload_add!(39usize, 115usize, 154usize); +payload_add!(39usize, 116usize, 155usize); +payload_add!(39usize, 117usize, 156usize); +payload_add!(39usize, 118usize, 157usize); +payload_add!(39usize, 119usize, 158usize); +payload_add!(39usize, 120usize, 159usize); +payload_add!(39usize, 121usize, 160usize); +payload_add!(39usize, 122usize, 161usize); +payload_add!(39usize, 123usize, 162usize); +payload_add!(39usize, 124usize, 163usize); +payload_add!(39usize, 125usize, 164usize); +payload_add!(39usize, 126usize, 165usize); +payload_add!(39usize, 127usize, 166usize); +payload_add!(39usize, 128usize, 167usize); +payload_add!(40usize, 1usize, 41usize); +payload_add!(40usize, 2usize, 42usize); +payload_add!(40usize, 3usize, 43usize); +payload_add!(40usize, 4usize, 44usize); +payload_add!(40usize, 5usize, 45usize); +payload_add!(40usize, 6usize, 46usize); +payload_add!(40usize, 7usize, 47usize); +payload_add!(40usize, 8usize, 48usize); +payload_add!(40usize, 9usize, 49usize); +payload_add!(40usize, 10usize, 50usize); +payload_add!(40usize, 11usize, 51usize); +payload_add!(40usize, 12usize, 52usize); +payload_add!(40usize, 13usize, 53usize); +payload_add!(40usize, 14usize, 54usize); +payload_add!(40usize, 15usize, 55usize); +payload_add!(40usize, 16usize, 56usize); +payload_add!(40usize, 17usize, 57usize); +payload_add!(40usize, 18usize, 58usize); +payload_add!(40usize, 19usize, 59usize); +payload_add!(40usize, 20usize, 60usize); +payload_add!(40usize, 21usize, 61usize); +payload_add!(40usize, 22usize, 62usize); +payload_add!(40usize, 23usize, 63usize); +payload_add!(40usize, 24usize, 64usize); +payload_add!(40usize, 25usize, 65usize); +payload_add!(40usize, 26usize, 66usize); +payload_add!(40usize, 27usize, 67usize); +payload_add!(40usize, 28usize, 68usize); +payload_add!(40usize, 29usize, 69usize); +payload_add!(40usize, 30usize, 70usize); +payload_add!(40usize, 31usize, 71usize); +payload_add!(40usize, 32usize, 72usize); +payload_add!(40usize, 33usize, 73usize); +payload_add!(40usize, 34usize, 74usize); +payload_add!(40usize, 35usize, 75usize); +payload_add!(40usize, 36usize, 76usize); +payload_add!(40usize, 37usize, 77usize); +payload_add!(40usize, 38usize, 78usize); +payload_add!(40usize, 39usize, 79usize); +payload_add!(40usize, 40usize, 80usize); +payload_add!(40usize, 41usize, 81usize); +payload_add!(40usize, 42usize, 82usize); +payload_add!(40usize, 43usize, 83usize); +payload_add!(40usize, 44usize, 84usize); +payload_add!(40usize, 45usize, 85usize); +payload_add!(40usize, 46usize, 86usize); +payload_add!(40usize, 47usize, 87usize); +payload_add!(40usize, 48usize, 88usize); +payload_add!(40usize, 49usize, 89usize); +payload_add!(40usize, 50usize, 90usize); +payload_add!(40usize, 51usize, 91usize); +payload_add!(40usize, 52usize, 92usize); +payload_add!(40usize, 53usize, 93usize); +payload_add!(40usize, 54usize, 94usize); +payload_add!(40usize, 55usize, 95usize); +payload_add!(40usize, 56usize, 96usize); +payload_add!(40usize, 57usize, 97usize); +payload_add!(40usize, 58usize, 98usize); +payload_add!(40usize, 59usize, 99usize); +payload_add!(40usize, 60usize, 100usize); +payload_add!(40usize, 61usize, 101usize); +payload_add!(40usize, 62usize, 102usize); +payload_add!(40usize, 63usize, 103usize); +payload_add!(40usize, 64usize, 104usize); +payload_add!(40usize, 65usize, 105usize); +payload_add!(40usize, 66usize, 106usize); +payload_add!(40usize, 67usize, 107usize); +payload_add!(40usize, 68usize, 108usize); +payload_add!(40usize, 69usize, 109usize); +payload_add!(40usize, 70usize, 110usize); +payload_add!(40usize, 71usize, 111usize); +payload_add!(40usize, 72usize, 112usize); +payload_add!(40usize, 73usize, 113usize); +payload_add!(40usize, 74usize, 114usize); +payload_add!(40usize, 75usize, 115usize); +payload_add!(40usize, 76usize, 116usize); +payload_add!(40usize, 77usize, 117usize); +payload_add!(40usize, 78usize, 118usize); +payload_add!(40usize, 79usize, 119usize); +payload_add!(40usize, 80usize, 120usize); +payload_add!(40usize, 81usize, 121usize); +payload_add!(40usize, 82usize, 122usize); +payload_add!(40usize, 83usize, 123usize); +payload_add!(40usize, 84usize, 124usize); +payload_add!(40usize, 85usize, 125usize); +payload_add!(40usize, 86usize, 126usize); +payload_add!(40usize, 87usize, 127usize); +payload_add!(40usize, 88usize, 128usize); +payload_add!(40usize, 89usize, 129usize); +payload_add!(40usize, 90usize, 130usize); +payload_add!(40usize, 91usize, 131usize); +payload_add!(40usize, 92usize, 132usize); +payload_add!(40usize, 93usize, 133usize); +payload_add!(40usize, 94usize, 134usize); +payload_add!(40usize, 95usize, 135usize); +payload_add!(40usize, 96usize, 136usize); +payload_add!(40usize, 97usize, 137usize); +payload_add!(40usize, 98usize, 138usize); +payload_add!(40usize, 99usize, 139usize); +payload_add!(40usize, 100usize, 140usize); +payload_add!(40usize, 101usize, 141usize); +payload_add!(40usize, 102usize, 142usize); +payload_add!(40usize, 103usize, 143usize); +payload_add!(40usize, 104usize, 144usize); +payload_add!(40usize, 105usize, 145usize); +payload_add!(40usize, 106usize, 146usize); +payload_add!(40usize, 107usize, 147usize); +payload_add!(40usize, 108usize, 148usize); +payload_add!(40usize, 109usize, 149usize); +payload_add!(40usize, 110usize, 150usize); +payload_add!(40usize, 111usize, 151usize); +payload_add!(40usize, 112usize, 152usize); +payload_add!(40usize, 113usize, 153usize); +payload_add!(40usize, 114usize, 154usize); +payload_add!(40usize, 115usize, 155usize); +payload_add!(40usize, 116usize, 156usize); +payload_add!(40usize, 117usize, 157usize); +payload_add!(40usize, 118usize, 158usize); +payload_add!(40usize, 119usize, 159usize); +payload_add!(40usize, 120usize, 160usize); +payload_add!(40usize, 121usize, 161usize); +payload_add!(40usize, 122usize, 162usize); +payload_add!(40usize, 123usize, 163usize); +payload_add!(40usize, 124usize, 164usize); +payload_add!(40usize, 125usize, 165usize); +payload_add!(40usize, 126usize, 166usize); +payload_add!(40usize, 127usize, 167usize); +payload_add!(40usize, 128usize, 168usize); +payload_add!(41usize, 1usize, 42usize); +payload_add!(41usize, 2usize, 43usize); +payload_add!(41usize, 3usize, 44usize); +payload_add!(41usize, 4usize, 45usize); +payload_add!(41usize, 5usize, 46usize); +payload_add!(41usize, 6usize, 47usize); +payload_add!(41usize, 7usize, 48usize); +payload_add!(41usize, 8usize, 49usize); +payload_add!(41usize, 9usize, 50usize); +payload_add!(41usize, 10usize, 51usize); +payload_add!(41usize, 11usize, 52usize); +payload_add!(41usize, 12usize, 53usize); +payload_add!(41usize, 13usize, 54usize); +payload_add!(41usize, 14usize, 55usize); +payload_add!(41usize, 15usize, 56usize); +payload_add!(41usize, 16usize, 57usize); +payload_add!(41usize, 17usize, 58usize); +payload_add!(41usize, 18usize, 59usize); +payload_add!(41usize, 19usize, 60usize); +payload_add!(41usize, 20usize, 61usize); +payload_add!(41usize, 21usize, 62usize); +payload_add!(41usize, 22usize, 63usize); +payload_add!(41usize, 23usize, 64usize); +payload_add!(41usize, 24usize, 65usize); +payload_add!(41usize, 25usize, 66usize); +payload_add!(41usize, 26usize, 67usize); +payload_add!(41usize, 27usize, 68usize); +payload_add!(41usize, 28usize, 69usize); +payload_add!(41usize, 29usize, 70usize); +payload_add!(41usize, 30usize, 71usize); +payload_add!(41usize, 31usize, 72usize); +payload_add!(41usize, 32usize, 73usize); +payload_add!(41usize, 33usize, 74usize); +payload_add!(41usize, 34usize, 75usize); +payload_add!(41usize, 35usize, 76usize); +payload_add!(41usize, 36usize, 77usize); +payload_add!(41usize, 37usize, 78usize); +payload_add!(41usize, 38usize, 79usize); +payload_add!(41usize, 39usize, 80usize); +payload_add!(41usize, 40usize, 81usize); +payload_add!(41usize, 41usize, 82usize); +payload_add!(41usize, 42usize, 83usize); +payload_add!(41usize, 43usize, 84usize); +payload_add!(41usize, 44usize, 85usize); +payload_add!(41usize, 45usize, 86usize); +payload_add!(41usize, 46usize, 87usize); +payload_add!(41usize, 47usize, 88usize); +payload_add!(41usize, 48usize, 89usize); +payload_add!(41usize, 49usize, 90usize); +payload_add!(41usize, 50usize, 91usize); +payload_add!(41usize, 51usize, 92usize); +payload_add!(41usize, 52usize, 93usize); +payload_add!(41usize, 53usize, 94usize); +payload_add!(41usize, 54usize, 95usize); +payload_add!(41usize, 55usize, 96usize); +payload_add!(41usize, 56usize, 97usize); +payload_add!(41usize, 57usize, 98usize); +payload_add!(41usize, 58usize, 99usize); +payload_add!(41usize, 59usize, 100usize); +payload_add!(41usize, 60usize, 101usize); +payload_add!(41usize, 61usize, 102usize); +payload_add!(41usize, 62usize, 103usize); +payload_add!(41usize, 63usize, 104usize); +payload_add!(41usize, 64usize, 105usize); +payload_add!(41usize, 65usize, 106usize); +payload_add!(41usize, 66usize, 107usize); +payload_add!(41usize, 67usize, 108usize); +payload_add!(41usize, 68usize, 109usize); +payload_add!(41usize, 69usize, 110usize); +payload_add!(41usize, 70usize, 111usize); +payload_add!(41usize, 71usize, 112usize); +payload_add!(41usize, 72usize, 113usize); +payload_add!(41usize, 73usize, 114usize); +payload_add!(41usize, 74usize, 115usize); +payload_add!(41usize, 75usize, 116usize); +payload_add!(41usize, 76usize, 117usize); +payload_add!(41usize, 77usize, 118usize); +payload_add!(41usize, 78usize, 119usize); +payload_add!(41usize, 79usize, 120usize); +payload_add!(41usize, 80usize, 121usize); +payload_add!(41usize, 81usize, 122usize); +payload_add!(41usize, 82usize, 123usize); +payload_add!(41usize, 83usize, 124usize); +payload_add!(41usize, 84usize, 125usize); +payload_add!(41usize, 85usize, 126usize); +payload_add!(41usize, 86usize, 127usize); +payload_add!(41usize, 87usize, 128usize); +payload_add!(41usize, 88usize, 129usize); +payload_add!(41usize, 89usize, 130usize); +payload_add!(41usize, 90usize, 131usize); +payload_add!(41usize, 91usize, 132usize); +payload_add!(41usize, 92usize, 133usize); +payload_add!(41usize, 93usize, 134usize); +payload_add!(41usize, 94usize, 135usize); +payload_add!(41usize, 95usize, 136usize); +payload_add!(41usize, 96usize, 137usize); +payload_add!(41usize, 97usize, 138usize); +payload_add!(41usize, 98usize, 139usize); +payload_add!(41usize, 99usize, 140usize); +payload_add!(41usize, 100usize, 141usize); +payload_add!(41usize, 101usize, 142usize); +payload_add!(41usize, 102usize, 143usize); +payload_add!(41usize, 103usize, 144usize); +payload_add!(41usize, 104usize, 145usize); +payload_add!(41usize, 105usize, 146usize); +payload_add!(41usize, 106usize, 147usize); +payload_add!(41usize, 107usize, 148usize); +payload_add!(41usize, 108usize, 149usize); +payload_add!(41usize, 109usize, 150usize); +payload_add!(41usize, 110usize, 151usize); +payload_add!(41usize, 111usize, 152usize); +payload_add!(41usize, 112usize, 153usize); +payload_add!(41usize, 113usize, 154usize); +payload_add!(41usize, 114usize, 155usize); +payload_add!(41usize, 115usize, 156usize); +payload_add!(41usize, 116usize, 157usize); +payload_add!(41usize, 117usize, 158usize); +payload_add!(41usize, 118usize, 159usize); +payload_add!(41usize, 119usize, 160usize); +payload_add!(41usize, 120usize, 161usize); +payload_add!(41usize, 121usize, 162usize); +payload_add!(41usize, 122usize, 163usize); +payload_add!(41usize, 123usize, 164usize); +payload_add!(41usize, 124usize, 165usize); +payload_add!(41usize, 125usize, 166usize); +payload_add!(41usize, 126usize, 167usize); +payload_add!(41usize, 127usize, 168usize); +payload_add!(41usize, 128usize, 169usize); +payload_add!(42usize, 1usize, 43usize); +payload_add!(42usize, 2usize, 44usize); +payload_add!(42usize, 3usize, 45usize); +payload_add!(42usize, 4usize, 46usize); +payload_add!(42usize, 5usize, 47usize); +payload_add!(42usize, 6usize, 48usize); +payload_add!(42usize, 7usize, 49usize); +payload_add!(42usize, 8usize, 50usize); +payload_add!(42usize, 9usize, 51usize); +payload_add!(42usize, 10usize, 52usize); +payload_add!(42usize, 11usize, 53usize); +payload_add!(42usize, 12usize, 54usize); +payload_add!(42usize, 13usize, 55usize); +payload_add!(42usize, 14usize, 56usize); +payload_add!(42usize, 15usize, 57usize); +payload_add!(42usize, 16usize, 58usize); +payload_add!(42usize, 17usize, 59usize); +payload_add!(42usize, 18usize, 60usize); +payload_add!(42usize, 19usize, 61usize); +payload_add!(42usize, 20usize, 62usize); +payload_add!(42usize, 21usize, 63usize); +payload_add!(42usize, 22usize, 64usize); +payload_add!(42usize, 23usize, 65usize); +payload_add!(42usize, 24usize, 66usize); +payload_add!(42usize, 25usize, 67usize); +payload_add!(42usize, 26usize, 68usize); +payload_add!(42usize, 27usize, 69usize); +payload_add!(42usize, 28usize, 70usize); +payload_add!(42usize, 29usize, 71usize); +payload_add!(42usize, 30usize, 72usize); +payload_add!(42usize, 31usize, 73usize); +payload_add!(42usize, 32usize, 74usize); +payload_add!(42usize, 33usize, 75usize); +payload_add!(42usize, 34usize, 76usize); +payload_add!(42usize, 35usize, 77usize); +payload_add!(42usize, 36usize, 78usize); +payload_add!(42usize, 37usize, 79usize); +payload_add!(42usize, 38usize, 80usize); +payload_add!(42usize, 39usize, 81usize); +payload_add!(42usize, 40usize, 82usize); +payload_add!(42usize, 41usize, 83usize); +payload_add!(42usize, 42usize, 84usize); +payload_add!(42usize, 43usize, 85usize); +payload_add!(42usize, 44usize, 86usize); +payload_add!(42usize, 45usize, 87usize); +payload_add!(42usize, 46usize, 88usize); +payload_add!(42usize, 47usize, 89usize); +payload_add!(42usize, 48usize, 90usize); +payload_add!(42usize, 49usize, 91usize); +payload_add!(42usize, 50usize, 92usize); +payload_add!(42usize, 51usize, 93usize); +payload_add!(42usize, 52usize, 94usize); +payload_add!(42usize, 53usize, 95usize); +payload_add!(42usize, 54usize, 96usize); +payload_add!(42usize, 55usize, 97usize); +payload_add!(42usize, 56usize, 98usize); +payload_add!(42usize, 57usize, 99usize); +payload_add!(42usize, 58usize, 100usize); +payload_add!(42usize, 59usize, 101usize); +payload_add!(42usize, 60usize, 102usize); +payload_add!(42usize, 61usize, 103usize); +payload_add!(42usize, 62usize, 104usize); +payload_add!(42usize, 63usize, 105usize); +payload_add!(42usize, 64usize, 106usize); +payload_add!(42usize, 65usize, 107usize); +payload_add!(42usize, 66usize, 108usize); +payload_add!(42usize, 67usize, 109usize); +payload_add!(42usize, 68usize, 110usize); +payload_add!(42usize, 69usize, 111usize); +payload_add!(42usize, 70usize, 112usize); +payload_add!(42usize, 71usize, 113usize); +payload_add!(42usize, 72usize, 114usize); +payload_add!(42usize, 73usize, 115usize); +payload_add!(42usize, 74usize, 116usize); +payload_add!(42usize, 75usize, 117usize); +payload_add!(42usize, 76usize, 118usize); +payload_add!(42usize, 77usize, 119usize); +payload_add!(42usize, 78usize, 120usize); +payload_add!(42usize, 79usize, 121usize); +payload_add!(42usize, 80usize, 122usize); +payload_add!(42usize, 81usize, 123usize); +payload_add!(42usize, 82usize, 124usize); +payload_add!(42usize, 83usize, 125usize); +payload_add!(42usize, 84usize, 126usize); +payload_add!(42usize, 85usize, 127usize); +payload_add!(42usize, 86usize, 128usize); +payload_add!(42usize, 87usize, 129usize); +payload_add!(42usize, 88usize, 130usize); +payload_add!(42usize, 89usize, 131usize); +payload_add!(42usize, 90usize, 132usize); +payload_add!(42usize, 91usize, 133usize); +payload_add!(42usize, 92usize, 134usize); +payload_add!(42usize, 93usize, 135usize); +payload_add!(42usize, 94usize, 136usize); +payload_add!(42usize, 95usize, 137usize); +payload_add!(42usize, 96usize, 138usize); +payload_add!(42usize, 97usize, 139usize); +payload_add!(42usize, 98usize, 140usize); +payload_add!(42usize, 99usize, 141usize); +payload_add!(42usize, 100usize, 142usize); +payload_add!(42usize, 101usize, 143usize); +payload_add!(42usize, 102usize, 144usize); +payload_add!(42usize, 103usize, 145usize); +payload_add!(42usize, 104usize, 146usize); +payload_add!(42usize, 105usize, 147usize); +payload_add!(42usize, 106usize, 148usize); +payload_add!(42usize, 107usize, 149usize); +payload_add!(42usize, 108usize, 150usize); +payload_add!(42usize, 109usize, 151usize); +payload_add!(42usize, 110usize, 152usize); +payload_add!(42usize, 111usize, 153usize); +payload_add!(42usize, 112usize, 154usize); +payload_add!(42usize, 113usize, 155usize); +payload_add!(42usize, 114usize, 156usize); +payload_add!(42usize, 115usize, 157usize); +payload_add!(42usize, 116usize, 158usize); +payload_add!(42usize, 117usize, 159usize); +payload_add!(42usize, 118usize, 160usize); +payload_add!(42usize, 119usize, 161usize); +payload_add!(42usize, 120usize, 162usize); +payload_add!(42usize, 121usize, 163usize); +payload_add!(42usize, 122usize, 164usize); +payload_add!(42usize, 123usize, 165usize); +payload_add!(42usize, 124usize, 166usize); +payload_add!(42usize, 125usize, 167usize); +payload_add!(42usize, 126usize, 168usize); +payload_add!(42usize, 127usize, 169usize); +payload_add!(42usize, 128usize, 170usize); +payload_add!(43usize, 1usize, 44usize); +payload_add!(43usize, 2usize, 45usize); +payload_add!(43usize, 3usize, 46usize); +payload_add!(43usize, 4usize, 47usize); +payload_add!(43usize, 5usize, 48usize); +payload_add!(43usize, 6usize, 49usize); +payload_add!(43usize, 7usize, 50usize); +payload_add!(43usize, 8usize, 51usize); +payload_add!(43usize, 9usize, 52usize); +payload_add!(43usize, 10usize, 53usize); +payload_add!(43usize, 11usize, 54usize); +payload_add!(43usize, 12usize, 55usize); +payload_add!(43usize, 13usize, 56usize); +payload_add!(43usize, 14usize, 57usize); +payload_add!(43usize, 15usize, 58usize); +payload_add!(43usize, 16usize, 59usize); +payload_add!(43usize, 17usize, 60usize); +payload_add!(43usize, 18usize, 61usize); +payload_add!(43usize, 19usize, 62usize); +payload_add!(43usize, 20usize, 63usize); +payload_add!(43usize, 21usize, 64usize); +payload_add!(43usize, 22usize, 65usize); +payload_add!(43usize, 23usize, 66usize); +payload_add!(43usize, 24usize, 67usize); +payload_add!(43usize, 25usize, 68usize); +payload_add!(43usize, 26usize, 69usize); +payload_add!(43usize, 27usize, 70usize); +payload_add!(43usize, 28usize, 71usize); +payload_add!(43usize, 29usize, 72usize); +payload_add!(43usize, 30usize, 73usize); +payload_add!(43usize, 31usize, 74usize); +payload_add!(43usize, 32usize, 75usize); +payload_add!(43usize, 33usize, 76usize); +payload_add!(43usize, 34usize, 77usize); +payload_add!(43usize, 35usize, 78usize); +payload_add!(43usize, 36usize, 79usize); +payload_add!(43usize, 37usize, 80usize); +payload_add!(43usize, 38usize, 81usize); +payload_add!(43usize, 39usize, 82usize); +payload_add!(43usize, 40usize, 83usize); +payload_add!(43usize, 41usize, 84usize); +payload_add!(43usize, 42usize, 85usize); +payload_add!(43usize, 43usize, 86usize); +payload_add!(43usize, 44usize, 87usize); +payload_add!(43usize, 45usize, 88usize); +payload_add!(43usize, 46usize, 89usize); +payload_add!(43usize, 47usize, 90usize); +payload_add!(43usize, 48usize, 91usize); +payload_add!(43usize, 49usize, 92usize); +payload_add!(43usize, 50usize, 93usize); +payload_add!(43usize, 51usize, 94usize); +payload_add!(43usize, 52usize, 95usize); +payload_add!(43usize, 53usize, 96usize); +payload_add!(43usize, 54usize, 97usize); +payload_add!(43usize, 55usize, 98usize); +payload_add!(43usize, 56usize, 99usize); +payload_add!(43usize, 57usize, 100usize); +payload_add!(43usize, 58usize, 101usize); +payload_add!(43usize, 59usize, 102usize); +payload_add!(43usize, 60usize, 103usize); +payload_add!(43usize, 61usize, 104usize); +payload_add!(43usize, 62usize, 105usize); +payload_add!(43usize, 63usize, 106usize); +payload_add!(43usize, 64usize, 107usize); +payload_add!(43usize, 65usize, 108usize); +payload_add!(43usize, 66usize, 109usize); +payload_add!(43usize, 67usize, 110usize); +payload_add!(43usize, 68usize, 111usize); +payload_add!(43usize, 69usize, 112usize); +payload_add!(43usize, 70usize, 113usize); +payload_add!(43usize, 71usize, 114usize); +payload_add!(43usize, 72usize, 115usize); +payload_add!(43usize, 73usize, 116usize); +payload_add!(43usize, 74usize, 117usize); +payload_add!(43usize, 75usize, 118usize); +payload_add!(43usize, 76usize, 119usize); +payload_add!(43usize, 77usize, 120usize); +payload_add!(43usize, 78usize, 121usize); +payload_add!(43usize, 79usize, 122usize); +payload_add!(43usize, 80usize, 123usize); +payload_add!(43usize, 81usize, 124usize); +payload_add!(43usize, 82usize, 125usize); +payload_add!(43usize, 83usize, 126usize); +payload_add!(43usize, 84usize, 127usize); +payload_add!(43usize, 85usize, 128usize); +payload_add!(43usize, 86usize, 129usize); +payload_add!(43usize, 87usize, 130usize); +payload_add!(43usize, 88usize, 131usize); +payload_add!(43usize, 89usize, 132usize); +payload_add!(43usize, 90usize, 133usize); +payload_add!(43usize, 91usize, 134usize); +payload_add!(43usize, 92usize, 135usize); +payload_add!(43usize, 93usize, 136usize); +payload_add!(43usize, 94usize, 137usize); +payload_add!(43usize, 95usize, 138usize); +payload_add!(43usize, 96usize, 139usize); +payload_add!(43usize, 97usize, 140usize); +payload_add!(43usize, 98usize, 141usize); +payload_add!(43usize, 99usize, 142usize); +payload_add!(43usize, 100usize, 143usize); +payload_add!(43usize, 101usize, 144usize); +payload_add!(43usize, 102usize, 145usize); +payload_add!(43usize, 103usize, 146usize); +payload_add!(43usize, 104usize, 147usize); +payload_add!(43usize, 105usize, 148usize); +payload_add!(43usize, 106usize, 149usize); +payload_add!(43usize, 107usize, 150usize); +payload_add!(43usize, 108usize, 151usize); +payload_add!(43usize, 109usize, 152usize); +payload_add!(43usize, 110usize, 153usize); +payload_add!(43usize, 111usize, 154usize); +payload_add!(43usize, 112usize, 155usize); +payload_add!(43usize, 113usize, 156usize); +payload_add!(43usize, 114usize, 157usize); +payload_add!(43usize, 115usize, 158usize); +payload_add!(43usize, 116usize, 159usize); +payload_add!(43usize, 117usize, 160usize); +payload_add!(43usize, 118usize, 161usize); +payload_add!(43usize, 119usize, 162usize); +payload_add!(43usize, 120usize, 163usize); +payload_add!(43usize, 121usize, 164usize); +payload_add!(43usize, 122usize, 165usize); +payload_add!(43usize, 123usize, 166usize); +payload_add!(43usize, 124usize, 167usize); +payload_add!(43usize, 125usize, 168usize); +payload_add!(43usize, 126usize, 169usize); +payload_add!(43usize, 127usize, 170usize); +payload_add!(43usize, 128usize, 171usize); +payload_add!(44usize, 1usize, 45usize); +payload_add!(44usize, 2usize, 46usize); +payload_add!(44usize, 3usize, 47usize); +payload_add!(44usize, 4usize, 48usize); +payload_add!(44usize, 5usize, 49usize); +payload_add!(44usize, 6usize, 50usize); +payload_add!(44usize, 7usize, 51usize); +payload_add!(44usize, 8usize, 52usize); +payload_add!(44usize, 9usize, 53usize); +payload_add!(44usize, 10usize, 54usize); +payload_add!(44usize, 11usize, 55usize); +payload_add!(44usize, 12usize, 56usize); +payload_add!(44usize, 13usize, 57usize); +payload_add!(44usize, 14usize, 58usize); +payload_add!(44usize, 15usize, 59usize); +payload_add!(44usize, 16usize, 60usize); +payload_add!(44usize, 17usize, 61usize); +payload_add!(44usize, 18usize, 62usize); +payload_add!(44usize, 19usize, 63usize); +payload_add!(44usize, 20usize, 64usize); +payload_add!(44usize, 21usize, 65usize); +payload_add!(44usize, 22usize, 66usize); +payload_add!(44usize, 23usize, 67usize); +payload_add!(44usize, 24usize, 68usize); +payload_add!(44usize, 25usize, 69usize); +payload_add!(44usize, 26usize, 70usize); +payload_add!(44usize, 27usize, 71usize); +payload_add!(44usize, 28usize, 72usize); +payload_add!(44usize, 29usize, 73usize); +payload_add!(44usize, 30usize, 74usize); +payload_add!(44usize, 31usize, 75usize); +payload_add!(44usize, 32usize, 76usize); +payload_add!(44usize, 33usize, 77usize); +payload_add!(44usize, 34usize, 78usize); +payload_add!(44usize, 35usize, 79usize); +payload_add!(44usize, 36usize, 80usize); +payload_add!(44usize, 37usize, 81usize); +payload_add!(44usize, 38usize, 82usize); +payload_add!(44usize, 39usize, 83usize); +payload_add!(44usize, 40usize, 84usize); +payload_add!(44usize, 41usize, 85usize); +payload_add!(44usize, 42usize, 86usize); +payload_add!(44usize, 43usize, 87usize); +payload_add!(44usize, 44usize, 88usize); +payload_add!(44usize, 45usize, 89usize); +payload_add!(44usize, 46usize, 90usize); +payload_add!(44usize, 47usize, 91usize); +payload_add!(44usize, 48usize, 92usize); +payload_add!(44usize, 49usize, 93usize); +payload_add!(44usize, 50usize, 94usize); +payload_add!(44usize, 51usize, 95usize); +payload_add!(44usize, 52usize, 96usize); +payload_add!(44usize, 53usize, 97usize); +payload_add!(44usize, 54usize, 98usize); +payload_add!(44usize, 55usize, 99usize); +payload_add!(44usize, 56usize, 100usize); +payload_add!(44usize, 57usize, 101usize); +payload_add!(44usize, 58usize, 102usize); +payload_add!(44usize, 59usize, 103usize); +payload_add!(44usize, 60usize, 104usize); +payload_add!(44usize, 61usize, 105usize); +payload_add!(44usize, 62usize, 106usize); +payload_add!(44usize, 63usize, 107usize); +payload_add!(44usize, 64usize, 108usize); +payload_add!(44usize, 65usize, 109usize); +payload_add!(44usize, 66usize, 110usize); +payload_add!(44usize, 67usize, 111usize); +payload_add!(44usize, 68usize, 112usize); +payload_add!(44usize, 69usize, 113usize); +payload_add!(44usize, 70usize, 114usize); +payload_add!(44usize, 71usize, 115usize); +payload_add!(44usize, 72usize, 116usize); +payload_add!(44usize, 73usize, 117usize); +payload_add!(44usize, 74usize, 118usize); +payload_add!(44usize, 75usize, 119usize); +payload_add!(44usize, 76usize, 120usize); +payload_add!(44usize, 77usize, 121usize); +payload_add!(44usize, 78usize, 122usize); +payload_add!(44usize, 79usize, 123usize); +payload_add!(44usize, 80usize, 124usize); +payload_add!(44usize, 81usize, 125usize); +payload_add!(44usize, 82usize, 126usize); +payload_add!(44usize, 83usize, 127usize); +payload_add!(44usize, 84usize, 128usize); +payload_add!(44usize, 85usize, 129usize); +payload_add!(44usize, 86usize, 130usize); +payload_add!(44usize, 87usize, 131usize); +payload_add!(44usize, 88usize, 132usize); +payload_add!(44usize, 89usize, 133usize); +payload_add!(44usize, 90usize, 134usize); +payload_add!(44usize, 91usize, 135usize); +payload_add!(44usize, 92usize, 136usize); +payload_add!(44usize, 93usize, 137usize); +payload_add!(44usize, 94usize, 138usize); +payload_add!(44usize, 95usize, 139usize); +payload_add!(44usize, 96usize, 140usize); +payload_add!(44usize, 97usize, 141usize); +payload_add!(44usize, 98usize, 142usize); +payload_add!(44usize, 99usize, 143usize); +payload_add!(44usize, 100usize, 144usize); +payload_add!(44usize, 101usize, 145usize); +payload_add!(44usize, 102usize, 146usize); +payload_add!(44usize, 103usize, 147usize); +payload_add!(44usize, 104usize, 148usize); +payload_add!(44usize, 105usize, 149usize); +payload_add!(44usize, 106usize, 150usize); +payload_add!(44usize, 107usize, 151usize); +payload_add!(44usize, 108usize, 152usize); +payload_add!(44usize, 109usize, 153usize); +payload_add!(44usize, 110usize, 154usize); +payload_add!(44usize, 111usize, 155usize); +payload_add!(44usize, 112usize, 156usize); +payload_add!(44usize, 113usize, 157usize); +payload_add!(44usize, 114usize, 158usize); +payload_add!(44usize, 115usize, 159usize); +payload_add!(44usize, 116usize, 160usize); +payload_add!(44usize, 117usize, 161usize); +payload_add!(44usize, 118usize, 162usize); +payload_add!(44usize, 119usize, 163usize); +payload_add!(44usize, 120usize, 164usize); +payload_add!(44usize, 121usize, 165usize); +payload_add!(44usize, 122usize, 166usize); +payload_add!(44usize, 123usize, 167usize); +payload_add!(44usize, 124usize, 168usize); +payload_add!(44usize, 125usize, 169usize); +payload_add!(44usize, 126usize, 170usize); +payload_add!(44usize, 127usize, 171usize); +payload_add!(44usize, 128usize, 172usize); +payload_add!(45usize, 1usize, 46usize); +payload_add!(45usize, 2usize, 47usize); +payload_add!(45usize, 3usize, 48usize); +payload_add!(45usize, 4usize, 49usize); +payload_add!(45usize, 5usize, 50usize); +payload_add!(45usize, 6usize, 51usize); +payload_add!(45usize, 7usize, 52usize); +payload_add!(45usize, 8usize, 53usize); +payload_add!(45usize, 9usize, 54usize); +payload_add!(45usize, 10usize, 55usize); +payload_add!(45usize, 11usize, 56usize); +payload_add!(45usize, 12usize, 57usize); +payload_add!(45usize, 13usize, 58usize); +payload_add!(45usize, 14usize, 59usize); +payload_add!(45usize, 15usize, 60usize); +payload_add!(45usize, 16usize, 61usize); +payload_add!(45usize, 17usize, 62usize); +payload_add!(45usize, 18usize, 63usize); +payload_add!(45usize, 19usize, 64usize); +payload_add!(45usize, 20usize, 65usize); +payload_add!(45usize, 21usize, 66usize); +payload_add!(45usize, 22usize, 67usize); +payload_add!(45usize, 23usize, 68usize); +payload_add!(45usize, 24usize, 69usize); +payload_add!(45usize, 25usize, 70usize); +payload_add!(45usize, 26usize, 71usize); +payload_add!(45usize, 27usize, 72usize); +payload_add!(45usize, 28usize, 73usize); +payload_add!(45usize, 29usize, 74usize); +payload_add!(45usize, 30usize, 75usize); +payload_add!(45usize, 31usize, 76usize); +payload_add!(45usize, 32usize, 77usize); +payload_add!(45usize, 33usize, 78usize); +payload_add!(45usize, 34usize, 79usize); +payload_add!(45usize, 35usize, 80usize); +payload_add!(45usize, 36usize, 81usize); +payload_add!(45usize, 37usize, 82usize); +payload_add!(45usize, 38usize, 83usize); +payload_add!(45usize, 39usize, 84usize); +payload_add!(45usize, 40usize, 85usize); +payload_add!(45usize, 41usize, 86usize); +payload_add!(45usize, 42usize, 87usize); +payload_add!(45usize, 43usize, 88usize); +payload_add!(45usize, 44usize, 89usize); +payload_add!(45usize, 45usize, 90usize); +payload_add!(45usize, 46usize, 91usize); +payload_add!(45usize, 47usize, 92usize); +payload_add!(45usize, 48usize, 93usize); +payload_add!(45usize, 49usize, 94usize); +payload_add!(45usize, 50usize, 95usize); +payload_add!(45usize, 51usize, 96usize); +payload_add!(45usize, 52usize, 97usize); +payload_add!(45usize, 53usize, 98usize); +payload_add!(45usize, 54usize, 99usize); +payload_add!(45usize, 55usize, 100usize); +payload_add!(45usize, 56usize, 101usize); +payload_add!(45usize, 57usize, 102usize); +payload_add!(45usize, 58usize, 103usize); +payload_add!(45usize, 59usize, 104usize); +payload_add!(45usize, 60usize, 105usize); +payload_add!(45usize, 61usize, 106usize); +payload_add!(45usize, 62usize, 107usize); +payload_add!(45usize, 63usize, 108usize); +payload_add!(45usize, 64usize, 109usize); +payload_add!(45usize, 65usize, 110usize); +payload_add!(45usize, 66usize, 111usize); +payload_add!(45usize, 67usize, 112usize); +payload_add!(45usize, 68usize, 113usize); +payload_add!(45usize, 69usize, 114usize); +payload_add!(45usize, 70usize, 115usize); +payload_add!(45usize, 71usize, 116usize); +payload_add!(45usize, 72usize, 117usize); +payload_add!(45usize, 73usize, 118usize); +payload_add!(45usize, 74usize, 119usize); +payload_add!(45usize, 75usize, 120usize); +payload_add!(45usize, 76usize, 121usize); +payload_add!(45usize, 77usize, 122usize); +payload_add!(45usize, 78usize, 123usize); +payload_add!(45usize, 79usize, 124usize); +payload_add!(45usize, 80usize, 125usize); +payload_add!(45usize, 81usize, 126usize); +payload_add!(45usize, 82usize, 127usize); +payload_add!(45usize, 83usize, 128usize); +payload_add!(45usize, 84usize, 129usize); +payload_add!(45usize, 85usize, 130usize); +payload_add!(45usize, 86usize, 131usize); +payload_add!(45usize, 87usize, 132usize); +payload_add!(45usize, 88usize, 133usize); +payload_add!(45usize, 89usize, 134usize); +payload_add!(45usize, 90usize, 135usize); +payload_add!(45usize, 91usize, 136usize); +payload_add!(45usize, 92usize, 137usize); +payload_add!(45usize, 93usize, 138usize); +payload_add!(45usize, 94usize, 139usize); +payload_add!(45usize, 95usize, 140usize); +payload_add!(45usize, 96usize, 141usize); +payload_add!(45usize, 97usize, 142usize); +payload_add!(45usize, 98usize, 143usize); +payload_add!(45usize, 99usize, 144usize); +payload_add!(45usize, 100usize, 145usize); +payload_add!(45usize, 101usize, 146usize); +payload_add!(45usize, 102usize, 147usize); +payload_add!(45usize, 103usize, 148usize); +payload_add!(45usize, 104usize, 149usize); +payload_add!(45usize, 105usize, 150usize); +payload_add!(45usize, 106usize, 151usize); +payload_add!(45usize, 107usize, 152usize); +payload_add!(45usize, 108usize, 153usize); +payload_add!(45usize, 109usize, 154usize); +payload_add!(45usize, 110usize, 155usize); +payload_add!(45usize, 111usize, 156usize); +payload_add!(45usize, 112usize, 157usize); +payload_add!(45usize, 113usize, 158usize); +payload_add!(45usize, 114usize, 159usize); +payload_add!(45usize, 115usize, 160usize); +payload_add!(45usize, 116usize, 161usize); +payload_add!(45usize, 117usize, 162usize); +payload_add!(45usize, 118usize, 163usize); +payload_add!(45usize, 119usize, 164usize); +payload_add!(45usize, 120usize, 165usize); +payload_add!(45usize, 121usize, 166usize); +payload_add!(45usize, 122usize, 167usize); +payload_add!(45usize, 123usize, 168usize); +payload_add!(45usize, 124usize, 169usize); +payload_add!(45usize, 125usize, 170usize); +payload_add!(45usize, 126usize, 171usize); +payload_add!(45usize, 127usize, 172usize); +payload_add!(45usize, 128usize, 173usize); +payload_add!(46usize, 1usize, 47usize); +payload_add!(46usize, 2usize, 48usize); +payload_add!(46usize, 3usize, 49usize); +payload_add!(46usize, 4usize, 50usize); +payload_add!(46usize, 5usize, 51usize); +payload_add!(46usize, 6usize, 52usize); +payload_add!(46usize, 7usize, 53usize); +payload_add!(46usize, 8usize, 54usize); +payload_add!(46usize, 9usize, 55usize); +payload_add!(46usize, 10usize, 56usize); +payload_add!(46usize, 11usize, 57usize); +payload_add!(46usize, 12usize, 58usize); +payload_add!(46usize, 13usize, 59usize); +payload_add!(46usize, 14usize, 60usize); +payload_add!(46usize, 15usize, 61usize); +payload_add!(46usize, 16usize, 62usize); +payload_add!(46usize, 17usize, 63usize); +payload_add!(46usize, 18usize, 64usize); +payload_add!(46usize, 19usize, 65usize); +payload_add!(46usize, 20usize, 66usize); +payload_add!(46usize, 21usize, 67usize); +payload_add!(46usize, 22usize, 68usize); +payload_add!(46usize, 23usize, 69usize); +payload_add!(46usize, 24usize, 70usize); +payload_add!(46usize, 25usize, 71usize); +payload_add!(46usize, 26usize, 72usize); +payload_add!(46usize, 27usize, 73usize); +payload_add!(46usize, 28usize, 74usize); +payload_add!(46usize, 29usize, 75usize); +payload_add!(46usize, 30usize, 76usize); +payload_add!(46usize, 31usize, 77usize); +payload_add!(46usize, 32usize, 78usize); +payload_add!(46usize, 33usize, 79usize); +payload_add!(46usize, 34usize, 80usize); +payload_add!(46usize, 35usize, 81usize); +payload_add!(46usize, 36usize, 82usize); +payload_add!(46usize, 37usize, 83usize); +payload_add!(46usize, 38usize, 84usize); +payload_add!(46usize, 39usize, 85usize); +payload_add!(46usize, 40usize, 86usize); +payload_add!(46usize, 41usize, 87usize); +payload_add!(46usize, 42usize, 88usize); +payload_add!(46usize, 43usize, 89usize); +payload_add!(46usize, 44usize, 90usize); +payload_add!(46usize, 45usize, 91usize); +payload_add!(46usize, 46usize, 92usize); +payload_add!(46usize, 47usize, 93usize); +payload_add!(46usize, 48usize, 94usize); +payload_add!(46usize, 49usize, 95usize); +payload_add!(46usize, 50usize, 96usize); +payload_add!(46usize, 51usize, 97usize); +payload_add!(46usize, 52usize, 98usize); +payload_add!(46usize, 53usize, 99usize); +payload_add!(46usize, 54usize, 100usize); +payload_add!(46usize, 55usize, 101usize); +payload_add!(46usize, 56usize, 102usize); +payload_add!(46usize, 57usize, 103usize); +payload_add!(46usize, 58usize, 104usize); +payload_add!(46usize, 59usize, 105usize); +payload_add!(46usize, 60usize, 106usize); +payload_add!(46usize, 61usize, 107usize); +payload_add!(46usize, 62usize, 108usize); +payload_add!(46usize, 63usize, 109usize); +payload_add!(46usize, 64usize, 110usize); +payload_add!(46usize, 65usize, 111usize); +payload_add!(46usize, 66usize, 112usize); +payload_add!(46usize, 67usize, 113usize); +payload_add!(46usize, 68usize, 114usize); +payload_add!(46usize, 69usize, 115usize); +payload_add!(46usize, 70usize, 116usize); +payload_add!(46usize, 71usize, 117usize); +payload_add!(46usize, 72usize, 118usize); +payload_add!(46usize, 73usize, 119usize); +payload_add!(46usize, 74usize, 120usize); +payload_add!(46usize, 75usize, 121usize); +payload_add!(46usize, 76usize, 122usize); +payload_add!(46usize, 77usize, 123usize); +payload_add!(46usize, 78usize, 124usize); +payload_add!(46usize, 79usize, 125usize); +payload_add!(46usize, 80usize, 126usize); +payload_add!(46usize, 81usize, 127usize); +payload_add!(46usize, 82usize, 128usize); +payload_add!(46usize, 83usize, 129usize); +payload_add!(46usize, 84usize, 130usize); +payload_add!(46usize, 85usize, 131usize); +payload_add!(46usize, 86usize, 132usize); +payload_add!(46usize, 87usize, 133usize); +payload_add!(46usize, 88usize, 134usize); +payload_add!(46usize, 89usize, 135usize); +payload_add!(46usize, 90usize, 136usize); +payload_add!(46usize, 91usize, 137usize); +payload_add!(46usize, 92usize, 138usize); +payload_add!(46usize, 93usize, 139usize); +payload_add!(46usize, 94usize, 140usize); +payload_add!(46usize, 95usize, 141usize); +payload_add!(46usize, 96usize, 142usize); +payload_add!(46usize, 97usize, 143usize); +payload_add!(46usize, 98usize, 144usize); +payload_add!(46usize, 99usize, 145usize); +payload_add!(46usize, 100usize, 146usize); +payload_add!(46usize, 101usize, 147usize); +payload_add!(46usize, 102usize, 148usize); +payload_add!(46usize, 103usize, 149usize); +payload_add!(46usize, 104usize, 150usize); +payload_add!(46usize, 105usize, 151usize); +payload_add!(46usize, 106usize, 152usize); +payload_add!(46usize, 107usize, 153usize); +payload_add!(46usize, 108usize, 154usize); +payload_add!(46usize, 109usize, 155usize); +payload_add!(46usize, 110usize, 156usize); +payload_add!(46usize, 111usize, 157usize); +payload_add!(46usize, 112usize, 158usize); +payload_add!(46usize, 113usize, 159usize); +payload_add!(46usize, 114usize, 160usize); +payload_add!(46usize, 115usize, 161usize); +payload_add!(46usize, 116usize, 162usize); +payload_add!(46usize, 117usize, 163usize); +payload_add!(46usize, 118usize, 164usize); +payload_add!(46usize, 119usize, 165usize); +payload_add!(46usize, 120usize, 166usize); +payload_add!(46usize, 121usize, 167usize); +payload_add!(46usize, 122usize, 168usize); +payload_add!(46usize, 123usize, 169usize); +payload_add!(46usize, 124usize, 170usize); +payload_add!(46usize, 125usize, 171usize); +payload_add!(46usize, 126usize, 172usize); +payload_add!(46usize, 127usize, 173usize); +payload_add!(46usize, 128usize, 174usize); +payload_add!(47usize, 1usize, 48usize); +payload_add!(47usize, 2usize, 49usize); +payload_add!(47usize, 3usize, 50usize); +payload_add!(47usize, 4usize, 51usize); +payload_add!(47usize, 5usize, 52usize); +payload_add!(47usize, 6usize, 53usize); +payload_add!(47usize, 7usize, 54usize); +payload_add!(47usize, 8usize, 55usize); +payload_add!(47usize, 9usize, 56usize); +payload_add!(47usize, 10usize, 57usize); +payload_add!(47usize, 11usize, 58usize); +payload_add!(47usize, 12usize, 59usize); +payload_add!(47usize, 13usize, 60usize); +payload_add!(47usize, 14usize, 61usize); +payload_add!(47usize, 15usize, 62usize); +payload_add!(47usize, 16usize, 63usize); +payload_add!(47usize, 17usize, 64usize); +payload_add!(47usize, 18usize, 65usize); +payload_add!(47usize, 19usize, 66usize); +payload_add!(47usize, 20usize, 67usize); +payload_add!(47usize, 21usize, 68usize); +payload_add!(47usize, 22usize, 69usize); +payload_add!(47usize, 23usize, 70usize); +payload_add!(47usize, 24usize, 71usize); +payload_add!(47usize, 25usize, 72usize); +payload_add!(47usize, 26usize, 73usize); +payload_add!(47usize, 27usize, 74usize); +payload_add!(47usize, 28usize, 75usize); +payload_add!(47usize, 29usize, 76usize); +payload_add!(47usize, 30usize, 77usize); +payload_add!(47usize, 31usize, 78usize); +payload_add!(47usize, 32usize, 79usize); +payload_add!(47usize, 33usize, 80usize); +payload_add!(47usize, 34usize, 81usize); +payload_add!(47usize, 35usize, 82usize); +payload_add!(47usize, 36usize, 83usize); +payload_add!(47usize, 37usize, 84usize); +payload_add!(47usize, 38usize, 85usize); +payload_add!(47usize, 39usize, 86usize); +payload_add!(47usize, 40usize, 87usize); +payload_add!(47usize, 41usize, 88usize); +payload_add!(47usize, 42usize, 89usize); +payload_add!(47usize, 43usize, 90usize); +payload_add!(47usize, 44usize, 91usize); +payload_add!(47usize, 45usize, 92usize); +payload_add!(47usize, 46usize, 93usize); +payload_add!(47usize, 47usize, 94usize); +payload_add!(47usize, 48usize, 95usize); +payload_add!(47usize, 49usize, 96usize); +payload_add!(47usize, 50usize, 97usize); +payload_add!(47usize, 51usize, 98usize); +payload_add!(47usize, 52usize, 99usize); +payload_add!(47usize, 53usize, 100usize); +payload_add!(47usize, 54usize, 101usize); +payload_add!(47usize, 55usize, 102usize); +payload_add!(47usize, 56usize, 103usize); +payload_add!(47usize, 57usize, 104usize); +payload_add!(47usize, 58usize, 105usize); +payload_add!(47usize, 59usize, 106usize); +payload_add!(47usize, 60usize, 107usize); +payload_add!(47usize, 61usize, 108usize); +payload_add!(47usize, 62usize, 109usize); +payload_add!(47usize, 63usize, 110usize); +payload_add!(47usize, 64usize, 111usize); +payload_add!(47usize, 65usize, 112usize); +payload_add!(47usize, 66usize, 113usize); +payload_add!(47usize, 67usize, 114usize); +payload_add!(47usize, 68usize, 115usize); +payload_add!(47usize, 69usize, 116usize); +payload_add!(47usize, 70usize, 117usize); +payload_add!(47usize, 71usize, 118usize); +payload_add!(47usize, 72usize, 119usize); +payload_add!(47usize, 73usize, 120usize); +payload_add!(47usize, 74usize, 121usize); +payload_add!(47usize, 75usize, 122usize); +payload_add!(47usize, 76usize, 123usize); +payload_add!(47usize, 77usize, 124usize); +payload_add!(47usize, 78usize, 125usize); +payload_add!(47usize, 79usize, 126usize); +payload_add!(47usize, 80usize, 127usize); +payload_add!(47usize, 81usize, 128usize); +payload_add!(47usize, 82usize, 129usize); +payload_add!(47usize, 83usize, 130usize); +payload_add!(47usize, 84usize, 131usize); +payload_add!(47usize, 85usize, 132usize); +payload_add!(47usize, 86usize, 133usize); +payload_add!(47usize, 87usize, 134usize); +payload_add!(47usize, 88usize, 135usize); +payload_add!(47usize, 89usize, 136usize); +payload_add!(47usize, 90usize, 137usize); +payload_add!(47usize, 91usize, 138usize); +payload_add!(47usize, 92usize, 139usize); +payload_add!(47usize, 93usize, 140usize); +payload_add!(47usize, 94usize, 141usize); +payload_add!(47usize, 95usize, 142usize); +payload_add!(47usize, 96usize, 143usize); +payload_add!(47usize, 97usize, 144usize); +payload_add!(47usize, 98usize, 145usize); +payload_add!(47usize, 99usize, 146usize); +payload_add!(47usize, 100usize, 147usize); +payload_add!(47usize, 101usize, 148usize); +payload_add!(47usize, 102usize, 149usize); +payload_add!(47usize, 103usize, 150usize); +payload_add!(47usize, 104usize, 151usize); +payload_add!(47usize, 105usize, 152usize); +payload_add!(47usize, 106usize, 153usize); +payload_add!(47usize, 107usize, 154usize); +payload_add!(47usize, 108usize, 155usize); +payload_add!(47usize, 109usize, 156usize); +payload_add!(47usize, 110usize, 157usize); +payload_add!(47usize, 111usize, 158usize); +payload_add!(47usize, 112usize, 159usize); +payload_add!(47usize, 113usize, 160usize); +payload_add!(47usize, 114usize, 161usize); +payload_add!(47usize, 115usize, 162usize); +payload_add!(47usize, 116usize, 163usize); +payload_add!(47usize, 117usize, 164usize); +payload_add!(47usize, 118usize, 165usize); +payload_add!(47usize, 119usize, 166usize); +payload_add!(47usize, 120usize, 167usize); +payload_add!(47usize, 121usize, 168usize); +payload_add!(47usize, 122usize, 169usize); +payload_add!(47usize, 123usize, 170usize); +payload_add!(47usize, 124usize, 171usize); +payload_add!(47usize, 125usize, 172usize); +payload_add!(47usize, 126usize, 173usize); +payload_add!(47usize, 127usize, 174usize); +payload_add!(47usize, 128usize, 175usize); +payload_add!(48usize, 1usize, 49usize); +payload_add!(48usize, 2usize, 50usize); +payload_add!(48usize, 3usize, 51usize); +payload_add!(48usize, 4usize, 52usize); +payload_add!(48usize, 5usize, 53usize); +payload_add!(48usize, 6usize, 54usize); +payload_add!(48usize, 7usize, 55usize); +payload_add!(48usize, 8usize, 56usize); +payload_add!(48usize, 9usize, 57usize); +payload_add!(48usize, 10usize, 58usize); +payload_add!(48usize, 11usize, 59usize); +payload_add!(48usize, 12usize, 60usize); +payload_add!(48usize, 13usize, 61usize); +payload_add!(48usize, 14usize, 62usize); +payload_add!(48usize, 15usize, 63usize); +payload_add!(48usize, 16usize, 64usize); +payload_add!(48usize, 17usize, 65usize); +payload_add!(48usize, 18usize, 66usize); +payload_add!(48usize, 19usize, 67usize); +payload_add!(48usize, 20usize, 68usize); +payload_add!(48usize, 21usize, 69usize); +payload_add!(48usize, 22usize, 70usize); +payload_add!(48usize, 23usize, 71usize); +payload_add!(48usize, 24usize, 72usize); +payload_add!(48usize, 25usize, 73usize); +payload_add!(48usize, 26usize, 74usize); +payload_add!(48usize, 27usize, 75usize); +payload_add!(48usize, 28usize, 76usize); +payload_add!(48usize, 29usize, 77usize); +payload_add!(48usize, 30usize, 78usize); +payload_add!(48usize, 31usize, 79usize); +payload_add!(48usize, 32usize, 80usize); +payload_add!(48usize, 33usize, 81usize); +payload_add!(48usize, 34usize, 82usize); +payload_add!(48usize, 35usize, 83usize); +payload_add!(48usize, 36usize, 84usize); +payload_add!(48usize, 37usize, 85usize); +payload_add!(48usize, 38usize, 86usize); +payload_add!(48usize, 39usize, 87usize); +payload_add!(48usize, 40usize, 88usize); +payload_add!(48usize, 41usize, 89usize); +payload_add!(48usize, 42usize, 90usize); +payload_add!(48usize, 43usize, 91usize); +payload_add!(48usize, 44usize, 92usize); +payload_add!(48usize, 45usize, 93usize); +payload_add!(48usize, 46usize, 94usize); +payload_add!(48usize, 47usize, 95usize); +payload_add!(48usize, 48usize, 96usize); +payload_add!(48usize, 49usize, 97usize); +payload_add!(48usize, 50usize, 98usize); +payload_add!(48usize, 51usize, 99usize); +payload_add!(48usize, 52usize, 100usize); +payload_add!(48usize, 53usize, 101usize); +payload_add!(48usize, 54usize, 102usize); +payload_add!(48usize, 55usize, 103usize); +payload_add!(48usize, 56usize, 104usize); +payload_add!(48usize, 57usize, 105usize); +payload_add!(48usize, 58usize, 106usize); +payload_add!(48usize, 59usize, 107usize); +payload_add!(48usize, 60usize, 108usize); +payload_add!(48usize, 61usize, 109usize); +payload_add!(48usize, 62usize, 110usize); +payload_add!(48usize, 63usize, 111usize); +payload_add!(48usize, 64usize, 112usize); +payload_add!(48usize, 65usize, 113usize); +payload_add!(48usize, 66usize, 114usize); +payload_add!(48usize, 67usize, 115usize); +payload_add!(48usize, 68usize, 116usize); +payload_add!(48usize, 69usize, 117usize); +payload_add!(48usize, 70usize, 118usize); +payload_add!(48usize, 71usize, 119usize); +payload_add!(48usize, 72usize, 120usize); +payload_add!(48usize, 73usize, 121usize); +payload_add!(48usize, 74usize, 122usize); +payload_add!(48usize, 75usize, 123usize); +payload_add!(48usize, 76usize, 124usize); +payload_add!(48usize, 77usize, 125usize); +payload_add!(48usize, 78usize, 126usize); +payload_add!(48usize, 79usize, 127usize); +payload_add!(48usize, 80usize, 128usize); +payload_add!(48usize, 81usize, 129usize); +payload_add!(48usize, 82usize, 130usize); +payload_add!(48usize, 83usize, 131usize); +payload_add!(48usize, 84usize, 132usize); +payload_add!(48usize, 85usize, 133usize); +payload_add!(48usize, 86usize, 134usize); +payload_add!(48usize, 87usize, 135usize); +payload_add!(48usize, 88usize, 136usize); +payload_add!(48usize, 89usize, 137usize); +payload_add!(48usize, 90usize, 138usize); +payload_add!(48usize, 91usize, 139usize); +payload_add!(48usize, 92usize, 140usize); +payload_add!(48usize, 93usize, 141usize); +payload_add!(48usize, 94usize, 142usize); +payload_add!(48usize, 95usize, 143usize); +payload_add!(48usize, 96usize, 144usize); +payload_add!(48usize, 97usize, 145usize); +payload_add!(48usize, 98usize, 146usize); +payload_add!(48usize, 99usize, 147usize); +payload_add!(48usize, 100usize, 148usize); +payload_add!(48usize, 101usize, 149usize); +payload_add!(48usize, 102usize, 150usize); +payload_add!(48usize, 103usize, 151usize); +payload_add!(48usize, 104usize, 152usize); +payload_add!(48usize, 105usize, 153usize); +payload_add!(48usize, 106usize, 154usize); +payload_add!(48usize, 107usize, 155usize); +payload_add!(48usize, 108usize, 156usize); +payload_add!(48usize, 109usize, 157usize); +payload_add!(48usize, 110usize, 158usize); +payload_add!(48usize, 111usize, 159usize); +payload_add!(48usize, 112usize, 160usize); +payload_add!(48usize, 113usize, 161usize); +payload_add!(48usize, 114usize, 162usize); +payload_add!(48usize, 115usize, 163usize); +payload_add!(48usize, 116usize, 164usize); +payload_add!(48usize, 117usize, 165usize); +payload_add!(48usize, 118usize, 166usize); +payload_add!(48usize, 119usize, 167usize); +payload_add!(48usize, 120usize, 168usize); +payload_add!(48usize, 121usize, 169usize); +payload_add!(48usize, 122usize, 170usize); +payload_add!(48usize, 123usize, 171usize); +payload_add!(48usize, 124usize, 172usize); +payload_add!(48usize, 125usize, 173usize); +payload_add!(48usize, 126usize, 174usize); +payload_add!(48usize, 127usize, 175usize); +payload_add!(48usize, 128usize, 176usize); diff --git a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs index a40c8c798f..20942e70d4 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_owned_iter.rs @@ -48,7 +48,7 @@ where fn next(&mut self) -> Option { // managedrev / reference type - let next_byte_start = self.byte_start + T::PAYLOAD_SIZE; + let next_byte_start = self.byte_start + T::payload_size(); if next_byte_start > self.byte_end { return None; } @@ -64,7 +64,8 @@ where } fn size_hint(&self) -> (usize, Option) { - let remaining = (self.byte_end - self.byte_start) / T::PAYLOAD_SIZE; + let size = T::payload_size(); + let remaining = (self.byte_end - self.byte_start) / size; (remaining, Some(remaining)) } } @@ -82,10 +83,10 @@ where T: ManagedVecItem, { fn next_back(&mut self) -> Option { - if self.byte_start + T::PAYLOAD_SIZE > self.byte_end { + if self.byte_start + T::payload_size() > self.byte_end { return None; } - self.byte_end -= T::PAYLOAD_SIZE; + self.byte_end -= T::payload_size(); let result = T::from_byte_reader(|dest_slice| { let _ = self diff --git a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs index 13d837510f..ad04b5eaf4 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_ref_iter.rs @@ -34,7 +34,7 @@ where type Item = T::Ref<'a>; fn next(&mut self) -> Option { - let next_byte_start = self.byte_start + T::PAYLOAD_SIZE; + let next_byte_start = self.byte_start + T::payload_size(); if next_byte_start > self.byte_end { return None; } @@ -52,7 +52,7 @@ where } fn size_hint(&self) -> (usize, Option) { - let remaining = (self.byte_end - self.byte_start) / T::PAYLOAD_SIZE; + let remaining = (self.byte_end - self.byte_start) / T::payload_size(); (remaining, Some(remaining)) } } @@ -70,10 +70,10 @@ where T: ManagedVecItem, { fn next_back(&mut self) -> Option { - if self.byte_start + T::PAYLOAD_SIZE > self.byte_end { + if self.byte_start + T::payload_size() > self.byte_end { return None; } - self.byte_end -= T::PAYLOAD_SIZE; + self.byte_end -= T::payload_size(); let result = unsafe { T::from_byte_reader_as_borrow(|dest_slice| { diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index e05c3a3a43..a07a604f0a 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -1,3 +1,4 @@ +mod builder; mod egld_or_esdt_token_identifier; mod egld_or_esdt_token_payment; mod egld_or_multi_esdt_payment; @@ -5,7 +6,6 @@ mod encoded_managed_vec_item; mod esdt_token_data; mod esdt_token_payment; mod managed_address; -mod managed_buffer_cached_builder; mod managed_byte_array; mod managed_decimal; mod managed_decimal_macros; @@ -13,21 +13,24 @@ mod managed_option; mod managed_ref; mod managed_vec; mod managed_vec_item; +mod managed_vec_item_nested_tuple; +mod managed_vec_item_payload; mod managed_vec_owned_iter; mod managed_vec_ref; mod managed_vec_ref_iter; pub(crate) mod preloaded_managed_buffer; mod randomness_source; mod token_identifier; +mod traits; +pub use builder::*; pub use egld_or_esdt_token_identifier::EgldOrEsdtTokenIdentifier; -pub use egld_or_esdt_token_payment::EgldOrEsdtTokenPayment; -pub use egld_or_multi_esdt_payment::EgldOrMultiEsdtPayment; +pub use egld_or_esdt_token_payment::{EgldOrEsdtTokenPayment, EgldOrEsdtTokenPaymentRefs}; +pub use egld_or_multi_esdt_payment::{EgldOrMultiEsdtPayment, EgldOrMultiEsdtPaymentRefs}; pub(crate) use encoded_managed_vec_item::EncodedManagedVecItem; pub use esdt_token_data::EsdtTokenData; -pub use esdt_token_payment::{EsdtTokenPayment, MultiEsdtPayment}; +pub use esdt_token_payment::{EsdtTokenPayment, EsdtTokenPaymentRefs, MultiEsdtPayment}; pub use managed_address::ManagedAddress; -pub use managed_buffer_cached_builder::ManagedBufferCachedBuilder; pub(crate) use managed_byte_array::ManagedBufferSizeContext; pub use managed_byte_array::ManagedByteArray; pub use managed_decimal::{ConstDecimals, Decimals, ManagedDecimal, NumDecimals}; @@ -35,8 +38,15 @@ pub use managed_option::ManagedOption; pub use managed_ref::ManagedRef; pub use managed_vec::ManagedVec; pub use managed_vec_item::ManagedVecItem; +pub use managed_vec_item_nested_tuple::ManagedVecItemNestedTuple; +pub use managed_vec_item_payload::*; pub use managed_vec_owned_iter::ManagedVecOwnedIterator; pub use managed_vec_ref::ManagedVecRef; pub use managed_vec_ref_iter::ManagedVecRefIterator; pub use randomness_source::RandomnessSource; pub use token_identifier::TokenIdentifier; + +pub use traits::{ + fixed_token_supply::FixedSupplyToken, + mergeable::{ExternallyMergeable, Mergeable}, +}; diff --git a/framework/base/src/types/managed/wrapped/token_identifier.rs b/framework/base/src/types/managed/wrapped/token_identifier.rs index 2e5a27020c..1e66615199 100644 --- a/framework/base/src/types/managed/wrapped/token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/token_identifier.rs @@ -1,7 +1,7 @@ use alloc::string::ToString; use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ErrorApi, ErrorApiImpl, HandleConstraints, ManagedTypeApi, ManagedTypeApiImpl}, codec::*, err_msg, @@ -71,9 +71,9 @@ impl TokenIdentifier { pub fn ticker(&self) -> ManagedBuffer { let token_id_len = self.buffer.len(); let ticker_len = M::managed_type_impl().get_token_ticker_len(token_id_len); - self.buffer - .copy_slice(0, ticker_len) - .unwrap_or_else(|| M::error_api_impl().signal_error(err_msg::BAD_TOKEN_TICKER_FORMAT)) + self.buffer.copy_slice(0, ticker_len).unwrap_or_else(|| { + M::error_api_impl().signal_error(err_msg::BAD_TOKEN_TICKER_FORMAT.as_bytes()) + }) } } @@ -98,6 +98,12 @@ impl From<&str> for TokenIdentifier { } } +impl From<&crate::types::heap::String> for TokenIdentifier { + fn from(s: &crate::types::heap::String) -> Self { + TokenIdentifier::from(s.as_bytes()) + } +} + impl PartialEq for TokenIdentifier { #[inline] fn eq(&self, other: &Self) -> bool { @@ -111,8 +117,9 @@ impl PartialEq> for TokenIdentif #[inline] fn eq(&self, other: &EgldOrEsdtTokenIdentifier) -> bool { other.map_ref_or_else( - || false, - |esdt_token_identifier| esdt_token_identifier == self, + (), + |()| false, + |(), esdt_token_identifier| esdt_token_identifier == self, ) } } @@ -163,16 +170,22 @@ impl TopDecode for TokenIdentifier { } } -impl CodecFromSelf for TokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom<&[u8]> for TokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom> for TokenIdentifier where M: ManagedTypeApi {} -impl CodecFrom<&[u8]> for TokenIdentifier where M: ManagedTypeApi {} - -impl CodecFrom> for TokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom for TokenIdentifier {} +impl TypeAbiFrom<&Self> for TokenIdentifier {} impl TypeAbi for TokenIdentifier { + type Unmanaged = Self; + fn type_name() -> TypeName { "TokenIdentifier".into() } + + fn type_name_rust() -> TypeName { + "TokenIdentifier<$API>".into() + } } impl SCDisplay for TokenIdentifier { diff --git a/framework/base/src/types/managed/wrapped/traits/fixed_token_supply.rs b/framework/base/src/types/managed/wrapped/traits/fixed_token_supply.rs new file mode 100644 index 0000000000..0b94cbbf6b --- /dev/null +++ b/framework/base/src/types/managed/wrapped/traits/fixed_token_supply.rs @@ -0,0 +1,34 @@ +use crate::{ + api::{ErrorApiImpl, ManagedTypeApi}, + types::BigUint, +}; + +pub trait FixedSupplyToken { + fn get_total_supply(&self) -> BigUint; + + fn into_part(self, payment_amount: &BigUint) -> Self; + + /// full_value * current_supply / total_supply + fn rule_of_three(&self, current_supply: &BigUint, full_value: &BigUint) -> BigUint { + let total_supply = self.get_total_supply(); + if current_supply == &total_supply { + return full_value.clone(); + } + + (full_value * current_supply) / total_supply + } + + /// full_value * current_supply / total_supply + fn rule_of_three_non_zero_result( + &self, + current_supply: &BigUint, + full_value: &BigUint, + ) -> BigUint { + let result = self.rule_of_three(current_supply, full_value); + if result == 0 { + M::error_api_impl().signal_error(b"Zero amount"); + } + + result + } +} diff --git a/framework/base/src/types/managed/wrapped/traits/mergeable.rs b/framework/base/src/types/managed/wrapped/traits/mergeable.rs new file mode 100644 index 0000000000..51298ba130 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/traits/mergeable.rs @@ -0,0 +1,65 @@ +use crate::{ + api::{ErrorApiImpl, ManagedTypeApi}, + types::{EsdtTokenPayment, ManagedVec, ManagedVecItem}, +}; + +pub static CANNOT_MERGE_ERR_MSG: &[u8] = b"Cannot merge"; + +/// Used for types that can be merged locally. +pub trait Mergeable { + fn error_if_not_mergeable(&self, other: &Self) { + if !self.can_merge_with(other) { + throw_not_mergeable_error::(); + } + } + + fn can_merge_with(&self, other: &Self) -> bool; + + fn merge_with(&mut self, other: Self); + + fn merge_with_multiple(&mut self, others: ManagedVec) + where + Self: Sized + ManagedVecItem, + { + for item in &others { + self.merge_with(item); + } + } +} + +/// Used when merging is done through an external SC call. +/// Generally, these only need to have the same token ID, with different nonces. +pub trait ExternallyMergeable { + fn error_if_not_externally_mergeable(&self, other: &Self) { + if !self.can_be_merged_externally_with(other) { + throw_not_mergeable_error::(); + } + } + + fn can_be_merged_externally_with(&self, other: &Self) -> bool; +} + +pub fn throw_not_mergeable_error() -> ! { + M::error_api_impl().signal_error(CANNOT_MERGE_ERR_MSG); +} + +impl Mergeable for EsdtTokenPayment { + fn can_merge_with(&self, other: &Self) -> bool { + let same_token_id = self.token_identifier == other.token_identifier; + let same_token_nonce = self.token_nonce == other.token_nonce; + + same_token_id && same_token_nonce + } + + fn merge_with(&mut self, other: Self) { + self.error_if_not_mergeable(&other); + + self.amount += other.amount; + } +} + +impl ExternallyMergeable for EsdtTokenPayment { + fn can_be_merged_externally_with(&self, other: &Self) -> bool { + self.token_identifier == other.token_identifier + } +} diff --git a/framework/base/src/types/managed/wrapped/traits/mod.rs b/framework/base/src/types/managed/wrapped/traits/mod.rs new file mode 100644 index 0000000000..2a9f147fdc --- /dev/null +++ b/framework/base/src/types/managed/wrapped/traits/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod fixed_token_supply; +pub(crate) mod mergeable; diff --git a/framework/base/src/types/static_buffer/sparse_array.rs b/framework/base/src/types/static_buffer/sparse_array.rs index 2c6ddd61e2..bb3a083243 100644 --- a/framework/base/src/types/static_buffer/sparse_array.rs +++ b/framework/base/src/types/static_buffer/sparse_array.rs @@ -1,5 +1,7 @@ +use alloc::format; + use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::{ErrorApi, ErrorApiImpl}, codec::{self, arrayvec::ArrayVec, NestedDecode, NestedEncode, TopDecode, TopEncode}, }; @@ -302,15 +304,24 @@ where } } +impl TypeAbiFrom for SparseArray where E: ErrorApi {} +impl TypeAbiFrom<&Self> for SparseArray where E: ErrorApi {} + impl TypeAbi for SparseArray where E: ErrorApi, { + type Unmanaged = Self; + /// It is semantically equivalent to any list of `usize`. fn type_name() -> TypeName { <&[usize] as TypeAbi>::type_name() } + fn type_name_rust() -> TypeName { + format!("SparseArray<$API, {CAPACITY}usize>") + } + fn provide_type_descriptions(accumulator: &mut TDC) { usize::provide_type_descriptions(accumulator); } diff --git a/framework/derive/Cargo.toml b/framework/derive/Cargo.toml index 490cccf7d8..ef10f1f2fa 100644 --- a/framework/derive/Cargo.toml +++ b/framework/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-derive" -version = "0.47.5" +version = "0.50.3" edition = "2021" authors = ["Andrei Marinica ", "MultiversX "] @@ -14,9 +14,9 @@ keywords = ["multiversx", "blockchain", "contract"] categories = ["cryptography::cryptocurrencies", "development-tools::procedural-macro-helpers"] [dependencies] -proc-macro2 = "=1.0.78" -quote = "=1.0.35" -syn = "=2.0.48" +proc-macro2 = "=1.0.82" +quote = "=1.0.36" +syn = "=2.0.61" hex = "=0.4.3" radix_trie = "=0.2.1" diff --git a/framework/derive/src/format/format_args_macro.rs b/framework/derive/src/format/format_args_macro.rs index 5e0ea07b63..080edf5bab 100644 --- a/framework/derive/src/format/format_args_macro.rs +++ b/framework/derive/src/format/format_args_macro.rs @@ -1,21 +1,21 @@ -use proc_macro::quote; +use quote::quote; use crate::{format::format_tokenize, generate::util::byte_str_literal}; use super::{count_args, parse_format_string, FormatPartType}; -pub fn format_receiver_args_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub fn format_receiver_args_macro(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream { let tokens = format_tokenize::tokenize(input); assert!( tokens.len() > 2, "format_receiver_args macro requires at least 2 arguments" ); let num_arguments = tokens.len() - 2; - let mut tokens_iter = tokens.into_iter(); + let mut tokens_iter: std::vec::IntoIter = tokens.into_iter(); let accumulator_expr = tokens_iter.next().unwrap(); let format_string_token = tokens_iter.next().unwrap(); - let format_string = if let proc_macro::TokenTree::Literal(lit) = format_string_token { + let format_string = if let proc_macro2::TokenTree::Literal(lit) = format_string_token { lit.to_string() } else { panic!( @@ -30,37 +30,45 @@ pub fn format_receiver_args_macro(input: proc_macro::TokenStream) -> proc_macro: "Number of placeholders ({num_placeholders}) does not match number of arguments ({num_arguments})." ); + format_tokens(format_str_parts, accumulator_expr, tokens_iter) +} + +fn format_tokens( + format_str_parts: Vec, + accumulator_expr: proc_macro2::TokenTree, + mut tokens_iter: std::vec::IntoIter, +) -> proc_macro2::TokenStream { format_str_parts.into_iter().map(|part| { match part { FormatPartType::StaticAscii(ascii_string) => { let str_as_bytes = byte_str_literal(ascii_string.as_bytes()); - quote! ( - multiversx_sc::formatter::FormatBuffer::append_ascii(&mut $accumulator_expr, $str_as_bytes); - ) + quote! { + multiversx_sc::formatter::FormatBuffer::append_ascii(&mut #accumulator_expr, #str_as_bytes); + } }, FormatPartType::Display => { let arg_expr = tokens_iter.next().unwrap(); - quote! ( - multiversx_sc::formatter::FormatBuffer::append_display(&mut $accumulator_expr, &$arg_expr); - ) + quote! { + multiversx_sc::formatter::FormatBuffer::append_display(&mut #accumulator_expr, &#arg_expr); + } }, FormatPartType::LowerHex => { let arg_expr = tokens_iter.next().unwrap(); - quote! ( - multiversx_sc::formatter::FormatBuffer::append_lower_hex(&mut $accumulator_expr, &$arg_expr); - ) + quote! { + multiversx_sc::formatter::FormatBuffer::append_lower_hex(&mut #accumulator_expr, &#arg_expr); + } }, FormatPartType::Codec => { let arg_expr = tokens_iter.next().unwrap(); - quote! ( - multiversx_sc::formatter::FormatBuffer::append_codec(&mut $accumulator_expr, &$arg_expr); - ) + quote! { + multiversx_sc::formatter::FormatBuffer::append_codec(&mut #accumulator_expr, &#arg_expr); + } }, FormatPartType::Bytes => { let arg_expr = tokens_iter.next().unwrap(); - quote! ( - multiversx_sc::formatter::FormatBuffer::append_binary(&mut $accumulator_expr, &$arg_expr); - ) + quote! { + multiversx_sc::formatter::FormatBuffer::append_binary(&mut #accumulator_expr, &#arg_expr); + } }, } }).collect() diff --git a/framework/derive/src/format/format_tokenize.rs b/framework/derive/src/format/format_tokenize.rs index 1e8dfe0bfb..2e9beb4294 100644 --- a/framework/derive/src/format/format_tokenize.rs +++ b/framework/derive/src/format/format_tokenize.rs @@ -1,7 +1,7 @@ -use proc_macro::Group; +use proc_macro2::Group; -fn token_tree_is_comma(tt: &proc_macro::TokenTree) -> bool { - if let proc_macro::TokenTree::Punct(punct) = &tt { +fn token_tree_is_comma(tt: &proc_macro2::TokenTree) -> bool { + if let proc_macro2::TokenTree::Punct(punct) = &tt { punct.as_char() == ',' } else { false @@ -9,20 +9,20 @@ fn token_tree_is_comma(tt: &proc_macro::TokenTree) -> bool { } fn flush_token_buffer( - output: &mut Vec, - mut buffer: Vec, + output: &mut Vec, + mut buffer: Vec, ) { match buffer.len() { 0 => panic!("empty tokens not allowed in push_format macro"), 1 => output.append(&mut buffer), - _ => output.push(proc_macro::TokenTree::Group(Group::new( - proc_macro::Delimiter::Parenthesis, + _ => output.push(proc_macro2::TokenTree::Group(Group::new( + proc_macro2::Delimiter::Parenthesis, buffer.into_iter().collect(), ))), } } -pub fn tokenize(input: proc_macro::TokenStream) -> Vec { +pub fn tokenize(input: proc_macro2::TokenStream) -> Vec { let mut buffer = Vec::new(); let mut output = Vec::new(); for tt in input.into_iter() { diff --git a/framework/derive/src/format/semver_tuple.rs b/framework/derive/src/format/semver_tuple.rs index e4c3c33fcc..f10036a973 100644 --- a/framework/derive/src/format/semver_tuple.rs +++ b/framework/derive/src/format/semver_tuple.rs @@ -1,37 +1,38 @@ -use proc_macro::{quote, Literal}; +use quote::quote; use crate::format::format_tokenize; -pub fn semver_tuple(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let tokens: Vec = format_tokenize::tokenize(input); - - tokens - .iter() - .map(|token| match token { - proc_macro::TokenTree::Group(lit) => { - let format_string = lit.stream().to_string(); - - let version_tokens: Vec<&str> = format_string.split('.').collect(); - assert!( - version_tokens.len() == 3, - "The argument does not have the required format." - ); - - let major = u64_literal_from_str(version_tokens[0]); - let minor = u64_literal_from_str(version_tokens[1]); - let patch = u64_literal_from_str(version_tokens[2]); - - quote!( - ($major, $minor, $patch) - ) - }, - _ => panic!("Tokentree does not match with the requirements"), - }) - .collect() +pub fn semver_tuple(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream { + let tokens = format_tokenize::tokenize(input); + + tokens.iter().map(convert_token_tree).collect() +} + +fn convert_token_tree(token: &proc_macro2::TokenTree) -> proc_macro2::TokenStream { + match token { + proc_macro2::TokenTree::Group(lit) => { + let format_string = lit.stream().to_string(); + + let version_tokens: Vec<&str> = format_string.split('.').collect(); + assert!( + version_tokens.len() == 3, + "The argument does not have the required format." + ); + + let major = u64_literal_from_str(version_tokens[0]); + let minor = u64_literal_from_str(version_tokens[1]); + let patch = u64_literal_from_str(version_tokens[2]); + + quote! { + (#major, #minor, #patch) + } + }, + _ => panic!("Tokentree does not match with the requirements"), + } } -fn u64_literal_from_str(s: &str) -> proc_macro::TokenTree { - proc_macro::TokenTree::Literal(Literal::u64_suffixed( +fn u64_literal_from_str(s: &str) -> proc_macro2::TokenTree { + proc_macro2::TokenTree::Literal(proc_macro2::Literal::u64_suffixed( s.parse().expect("failed to parse token as u64"), )) } diff --git a/framework/derive/src/generate/abi_gen.rs b/framework/derive/src/generate/abi_gen.rs index df8755ded7..5d5a73934c 100644 --- a/framework/derive/src/generate/abi_gen.rs +++ b/framework/derive/src/generate/abi_gen.rs @@ -91,6 +91,21 @@ fn generate_endpoint_snippets(contract: &ContractTrait) -> Vec { + let endpoint_def = generate_endpoint_snippet( + m, + "upgrade", + false, + false, + EndpointMutabilityMetadata::Mutable, + EndpointTypeMetadata::Upgrade, + m.is_allow_multiple_var_args(), + ); + Some(quote! { + #endpoint_def + contract_abi.upgrade_constructors.push(endpoint_abi); + }) + }, PublicRole::Endpoint(endpoint_metadata) => { let endpoint_def = generate_endpoint_snippet( m, @@ -182,15 +197,15 @@ fn has_callback(contract: &ContractTrait) -> bool { fn generate_supertrait_snippets(contract: &ContractTrait) -> Vec { contract - .supertraits - .iter() - .map(|supertrait| { - let module_path = &supertrait.module_path; - quote! { - contract_abi.coalesce(<#module_path AbiProvider as multiversx_sc::contract_base::ContractAbiProvider>::abi()); - } - }) - .collect() + .supertraits + .iter() + .map(|supertrait| { + let module_path = &supertrait.module_path; + quote! { + contract_abi.coalesce(<#module_path AbiProvider as multiversx_sc::contract_base::ContractAbiProvider>::abi()); + } + }) + .collect() } fn generate_esdt_attribute_snippets(contract: &ContractTrait) -> Vec { diff --git a/framework/derive/src/generate/auto_impl_proxy.rs b/framework/derive/src/generate/auto_impl_proxy.rs index 7590b57b63..33c36724ca 100644 --- a/framework/derive/src/generate/auto_impl_proxy.rs +++ b/framework/derive/src/generate/auto_impl_proxy.rs @@ -3,7 +3,8 @@ use crate::{ model::{AutoImpl, ContractTrait, Method, MethodImpl}, parse::split_path_last, }; -use syn::{punctuated::Punctuated, token::PathSep}; +use proc_macro2::Ident; +use syn::{punctuated::Punctuated, token::PathSep, Pat}; /// Path to a Rust module containing a contract call proxy. pub type ProxyModulePath = Punctuated; @@ -34,19 +35,37 @@ pub fn proxy_getter_return_type(m: &Method) -> ProxyGetterReturnType { } } -fn proxy_getter_address_snippet(m: &Method) -> proc_macro2::TokenStream { +pub fn proxy_getter_return_type_token(m: &Method) -> proc_macro2::TokenStream { + let ProxyGetterReturnType { + module_path, + mut proxy_obj_name, + } = proxy_getter_return_type(m); + if proxy_getter_address_arg_name(m).is_some() { + // replace type name + let span = proxy_obj_name.ident.span(); // preserve span + proxy_obj_name.ident = Ident::new("ProxyTo", span); + } + quote! { #module_path #proxy_obj_name} +} + +fn proxy_getter_address_arg_name(m: &Method) -> Option { match m.method_args.len() { - 0 => quote! {}, - 1 => { - let address_arg_name = &m.method_args[0].pat; - quote! { - .contract(#address_arg_name) - } - }, + 0 => None, + 1 => Some(m.method_args[0].pat.clone()), _ => panic!("Proxy getter can have at most 1 argument, which is the target address"), } } +fn proxy_getter_address_snippet(m: &Method) -> proc_macro2::TokenStream { + if let Some(address_arg_name) = proxy_getter_address_arg_name(m) { + quote! { + .contract(#address_arg_name) + } + } else { + quote! {} + } +} + pub fn generate_proxy_getter_impl(m: &Method) -> proc_macro2::TokenStream { let msig = method_gen::generate_sig_with_attributes(m); let parsed_return_type = proxy_getter_return_type(m); @@ -55,7 +74,7 @@ pub fn generate_proxy_getter_impl(m: &Method) -> proc_macro2::TokenStream { quote! { #msig { - #module_path Proxy::new_proxy_obj() #address_snippet + <#module_path Proxy as multiversx_sc::contract_base::ProxyObjNew>::new_proxy_obj() #address_snippet } } } diff --git a/framework/derive/src/generate/callback_gen.rs b/framework/derive/src/generate/callback_gen.rs index 5d1cda744f..23a3a56713 100644 --- a/framework/derive/src/generate/callback_gen.rs +++ b/framework/derive/src/generate/callback_gen.rs @@ -48,10 +48,10 @@ pub fn generate_callback_selector_and_main( let cb_main_body = quote! { if let Some(___cb_closure___) = multiversx_sc::types::CallbackClosureForDeser::storage_load_and_clear::() { if let multiversx_sc::types::CallbackSelectorResult::NotProcessed(_) = - self::EndpointWrappers::callback_selector(self, ___cb_closure___) { + self::EndpointWrappers::callback_selector(self, ___cb_closure___) { multiversx_sc::api::ErrorApiImpl::signal_error( &::error_api_impl(), - err_msg::CALLBACK_BAD_FUNC, + err_msg::CALLBACK_BAD_FUNC.as_bytes(), ); } } diff --git a/framework/derive/src/generate/contract_gen.rs b/framework/derive/src/generate/contract_gen.rs index 6d3cf620e6..ba7ace5879 100644 --- a/framework/derive/src/generate/contract_gen.rs +++ b/framework/derive/src/generate/contract_gen.rs @@ -28,6 +28,7 @@ pub fn generate_call_methods(contract_trait: &ContractTrait) -> Vec Some(generate_call_method(m)), + PublicRole::Upgrade(_upgrade_metadata) => Some(generate_call_method(m)), PublicRole::Endpoint(_endpoint_metadata) => Some(generate_call_method(m)), PublicRole::CallbackPromise(_callback_metadata) => { Some(generate_promises_callback_call_method(m)) diff --git a/framework/derive/src/generate/endpoints_mod_gen.rs b/framework/derive/src/generate/endpoints_mod_gen.rs index 5f780f0c4a..b32a7ce9a8 100644 --- a/framework/derive/src/generate/endpoints_mod_gen.rs +++ b/framework/derive/src/generate/endpoints_mod_gen.rs @@ -67,6 +67,7 @@ fn generate_wasm_endpoints(contract_trait: &ContractTrait) -> Vec Some(generate_wasm_endpoint(m, "e! { init })), + PublicRole::Upgrade(_) => Some(generate_wasm_endpoint(m, "e! { upgrade })), PublicRole::Endpoint(endpoint_metadata) => { let endpoint_ident = &endpoint_metadata.public_name; Some(generate_wasm_endpoint(m, "e! { #endpoint_ident })) diff --git a/framework/derive/src/generate/function_selector.rs b/framework/derive/src/generate/function_selector.rs index d49a673d71..6f157724f8 100644 --- a/framework/derive/src/generate/function_selector.rs +++ b/framework/derive/src/generate/function_selector.rs @@ -27,6 +27,11 @@ pub fn generate_function_selector_body(contract: &ContractTrait) -> proc_macro2: "init", quote! { if !::external_view_init_override() }, )), + PublicRole::Upgrade(_) => Some(endpoint_match_arm( + m, + "upgrade", + quote! {}, + )), PublicRole::Endpoint(endpoint_metadata) => Some(endpoint_match_arm( m, endpoint_metadata.public_name.to_string().as_str(), diff --git a/framework/derive/src/generate/method_gen.rs b/framework/derive/src/generate/method_gen.rs index dc979fe300..88de2bd30a 100644 --- a/framework/derive/src/generate/method_gen.rs +++ b/framework/derive/src/generate/method_gen.rs @@ -1,4 +1,6 @@ -use crate::model::{Method, MethodArgument}; +use crate::model::{AutoImpl, Method, MethodArgument, MethodImpl}; + +use super::auto_impl_proxy::proxy_getter_return_type_token; pub fn arg_declarations(method_args: &[MethodArgument]) -> Vec { method_args @@ -17,10 +19,7 @@ pub fn generate_sig(m: &Method) -> proc_macro2::TokenStream { let generics = &m.generics; let generics_where = &m.generics.where_clause; let arg_decl = arg_declarations(&m.method_args); - let ret_tok = match &m.return_type { - syn::ReturnType::Default => quote! {}, - syn::ReturnType::Type(r_arrow_token, ty) => quote! { #r_arrow_token #ty }, - }; + let ret_tok = generate_sig_return(m); let result = quote! { #[allow(clippy::too_many_arguments)] #[allow(clippy::type_complexity)] @@ -29,6 +28,18 @@ pub fn generate_sig(m: &Method) -> proc_macro2::TokenStream { result } +pub fn generate_sig_return(m: &Method) -> proc_macro2::TokenStream { + if let MethodImpl::Generated(AutoImpl::ProxyGetter) = &m.implementation { + let proxy_ret_tok = proxy_getter_return_type_token(m); + return quote! { -> #proxy_ret_tok }; + } + + match &m.return_type { + syn::ReturnType::Default => quote! {}, + syn::ReturnType::Type(r_arrow_token, ty) => quote! { #r_arrow_token #ty }, + } +} + pub fn generate_sig_with_attributes(m: &Method) -> proc_macro2::TokenStream { let unprocessed_attributes = &m.unprocessed_attributes; let msig = generate_sig(m); diff --git a/framework/derive/src/generate/proxy_gen.rs b/framework/derive/src/generate/proxy_gen.rs index bc44d03b95..81b416c009 100644 --- a/framework/derive/src/generate/proxy_gen.rs +++ b/framework/derive/src/generate/proxy_gen.rs @@ -46,26 +46,29 @@ pub fn proxy_arg_gen( pub fn generate_proxy_method_sig( method: &Method, - proxy_return_struct_path: proc_macro2::TokenStream, + return_type: proc_macro2::TokenStream, ) -> proc_macro2::TokenStream { let method_name = &method.name; let mut generics = method.generics.clone(); let generics_where = &method.generics.where_clause; let arg_decl = proxy_arg_gen(&method.method_args, &mut generics); - let ret_tok = match &method.return_type { - syn::ReturnType::Default => quote! { () }, - syn::ReturnType::Type(_, ty) => quote! { #ty }, - }; let result = quote! { fn #method_name #generics ( &mut self, #(#arg_decl),* - ) -> #proxy_return_struct_path + ) -> #return_type #generics_where }; result } +fn original_type_tokens(m: &Method) -> proc_macro2::TokenStream { + match &m.return_type { + syn::ReturnType::Default => quote! { () }, + syn::ReturnType::Type(_, ty) => quote! { #ty }, + } +} + pub fn generate_proxy_endpoint(m: &Method, endpoint_name: String) -> proc_macro2::TokenStream { let mut token_count = 0; let mut token_expr = @@ -84,7 +87,7 @@ pub fn generate_proxy_endpoint(m: &Method, endpoint_name: String) -> proc_macro2 ArgPaymentMetadata::NotPayment => { let pat = &arg.pat; arg_push_snippets.push(quote! { - multiversx_sc::types::ContractCall::proxy_arg(&mut ___contract_call___, &#pat); + .argument(&#pat) }); }, ArgPaymentMetadata::PaymentToken => { @@ -127,62 +130,58 @@ pub fn generate_proxy_endpoint(m: &Method, endpoint_name: String) -> proc_macro2 "No more than one payment multi argument allowed in call proxy" ); - let contract_call_type; - let contract_call_init; + let payment_type; + let payment_init; if token_count > 0 || nonce_count > 0 || payment_count > 0 { assert!(multi_count == 0, "#[payment_multi] cannot coexist with any other payment annotation in the same endpoint"); if token_count == 0 && nonce_count == 0 { - contract_call_type = quote! { multiversx_sc::types::ContractCallWithEgld }; - contract_call_init = quote! { - let mut ___contract_call___ = multiversx_sc::types::ContractCallWithEgld::new( - ___address___, - #endpoint_name, - #payment_expr, - ); - }; + payment_type = quote! { multiversx_sc::types::EgldPayment }; + payment_init = quote! { .egld(#payment_expr) }; } else { - contract_call_type = quote! { multiversx_sc::types::ContractCallWithEgldOrSingleEsdt }; - contract_call_init = quote! { - let mut ___contract_call___ = multiversx_sc::types::ContractCallWithEgldOrSingleEsdt::new( - ___address___, - #endpoint_name, + payment_type = quote! { multiversx_sc::types::EgldOrEsdtTokenPayment }; + payment_init = quote! { .payment( + multiversx_sc::types::EgldOrEsdtTokenPayment::new( #token_expr, #nonce_expr, #payment_expr, - ); - }; + ) + )}; } } else if multi_count > 0 { let multi_expr = multi_expr_opt.unwrap(); - contract_call_type = quote! { multiversx_sc::types::ContractCallWithMultiEsdt }; - contract_call_init = quote! { - let mut ___contract_call___ = multiversx_sc::types::ContractCallWithMultiEsdt::new( - ___address___, - #endpoint_name, - #multi_expr.clone_value(), - ); - }; + payment_type = quote! { MultiEsdtPayment }; + payment_init = quote! { .multi_esdt(#multi_expr.clone_value()) }; } else { - contract_call_type = quote! { multiversx_sc::types::ContractCallNoPayment }; - contract_call_init = quote! { - let mut ___contract_call___ = multiversx_sc::types::ContractCallNoPayment::new( - ___address___, - #endpoint_name, - ); - }; + payment_type = quote! { () }; + payment_init = quote! {}; } - let msig = generate_proxy_method_sig(m, contract_call_type); + let original_type = original_type_tokens(m); + let return_type = quote! { + multiversx_sc::types::Tx< + multiversx_sc::types::TxScEnv, + (), + Self::To, + #payment_type, + (), + multiversx_sc::types::FunctionCall, + multiversx_sc::types::OriginalResultMarker<#original_type>, + > + }; + + let msig = generate_proxy_method_sig(m, return_type); let sig = quote! { #[allow(clippy::too_many_arguments)] #[allow(clippy::type_complexity)] #msig { - let ___address___ = self.extract_address(); - #contract_call_init - #(#arg_push_snippets)* - ___contract_call___ + multiversx_sc::types::TxBaseWithEnv::new_tx_from_sc() + .to(self.extract_proxy_to()) + .original_result() + .raw_call(#endpoint_name) + #payment_init + #(#arg_push_snippets)* } }; @@ -190,50 +189,41 @@ pub fn generate_proxy_endpoint(m: &Method, endpoint_name: String) -> proc_macro2 } pub fn generate_proxy_deploy(init_method: &Method) -> proc_macro2::TokenStream { - let msig = - generate_proxy_method_sig(init_method, quote! { multiversx_sc::types::ContractDeploy }); - let mut payment_count = 0; let mut multi_count = 0; let mut token_count = 0; let mut nonce_count = 0; - let arg_push_snippets: Vec = init_method - .method_args - .iter() - .map(|arg| match &arg.metadata.payment { + let mut payment_type = quote! { () }; + let mut payment_init = quote! {}; + + let mut arg_push_snippets = Vec::::new(); + + for arg in &init_method.method_args { + match &arg.metadata.payment { ArgPaymentMetadata::NotPayment => { let pat = &arg.pat; - quote! { - ___contract_deploy___.push_endpoint_arg(&#pat); - } + arg_push_snippets.push(quote! { + .argument(&#pat) + }); }, ArgPaymentMetadata::PaymentToken => { token_count += 1; - - quote! {} }, ArgPaymentMetadata::PaymentNonce => { nonce_count += 1; - - quote! {} }, ArgPaymentMetadata::PaymentAmount => { payment_count += 1; - let pat = &arg.pat; - quote! { - ___contract_deploy___ = ___contract_deploy___.with_egld_transfer(#pat); - } + let payment_expr = &arg.pat; + payment_type = quote! { multiversx_sc::types::EgldPayment }; + payment_init = quote! { .egld(#payment_expr) }; }, ArgPaymentMetadata::PaymentMulti => { multi_count += 1; - let pat = &arg.pat; - quote! { - ___contract_deploy___ = ___contract_deploy___.with_multi_token_transfer(#pat); - } }, - }) - .collect(); + } + } assert!( payment_count <= 1, @@ -241,17 +231,36 @@ pub fn generate_proxy_deploy(init_method: &Method) -> proc_macro2::TokenStream { ); assert!(token_count == 0, "No ESDT payment allowed in #[init]"); assert!(nonce_count == 0, "No SFT/NFT payment allowed in #[init]"); + assert!( + multi_count == 0, + "No multi ESDT payments allowed in #[init]" + ); + + let original_type = original_type_tokens(init_method); + let return_type = quote! { + multiversx_sc::types::Tx< + multiversx_sc::types::TxScEnv, + (), + Self::To, // still accepted, until we separate the upgrade constructor completely + #payment_type, + (), + multiversx_sc::types::DeployCall, ()>, + multiversx_sc::types::OriginalResultMarker<#original_type>, + > + }; + + let msig = generate_proxy_method_sig(init_method, return_type); let sig = quote! { #[allow(clippy::too_many_arguments)] #[allow(clippy::type_complexity)] #msig { - let ___opt_address___ = self.extract_opt_address(); - let mut ___contract_deploy___ = multiversx_sc::types::new_contract_deploy( - ___opt_address___, - ); - #(#arg_push_snippets)* - ___contract_deploy___ + multiversx_sc::types::TxBaseWithEnv::new_tx_from_sc() + .raw_deploy() + #payment_init + #(#arg_push_snippets)* + .original_result() + .to(self.extract_proxy_to()) // still accepted, until we separate the upgrade constructor completely } }; @@ -264,6 +273,7 @@ pub fn generate_method_impl(contract_trait: &ContractTrait) -> Vec Some(generate_proxy_deploy(m)), + PublicRole::Upgrade(_) => Some(generate_proxy_endpoint(m, "upgrade".to_string())), PublicRole::Endpoint(endpoint_metadata) => Some(generate_proxy_endpoint( m, endpoint_metadata.public_name.to_string(), @@ -303,7 +313,7 @@ fn equivalent_encode_path_gen(ty: &syn::Type) -> syn::Path { let owned_type = convert_to_owned_type(ty); syn::parse_str( format!( - "multiversx_sc::codec::CodecInto<{}>", + "multiversx_sc::types::ProxyArg<{}>", owned_type.to_token_stream() ) .as_str(), diff --git a/framework/derive/src/generate/snippets.rs b/framework/derive/src/generate/snippets.rs index 6c1751a187..6e66eb9ae4 100644 --- a/framework/derive/src/generate/snippets.rs +++ b/framework/derive/src/generate/snippets.rs @@ -79,7 +79,7 @@ pub fn proxy_object_def() -> proc_macro2::TokenStream { where A: multiversx_sc::api::VMApi + 'static, { - pub address: multiversx_sc::types::ManagedOption>, + _phantom: core::marker::PhantomData, } impl multiversx_sc::contract_base::ProxyObjBase for Proxy @@ -87,17 +87,60 @@ pub fn proxy_object_def() -> proc_macro2::TokenStream { A: multiversx_sc::api::VMApi + 'static, { type Api = A; + type To = (); + + fn extract_opt_address( + &mut self, + ) -> multiversx_sc::types::ManagedOption< + Self::Api, + multiversx_sc::types::ManagedAddress, + > { + multiversx_sc::types::ManagedOption::none() + } + + fn extract_address(&mut self) -> multiversx_sc::types::ManagedAddress { + multiversx_sc::api::ErrorApiImpl::signal_error( + &::error_api_impl(), + multiversx_sc::err_msg::RECIPIENT_ADDRESS_NOT_SET.as_bytes(), + ) + } + + fn extract_proxy_to(&mut self) -> Self::To {} + } + + impl multiversx_sc::contract_base::ProxyObjNew for Proxy + where + A: multiversx_sc::api::VMApi + 'static, + { + type ProxyTo = ProxyTo; fn new_proxy_obj() -> Self { Proxy { - address: multiversx_sc::types::ManagedOption::none(), + _phantom: core::marker::PhantomData, } } - fn contract(mut self, address: multiversx_sc::types::ManagedAddress) -> Self { - self.address = multiversx_sc::types::ManagedOption::some(address); - self + fn contract(mut self, address: multiversx_sc::types::ManagedAddress) -> Self::ProxyTo { + ProxyTo { + address: multiversx_sc::types::ManagedOption::some(address) + } } + } + + pub struct ProxyTo + where + A: multiversx_sc::api::VMApi + 'static, + { + pub address: + multiversx_sc::types::ManagedOption>, + } + + impl multiversx_sc::contract_base::ProxyObjBase for ProxyTo + where + A: multiversx_sc::api::VMApi + 'static, + { + type Api = A; + type To = multiversx_sc::types::ManagedAddress; fn extract_opt_address( &mut self, @@ -105,11 +148,22 @@ pub fn proxy_object_def() -> proc_macro2::TokenStream { Self::Api, multiversx_sc::types::ManagedAddress, > { - core::mem::replace(&mut self.address, multiversx_sc::types::ManagedOption::none()) + core::mem::replace( + &mut self.address, + multiversx_sc::types::ManagedOption::none(), + ) } fn extract_address(&mut self) -> multiversx_sc::types::ManagedAddress { - self.extract_opt_address().unwrap_or_sc_panic(multiversx_sc::err_msg::RECIPIENT_ADDRESS_NOT_SET) + let address = core::mem::replace( + &mut self.address, + multiversx_sc::types::ManagedOption::none(), + ); + address.unwrap_or_sc_panic(multiversx_sc::err_msg::RECIPIENT_ADDRESS_NOT_SET) + } + + fn extract_proxy_to(&mut self) -> Self::To { + self.extract_address() } } } diff --git a/framework/derive/src/generate/supertrait_gen.rs b/framework/derive/src/generate/supertrait_gen.rs index de5ba0f393..3d12cbb913 100644 --- a/framework/derive/src/generate/supertrait_gen.rs +++ b/framework/derive/src/generate/supertrait_gen.rs @@ -135,6 +135,7 @@ pub fn function_selector_module_calls(supertraits: &[Supertrait]) -> Vec proc_macro2::TokenStream { quote! { impl #module_path ProxyTrait for Proxy where A: multiversx_sc::api::VMApi {} + impl #module_path ProxyTrait for ProxyTo where A: multiversx_sc::api::VMApi {} } } diff --git a/framework/derive/src/lib.rs b/framework/derive/src/lib.rs index a68d493c97..7f32bb2133 100644 --- a/framework/derive/src/lib.rs +++ b/framework/derive/src/lib.rs @@ -1,7 +1,5 @@ -#![allow(stable_features)] // ensure we don't run out of macro stack #![recursion_limit = "1024"] -#![feature(proc_macro_quote)] #[macro_use] extern crate syn; @@ -48,8 +46,16 @@ pub fn proxy( #[proc_macro_derive(TypeAbi)] pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let ast = syn::parse(input).unwrap(); - type_abi_derive::type_abi_derive(&ast) + type_abi_derive::type_abi_derive(input).into() +} + +#[proc_macro_attribute] +pub fn type_abi( + args: proc_macro::TokenStream, + input: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + assert!(args.is_empty(), "#[type_abi] attribute takes no args"); + type_abi_derive::type_abi_full(input).into() } #[proc_macro_derive(ManagedVecItem)] @@ -60,10 +66,10 @@ pub fn managed_vec_item_derive(input: proc_macro::TokenStream) -> proc_macro::To #[proc_macro] pub fn format_receiver_args(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - format::format_receiver_args_macro(input) + format::format_receiver_args_macro(input.into()).into() } #[proc_macro] pub fn semver_tuple(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - format::semver_tuple(input) + format::semver_tuple(input.into()).into() } diff --git a/framework/derive/src/managed_vec_item_derive.rs b/framework/derive/src/managed_vec_item_derive.rs index a65f62a37c..1755182f34 100644 --- a/framework/derive/src/managed_vec_item_derive.rs +++ b/framework/derive/src/managed_vec_item_derive.rs @@ -9,19 +9,16 @@ pub fn managed_vec_item_derive(ast: &syn::DeriveInput) -> TokenStream { } } -fn type_payload_size(type_name: &syn::Type) -> proc_macro2::TokenStream { - quote! { - <#type_name as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE - } -} - -fn generate_payload_snippets(fields: &syn::Fields) -> Vec { +fn generate_payload_nested_tuple(fields: &syn::Fields) -> proc_macro2::TokenStream { match fields { - syn::Fields::Named(fields_named) => fields_named - .named - .iter() - .map(|field| type_payload_size(&field.ty)) - .collect(), + syn::Fields::Named(fields_named) => { + let types: Vec<_> = fields_named.named.iter().map(|field| &field.ty).collect(); + let mut result = quote! { () }; + for ty in types.iter().rev() { + result = quote! { (#ty, #result) }; + } + result + }, _ => { panic!("ManagedVecItem only supports named fields") }, @@ -56,8 +53,8 @@ fn generate_from_byte_reader_snippets(fields: &syn::Fields) -> Vec::PAYLOAD_SIZE; - bytes.copy_from_slice(&arr[index .. next_index]); + let next_index = index + <#type_name as multiversx_sc::types::ManagedVecItem>::payload_size(); + bytes.copy_from_slice(&payload_slice[index .. next_index]); index = next_index; }), } @@ -79,8 +76,8 @@ fn generate_to_byte_writer_snippets(fields: &syn::Fields) -> Vec::PAYLOAD_SIZE; - arr[index .. next_index].copy_from_slice(bytes); + let next_index = index + <#type_name as multiversx_sc::types::ManagedVecItem>::payload_size(); + payload_slice[index .. next_index].copy_from_slice(bytes); index = next_index; }); } @@ -92,16 +89,10 @@ fn generate_to_byte_writer_snippets(fields: &syn::Fields) -> Vec proc_macro2::TokenStream { - let name = &ast.ident; - let self_expr = if ast.generics.params.is_empty() { - quote! { #name } - } else { - quote! { #name } - }; +fn generate_payload_buffer_snippet() -> proc_macro2::TokenStream { quote! { - const SELF_PAYLOAD_SIZE: usize = <#self_expr as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE; - let mut arr: [u8; SELF_PAYLOAD_SIZE] = [0u8; SELF_PAYLOAD_SIZE]; + let mut payload = ::new_buffer(); + let payload_slice = multiversx_sc::types::ManagedVecItemPayload::payload_slice_mut(&mut payload); } } @@ -130,7 +121,7 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream let gen = quote! { impl #impl_generics multiversx_sc::types::ManagedVecItem for #name #ty_generics #where_clause { - const PAYLOAD_SIZE: usize = 1; + type PAYLOAD = multiversx_sc::types::ManagedVecItemPayloadBuffer<1>; const SKIPS_RESERIALIZATION: bool = true; type Ref<'a> = Self; @@ -161,23 +152,23 @@ fn enum_derive(data_enum: &syn::DataEnum, ast: &syn::DeriveInput) -> TokenStream fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; let (impl_generics, ty_generics, where_clause) = &ast.generics.split_for_impl(); - let payload_snippets = generate_payload_snippets(&data_struct.fields); + let payload_nested_tuple = generate_payload_nested_tuple(&data_struct.fields); let skips_reserialization_snippets = generate_skips_reserialization_snippets(&data_struct.fields); let from_byte_reader_snippets = generate_from_byte_reader_snippets(&data_struct.fields); let to_byte_writer_snippets = generate_to_byte_writer_snippets(&data_struct.fields); - let array_init_snippet = generate_array_init_snippet(ast); + let payload_buffer_snippet = generate_payload_buffer_snippet(); let gen = quote! { impl #impl_generics multiversx_sc::types::ManagedVecItem for #name #ty_generics #where_clause { - const PAYLOAD_SIZE: usize = #(#payload_snippets)+*; + type PAYLOAD = <#payload_nested_tuple as multiversx_sc::types::ManagedVecItemNestedTuple>::PAYLOAD; const SKIPS_RESERIALIZATION: bool = #(#skips_reserialization_snippets)&&*; type Ref<'a> = Self; fn from_byte_reader(mut reader: Reader) -> Self { - #array_init_snippet - reader(&mut arr[..]); + #payload_buffer_snippet + reader(payload_slice); let mut index = 0; #name { @@ -190,12 +181,12 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token } fn to_byte_writer R>(&self, mut writer: Writer) -> R { - #array_init_snippet + #payload_buffer_snippet let mut index = 0; #(#to_byte_writer_snippets)* - writer(&arr[..]) + writer(&payload_slice[..]) } } }; diff --git a/framework/derive/src/model/contract_trait.rs b/framework/derive/src/model/contract_trait.rs index a3e5594a5a..3d3f838c7c 100644 --- a/framework/derive/src/model/contract_trait.rs +++ b/framework/derive/src/model/contract_trait.rs @@ -10,6 +10,7 @@ pub struct ContractTrait { /// It is possible to automatically implement a contract module for all contracts that use it indirectly. /// The drawback is that the developer make sure multiple inheritance does not happen. /// This feature is currently disabled. + #[allow(dead_code)] pub auto_inheritance_modules: Vec, pub methods: Vec, diff --git a/framework/derive/src/model/endpoint.rs b/framework/derive/src/model/endpoint.rs index 5c3d403fdc..1385dd1ada 100644 --- a/framework/derive/src/model/endpoint.rs +++ b/framework/derive/src/model/endpoint.rs @@ -29,6 +29,9 @@ pub enum PublicRole { /// The smart contract constructor. There can be only one. Init(InitMetadata), + /// The smart contract upgrade constructor. + Upgrade(InitMetadata), + /// Means it gets a smart contract function generated for it Endpoint(EndpointMetadata), diff --git a/framework/derive/src/model/endpoint_type_metadata.rs b/framework/derive/src/model/endpoint_type_metadata.rs index 4d668b2df7..4c048e94cb 100644 --- a/framework/derive/src/model/endpoint_type_metadata.rs +++ b/framework/derive/src/model/endpoint_type_metadata.rs @@ -2,6 +2,7 @@ #[derive(Debug, Clone)] pub enum EndpointTypeMetadata { Init, + Upgrade, Endpoint, PromisesCallback, } @@ -12,6 +13,9 @@ impl EndpointTypeMetadata { EndpointTypeMetadata::Init => { quote! { multiversx_sc::abi::EndpointTypeAbi::Init } }, + EndpointTypeMetadata::Upgrade => { + quote! { multiversx_sc::abi::EndpointTypeAbi::Upgrade } + }, EndpointTypeMetadata::Endpoint => { quote! { multiversx_sc::abi::EndpointTypeAbi::Endpoint } }, diff --git a/framework/derive/src/model/method.rs b/framework/derive/src/model/method.rs index c705ecb268..776e39dfaa 100644 --- a/framework/derive/src/model/method.rs +++ b/framework/derive/src/model/method.rs @@ -77,6 +77,7 @@ impl Method { pub fn is_payable(&self) -> bool { match &self.public_role { PublicRole::Init(init_metadata) => init_metadata.payable.is_payable(), + PublicRole::Upgrade(upgrade_metadata) => upgrade_metadata.payable.is_payable(), PublicRole::Endpoint(endpoint_metadata) => endpoint_metadata.payable.is_payable(), PublicRole::Callback(_) | PublicRole::CallbackRaw | PublicRole::CallbackPromise(_) => { true @@ -88,6 +89,7 @@ impl Method { pub fn payable_metadata(&self) -> MethodPayableMetadata { match &self.public_role { PublicRole::Init(init_metadata) => init_metadata.payable.clone(), + PublicRole::Upgrade(upgrade_metadata) => upgrade_metadata.payable.clone(), PublicRole::Endpoint(endpoint_metadata) => endpoint_metadata.payable.clone(), PublicRole::Callback(_) | PublicRole::CallbackRaw | PublicRole::CallbackPromise(_) => { MethodPayableMetadata::AnyToken @@ -99,6 +101,7 @@ impl Method { pub fn is_allow_multiple_var_args(&self) -> bool { match &self.public_role { PublicRole::Init(init_metadata) => init_metadata.allow_multiple_var_args, + PublicRole::Upgrade(upgrade_metadata) => upgrade_metadata.allow_multiple_var_args, PublicRole::Endpoint(endpoint_metadata) => endpoint_metadata.allow_multiple_var_args, PublicRole::Callback(callback_metadata) | PublicRole::CallbackPromise(callback_metadata) => { diff --git a/framework/derive/src/model/supertrait.rs b/framework/derive/src/model/supertrait.rs index 428bb5ea9c..e5aad040c4 100644 --- a/framework/derive/src/model/supertrait.rs +++ b/framework/derive/src/model/supertrait.rs @@ -6,6 +6,7 @@ pub type ModulePath = Punctuated; #[derive(Clone, Debug)] pub struct Supertrait { pub full_path: syn::Path, + #[allow(dead_code)] pub trait_name: syn::PathSegment, pub module_path: ModulePath, } diff --git a/framework/derive/src/parse/attributes/doc_attr.rs b/framework/derive/src/parse/attributes/doc_attr.rs index c2a670abb5..5c5ed4d41b 100644 --- a/framework/derive/src/parse/attributes/doc_attr.rs +++ b/framework/derive/src/parse/attributes/doc_attr.rs @@ -45,6 +45,24 @@ pub fn extract_doc(attrs: &[syn::Attribute]) -> Vec { .collect() } +pub fn extract_macro_attributes(attrs: &[syn::Attribute]) -> Vec { + let mut macro_attributes = Vec::new(); + + for a in attrs { + if let syn::Meta::List(list) = &a.meta { + if list.path.is_ident("derive") { + for token in list.tokens.clone().into_iter() { + if let proc_macro2::TokenTree::Ident(ident) = token { + macro_attributes.push(ident.to_string()); + } + } + } + } + } + + macro_attributes +} + fn remove_backslashes(input: &str) -> String { input .trim_matches('\"') diff --git a/framework/derive/src/parse/attributes/mod.rs b/framework/derive/src/parse/attributes/mod.rs index e355c78e61..e58c1a912e 100644 --- a/framework/derive/src/parse/attributes/mod.rs +++ b/framework/derive/src/parse/attributes/mod.rs @@ -11,7 +11,7 @@ mod trait_prop_names; mod util; pub use argument_attr::*; -pub use doc_attr::{extract_doc, OutputNameAttribute}; +pub use doc_attr::{extract_doc, extract_macro_attributes, OutputNameAttribute}; pub use endpoint_attr::*; pub use event_attr::*; pub use label_attr::*; diff --git a/framework/derive/src/parse/auto_impl_parse.rs b/framework/derive/src/parse/auto_impl_parse.rs index 11553794cd..24002e2139 100644 --- a/framework/derive/src/parse/auto_impl_parse.rs +++ b/framework/derive/src/parse/auto_impl_parse.rs @@ -4,17 +4,17 @@ use super::attributes::*; fn assert_no_other_auto_impl(method: &Method) { assert!( - method.implementation.is_no_implementation(), - "Only one auto-implementation can be specified at one time. Auto-implementations are: {}{}{}{}{}{}{}{}", - "`#[storage_get]`, ", - "`#[storage_set]`, ", - "`#[storage_mapper]`, ", - "`#[storage_is_empty]`, ", - "`#[storage_clear]`, ", - "`#[proxy]`, ", - "`#[module]`, ", - "`#[event]`." - ) + method.implementation.is_no_implementation(), + "Only one auto-implementation can be specified at one time. Auto-implementations are: {}{}{}{}{}{}{}{}", + "`#[storage_get]`, ", + "`#[storage_set]`, ", + "`#[storage_mapper]`, ", + "`#[storage_is_empty]`, ", + "`#[storage_clear]`, ", + "`#[proxy]`, ", + "`#[module]`, ", + "`#[event]`." + ) } pub fn process_event_attribute(attr: &syn::Attribute, method: &mut Method) -> bool { diff --git a/framework/derive/src/parse/endpoint_parse.rs b/framework/derive/src/parse/endpoint_parse.rs index 92fd4ff175..5edc30ad08 100644 --- a/framework/derive/src/parse/endpoint_parse.rs +++ b/framework/derive/src/parse/endpoint_parse.rs @@ -15,8 +15,8 @@ use super::{ fn check_single_role(method: &Method) { assert!(matches!(method.public_role, PublicRole::Private), - "Can only annotate with one of the following arguments: `#[init]`, `#[endpoint]`, `#[view]`, `#[callback]`, `#[callback_raw]`, `#[upgrade]`." - ); + "Can only annotate with one of the following arguments: `#[init]`, `#[endpoint]`, `#[view]`, `#[callback]`, `#[callback_raw]`, `#[upgrade]`." + ); } pub fn process_init_attribute( @@ -44,13 +44,8 @@ pub fn process_upgrade_attribute( let has_attr = is_upgrade(attr); if has_attr { check_single_role(&*method); - method.public_role = PublicRole::Endpoint(EndpointMetadata { - public_name: proc_macro2::Ident::new("upgrade", proc_macro2::Span::call_site()), + method.public_role = PublicRole::Upgrade(InitMetadata { payable: first_pass_data.payable.clone(), - only_owner: false, - only_admin: false, - only_user_account: false, - mutability: EndpointMutabilityMetadata::Mutable, allow_multiple_var_args: first_pass_data.allow_multiple_var_args, }); true diff --git a/framework/derive/src/parse/method_parse.rs b/framework/derive/src/parse/method_parse.rs index 267e9faa7b..a8c8a111c7 100644 --- a/framework/derive/src/parse/method_parse.rs +++ b/framework/derive/src/parse/method_parse.rs @@ -137,8 +137,8 @@ fn validate_method(method: &Method) { assert!( matches!( method.public_role, - PublicRole::Init(_) | PublicRole::Endpoint(_) | PublicRole::CallbackPromise(_) - ) || method.label_names.is_empty(), + PublicRole::Init(_) | PublicRole::Endpoint(_) | PublicRole::CallbackPromise(_) | PublicRole::Upgrade(_) + ) || method.label_names.is_empty(), "Labels can only be placed on endpoints, constructors, and promises callbacks. Method '{}' is neither.", &method.name.to_string() ) diff --git a/framework/derive/src/parse/payable_parse.rs b/framework/derive/src/parse/payable_parse.rs index 8d199b94a8..91deba4509 100644 --- a/framework/derive/src/parse/payable_parse.rs +++ b/framework/derive/src/parse/payable_parse.rs @@ -6,14 +6,14 @@ pub fn process_payable_attribute( pass_1_data: &mut MethodAttributesPass1, ) -> bool { PayableAttribute::parse(attr).map(|payable_attr| { - if let Some(identifier) = payable_attr.identifier { - pass_1_data.payable = parse_payable_identifier(identifier.as_str()); - } else { - panic!( - "Endpoint `payable` attribute requires one argument. Replace with `#[payable(\"*\")]` or `#[payable(\"EGLD\")]`. Method name: {}", - &pass_1_data.method_name); - } - }).is_some() + if let Some(identifier) = payable_attr.identifier { + pass_1_data.payable = parse_payable_identifier(identifier.as_str()); + } else { + panic!( + "Endpoint `payable` attribute requires one argument. Replace with `#[payable(\"*\")]` or `#[payable(\"EGLD\")]`. Method name: {}", + &pass_1_data.method_name); + } + }).is_some() } fn parse_payable_identifier(identifier: &str) -> MethodPayableMetadata { diff --git a/framework/derive/src/preprocessing/substitution_list.rs b/framework/derive/src/preprocessing/substitution_list.rs index 8084651a49..62fdb11823 100644 --- a/framework/derive/src/preprocessing/substitution_list.rs +++ b/framework/derive/src/preprocessing/substitution_list.rs @@ -71,7 +71,7 @@ fn add_managed_types(substitutions: &mut SubstitutionsMap) { add_managed_type(substitutions, "e!(EsdtTokenData)); add_managed_type(substitutions, "e!(EsdtTokenPayment)); add_managed_type(substitutions, "e!(ManagedAddress)); - add_managed_type(substitutions, "e!(ManagedBufferCachedBuilder)); + add_managed_type(substitutions, "e!(ManagedBufferBuilder)); add_managed_type_with_generics(substitutions, "e!(ManagedByteArray)); add_managed_type_with_generics(substitutions, "e!(ManagedOption)); add_managed_type_with_generics(substitutions, "e!(ManagedRef)); diff --git a/framework/derive/src/type_abi_derive.rs b/framework/derive/src/type_abi_derive.rs index efef94acb6..8c70b56af8 100644 --- a/framework/derive/src/type_abi_derive.rs +++ b/framework/derive/src/type_abi_derive.rs @@ -1,5 +1,6 @@ +use crate::parse::attributes::extract_macro_attributes; + use super::parse::attributes::extract_doc; -use proc_macro::TokenStream; use quote::quote; pub struct ExplicitDiscriminant { @@ -19,7 +20,7 @@ fn field_snippet(index: usize, field: &syn::Field) -> proc_macro2::TokenStream { field_descriptions.push(multiversx_sc::abi::StructFieldDescription::new( &[ #(#field_docs),* ], #field_name_str, - <#field_ty>::type_name(), + <#field_ty>::type_names(), )); <#field_ty>::provide_type_descriptions(accumulator); } @@ -43,24 +44,28 @@ fn fields_snippets(fields: &syn::Fields) -> Vec { } } -pub fn type_abi_derive(ast: &syn::DeriveInput) -> TokenStream { +pub fn type_abi_derive(input: proc_macro::TokenStream) -> proc_macro2::TokenStream { + let ast: syn::DeriveInput = syn::parse(input).unwrap(); let type_docs = extract_doc(ast.attrs.as_slice()); + let macro_attributes = extract_macro_attributes(ast.attrs.as_slice()); + let type_description_impl = match &ast.data { syn::Data::Struct(data_struct) => { let struct_field_snippets = fields_snippets(&data_struct.fields); quote! { fn provide_type_descriptions(accumulator: &mut TDC) { - let type_name = Self::type_name(); - if !accumulator.contains_type(&type_name) { - accumulator.reserve_type_name(type_name.clone()); + let type_names = Self::type_names(); + if !accumulator.contains_type(&type_names.abi) { + accumulator.reserve_type_name(type_names.clone()); let mut field_descriptions = multiversx_sc::types::heap::Vec::new(); #(#struct_field_snippets)* accumulator.insert( - type_name.clone(), + type_names.clone(), multiversx_sc::abi::TypeDescription::new( &[ #(#type_docs),* ], - type_name, + type_names, multiversx_sc::abi::TypeContents::Struct(field_descriptions), + &[ #(#macro_attributes),* ], ), ); } @@ -93,17 +98,18 @@ pub fn type_abi_derive(ast: &syn::DeriveInput) -> TokenStream { .collect(); quote! { fn provide_type_descriptions(accumulator: &mut TDC) { - let type_name = Self::type_name(); - if !accumulator.contains_type(&type_name) { - accumulator.reserve_type_name(type_name.clone()); + let type_names = Self::type_names(); + if !accumulator.contains_type(&type_names.abi) { + accumulator.reserve_type_name(type_names.clone()); let mut variant_descriptions = multiversx_sc::types::heap::Vec::new(); #(#enum_variant_snippets)* accumulator.insert( - type_name.clone(), + type_names.clone(), multiversx_sc::abi::TypeDescription::new( &[ #(#type_docs),* ], - type_name, + type_names, multiversx_sc::abi::TypeContents::Enum(variant_descriptions), + &[ #(#macro_attributes),* ], ), ); } @@ -116,16 +122,28 @@ pub fn type_abi_derive(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; let name_str = name.to_string(); let (impl_generics, ty_generics, where_clause) = &ast.generics.split_for_impl(); - let type_abi_impl = quote! { + quote! { + impl #impl_generics multiversx_sc::abi::TypeAbiFrom for #name #ty_generics #where_clause {} + impl #impl_generics multiversx_sc::abi::TypeAbiFrom<&Self> for #name #ty_generics #where_clause {} + impl #impl_generics multiversx_sc::abi::TypeAbi for #name #ty_generics #where_clause { + type Unmanaged = Self; + fn type_name() -> multiversx_sc::abi::TypeName { #name_str.into() } - #type_description_impl } - }; - type_abi_impl.into() + } +} + +pub fn type_abi_full(input: proc_macro::TokenStream) -> proc_macro2::TokenStream { + let input_conv = proc_macro2::TokenStream::from(input.clone()); + let derive_code = type_abi_derive(input); + quote! { + #input_conv + #derive_code + } } pub fn get_discriminant( diff --git a/framework/derive/src/validate/validate_method.rs b/framework/derive/src/validate/validate_method.rs index 9683e6c2ff..fafb2322e0 100644 --- a/framework/derive/src/validate/validate_method.rs +++ b/framework/derive/src/validate/validate_method.rs @@ -2,6 +2,7 @@ use super::reserved; use crate::model::{ArgPaymentMetadata, ContractTrait, Method, PublicRole}; const INIT_ENDPOINT_NAME: &str = "init"; +const UPGRADE_ENDPOINT_NAME: &str = "upgrade"; /// TODO: make it work with Result instead of panic pub fn validate_contract(contract_trait: &ContractTrait) { @@ -23,6 +24,10 @@ fn validate_method_name(m: &Method) { endpoint_name_str != INIT_ENDPOINT_NAME, "Cannot declare endpoint with name 'init'. Use #[init] instead." ); + assert!( + endpoint_name_str != UPGRADE_ENDPOINT_NAME, + "Cannot declare endpoint with name 'upgrade'. Use #[upgrade] instead." + ); assert!(!reserved::is_reserved(endpoint_name_str.as_str()), "Cannot declare endpoint with name '{endpoint_name_str}', because that name is reserved by the Arwen API."); } } @@ -73,7 +78,7 @@ fn validate_payment_args(m: &Method) { assert!(num_payment_token == 0, "`#[payment_token]` only allowed in payable endpoints, payable init or callbacks (method: `{}`)", m.name); } - if let PublicRole::Init(init_metadata) = &m.public_role { + if let PublicRole::Init(init_metadata) | PublicRole::Upgrade(init_metadata) = &m.public_role { assert!( init_metadata.payable.no_esdt(), "only EGLD payments currently allowed in constructors" diff --git a/framework/meta-lib/Cargo.toml b/framework/meta-lib/Cargo.toml new file mode 100644 index 0000000000..bb963552f2 --- /dev/null +++ b/framework/meta-lib/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "multiversx-sc-meta-lib" +version = "0.50.3" +edition = "2021" + +authors = [ + "Andrei Marinica ", + "MultiversX ", +] +license = "GPL-3.0-only" +readme = "README.md" +repository = "https://github.com/multiversx/mx-sdk-rs" +homepage = "https://multiversx.com/" +documentation = "https://docs.multiversx.com/" +description = "MultiversX smart contract meta-programming tools and build system" +keywords = ["multiversx", "blockchain", "contract", "debug"] +categories = ["cryptography::cryptocurrencies", "development-tools::debugging"] + +[dependencies] +clap = { version = "4.4.7", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +rustc_version = "0.4" +toml = { version = "0.8.6", features = ["preserve_order"] } +colored = "2.0" +lazy_static = "1.4.0" +convert_case = "0.6.0" +hex = "0.4" +wasmparser = "0.208" +wasmprinter = "0.208" +semver = "1.0.20" + +[dependencies.multiversx-sc] +version = "=0.50.3" +path = "../base" +features = ["alloc", "num-bigint"] diff --git a/framework/meta-lib/README.md b/framework/meta-lib/README.md new file mode 100644 index 0000000000..93814bc3d0 --- /dev/null +++ b/framework/meta-lib/README.md @@ -0,0 +1,14 @@ +# Smart contract `meta` crate support + +[![crates.io](https://img.shields.io/crates/v/multiversx-sc-meta.svg)](https://crates.io/crates/multiversx-sc-meta) + +The library that provides all the functionality of the individual contracts `meta` crates. + +The purpose of the contract `meta` crates is to produce the contract ABI. Because of their access to the ABI, they have other ABI-based responsibilities, such as: +- generating the `wasm` crates, +- building the contracts, +- performing validations not possible otherwise, +- generating snippets, +- etc. + +For more about the build process, see https://docs.multiversx.com/developers/developer-reference/sc-build-reference/ diff --git a/framework/meta/src/abi_json.rs b/framework/meta-lib/src/abi_json.rs similarity index 100% rename from framework/meta/src/abi_json.rs rename to framework/meta-lib/src/abi_json.rs diff --git a/framework/meta/src/abi_json/build_info_abi_json.rs b/framework/meta-lib/src/abi_json/build_info_abi_json.rs similarity index 100% rename from framework/meta/src/abi_json/build_info_abi_json.rs rename to framework/meta-lib/src/abi_json/build_info_abi_json.rs diff --git a/framework/meta/src/abi_json/contract_abi_json.rs b/framework/meta-lib/src/abi_json/contract_abi_json.rs similarity index 89% rename from framework/meta/src/abi_json/contract_abi_json.rs rename to framework/meta-lib/src/abi_json/contract_abi_json.rs index c4f62916c3..58c0865eee 100644 --- a/framework/meta/src/abi_json/contract_abi_json.rs +++ b/framework/meta-lib/src/abi_json/contract_abi_json.rs @@ -20,6 +20,10 @@ pub struct ContractAbiJson { #[serde(skip_serializing_if = "Option::is_none")] pub constructor: Option, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + pub upgrade_constructor: Option, + #[serde(default)] pub endpoints: Vec, @@ -48,6 +52,10 @@ impl From<&ContractAbi> for ContractAbiJson { docs: abi.docs.iter().map(|d| d.to_string()).collect(), name: abi.name.to_string(), constructor: abi.constructors.first().map(ConstructorAbiJson::from), + upgrade_constructor: abi + .upgrade_constructors + .first() + .map(ConstructorAbiJson::from), endpoints: abi.endpoints.iter().map(EndpointAbiJson::from).collect(), promises_callback_names: abi .promise_callbacks @@ -70,10 +78,10 @@ pub fn convert_type_descriptions_to_json( type_descriptions: &TypeDescriptionContainerImpl, ) -> BTreeMap { let mut types = BTreeMap::new(); - for (type_name, type_description) in type_descriptions.0.iter() { + for (type_names, type_description) in type_descriptions.0.iter() { if type_description.contents.is_specified() { types.insert( - type_name.clone(), + type_names.abi.clone(), TypeDescriptionJson::from(type_description), ); } diff --git a/framework/meta/src/abi_json/endpoint_abi_json.rs b/framework/meta-lib/src/abi_json/endpoint_abi_json.rs similarity index 97% rename from framework/meta/src/abi_json/endpoint_abi_json.rs rename to framework/meta-lib/src/abi_json/endpoint_abi_json.rs index 5882fcd961..b6bd041713 100644 --- a/framework/meta/src/abi_json/endpoint_abi_json.rs +++ b/framework/meta-lib/src/abi_json/endpoint_abi_json.rs @@ -19,7 +19,7 @@ impl From<&InputAbi> for InputAbiJson { fn from(abi: &InputAbi) -> Self { InputAbiJson { arg_name: abi.arg_name.to_string(), - type_name: abi.type_name.clone(), + type_name: abi.type_names.abi.clone(), multi_arg: if abi.multi_arg { Some(true) } else { None }, } } @@ -43,7 +43,7 @@ impl From<&OutputAbi> for OutputAbiJson { fn from(abi: &OutputAbi) -> Self { OutputAbiJson { output_name: abi.output_name.clone(), - type_name: abi.type_name.clone(), + type_name: abi.type_names.abi.clone(), multi_result: if abi.multi_result { Some(true) } else { None }, } } diff --git a/framework/meta/src/abi_json/esdt_attribute_abi_json.rs b/framework/meta-lib/src/abi_json/esdt_attribute_abi_json.rs similarity index 100% rename from framework/meta/src/abi_json/esdt_attribute_abi_json.rs rename to framework/meta-lib/src/abi_json/esdt_attribute_abi_json.rs diff --git a/framework/meta/src/abi_json/esdt_attribute_json.rs b/framework/meta-lib/src/abi_json/esdt_attribute_json.rs similarity index 100% rename from framework/meta/src/abi_json/esdt_attribute_json.rs rename to framework/meta-lib/src/abi_json/esdt_attribute_json.rs diff --git a/framework/meta/src/abi_json/event_abi_json.rs b/framework/meta-lib/src/abi_json/event_abi_json.rs similarity index 100% rename from framework/meta/src/abi_json/event_abi_json.rs rename to framework/meta-lib/src/abi_json/event_abi_json.rs diff --git a/framework/meta/src/abi_json/type_abi_json.rs b/framework/meta-lib/src/abi_json/type_abi_json.rs similarity index 94% rename from framework/meta/src/abi_json/type_abi_json.rs rename to framework/meta-lib/src/abi_json/type_abi_json.rs index 5602ae98cc..f26cc7086d 100644 --- a/framework/meta/src/abi_json/type_abi_json.rs +++ b/framework/meta-lib/src/abi_json/type_abi_json.rs @@ -68,10 +68,10 @@ impl From<&TypeDescription> for TypeDescriptionJson { } impl TypeDescriptionJson { - pub fn to_type_description(&self, name: &str) -> TypeDescription { + pub fn to_type_description(&self, names: TypeNames) -> TypeDescription { TypeDescription { docs: self.docs.clone(), - name: name.to_string(), + names, contents: match self.content_type.as_str() { TYPE_DESCRIPTION_JSON_TYPE_STRUCT => TypeContents::Struct( self.fields @@ -87,6 +87,7 @@ impl TypeDescriptionJson { ), _ => TypeContents::NotSpecified, }, + macro_attributes: Vec::new(), } } } @@ -108,7 +109,7 @@ impl From<&StructFieldDescription> for StructFieldDescriptionJson { StructFieldDescriptionJson { docs: abi.docs.iter().map(|d| d.to_string()).collect(), name: abi.name.to_string(), - field_type: abi.field_type.clone(), + field_type: abi.field_type.abi.clone(), } } } @@ -118,7 +119,10 @@ impl StructFieldDescriptionJson { StructFieldDescription { docs: self.docs.clone(), name: self.name.clone(), - field_type: self.field_type.clone(), + field_type: TypeNames { + abi: self.field_type.clone(), + rust: "".into(), + }, } } } diff --git a/framework/meta/src/cargo_toml_contents.rs b/framework/meta-lib/src/cargo_toml_contents.rs similarity index 97% rename from framework/meta/src/cargo_toml_contents.rs rename to framework/meta-lib/src/cargo_toml_contents.rs index 1a6596a68d..49721f5cec 100644 --- a/framework/meta/src/cargo_toml_contents.rs +++ b/framework/meta-lib/src/cargo_toml_contents.rs @@ -6,7 +6,7 @@ use std::{ use toml::{value::Table, Value}; -use crate::cmd::contract::sc_config::ContractVariantProfile; +use crate::contract::sc_config::ContractVariantProfile; pub const CARGO_TOML_DEPENDENCIES: &str = "dependencies"; pub const CARGO_TOML_DEV_DEPENDENCIES: &str = "dev-dependencies"; @@ -218,9 +218,15 @@ impl CargoTomlContents { Value::Boolean(contract_profile.overflow_checks), ); + // add contract variant profile let mut toml_table = toml::map::Map::new(); toml_table.insert("release".to_string(), toml::Value::Table(profile_props)); + // add profile dev + let mut dev_value = toml::map::Map::new(); + dev_value.insert("panic".to_string(), Value::String("abort".to_string())); + toml_table.insert("dev".to_string(), toml::Value::Table(dev_value)); + self.toml_value .as_table_mut() .expect("malformed package in Cargo.toml") diff --git a/framework/meta/src/cli_args.rs b/framework/meta-lib/src/cli.rs similarity index 81% rename from framework/meta/src/cli_args.rs rename to framework/meta-lib/src/cli.rs index d3ff8af23d..ff5d4a8111 100644 --- a/framework/meta/src/cli_args.rs +++ b/framework/meta-lib/src/cli.rs @@ -1,10 +1,10 @@ mod cli_args_build; mod cli_args_contract; -mod cli_args_standalone; +mod cli_contract_main; pub use cli_args_build::*; pub use cli_args_contract::*; -pub use cli_args_standalone::*; +pub use cli_contract_main::*; pub trait CliArgsToRaw { /// Converts to a list of raw arguments, as they would be called in a command. diff --git a/framework/meta/src/cli_args/cli_args_build.rs b/framework/meta-lib/src/cli/cli_args_build.rs similarity index 100% rename from framework/meta/src/cli_args/cli_args_build.rs rename to framework/meta-lib/src/cli/cli_args_build.rs diff --git a/framework/meta/src/cli_args/cli_args_contract.rs b/framework/meta-lib/src/cli/cli_args_contract.rs similarity index 82% rename from framework/meta/src/cli_args/cli_args_contract.rs rename to framework/meta-lib/src/cli/cli_args_contract.rs index 1853d64675..4a7f0ee4c7 100644 --- a/framework/meta/src/cli_args/cli_args_contract.rs +++ b/framework/meta-lib/src/cli/cli_args_contract.rs @@ -66,6 +66,12 @@ pub enum ContractCliAction { about = "Generates a snippets project, based on the contract ABI." )] GenerateSnippets(GenerateSnippetsArgs), + + #[command( + name = "proxy", + about = "Generates a proxy, based on the contract ABI." + )] + GenerateProxies(GenerateProxyArgs), } impl CliArgsToRaw for ContractCliAction { @@ -97,6 +103,10 @@ impl CliArgsToRaw for ContractCliAction { raw.push("snippets".to_string()); raw.append(&mut args.to_raw()); }, + ContractCliAction::GenerateProxies(args) => { + raw.push("proxy".to_string()); + raw.append(&mut args.to_raw()); + }, } raw } @@ -118,3 +128,20 @@ impl CliArgsToRaw for GenerateSnippetsArgs { raw } } + +#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] +pub struct GenerateProxyArgs { + /// Runs proxy comparison (newly generated vs already present on disk). + #[arg(long, verbatim_doc_comment)] + pub compare: bool, +} + +impl CliArgsToRaw for GenerateProxyArgs { + fn to_raw(&self) -> Vec { + let mut raw = Vec::new(); + if self.compare { + raw.push("--compare".to_string()); + } + raw + } +} diff --git a/framework/meta/src/cmd/contract.rs b/framework/meta-lib/src/cli/cli_contract_main.rs similarity index 74% rename from framework/meta/src/cmd/contract.rs rename to framework/meta-lib/src/cli/cli_contract_main.rs index 215c394d63..7ce6dcbd74 100644 --- a/framework/meta/src/cmd/contract.rs +++ b/framework/meta-lib/src/cli/cli_contract_main.rs @@ -1,17 +1,11 @@ -mod generate_snippets; -mod meta_abi; -mod meta_config; -pub mod sc_config; -pub mod wasm_cargo_toml_data; -pub mod wasm_cargo_toml_generate; - use std::path::Path; -use crate::cli_args::{ContractCliAction, ContractCliArgs}; +use crate::{ + cli::{ContractCliAction, ContractCliArgs}, + contract::{meta_config::MetaConfig, sc_config::ScConfig}, +}; use clap::Parser; -use meta_config::MetaConfig; use multiversx_sc::contract_base::ContractAbiProvider; -use sc_config::ScConfig; /// Entry point in the program from the contract meta crates. pub fn cli_main() { @@ -28,8 +22,17 @@ pub fn cli_main() { }, ContractCliAction::Clean => meta_config_opt.clean(), ContractCliAction::Update => meta_config_opt.update(), - ContractCliAction::GenerateSnippets(gs_args) => { - meta_config_opt.generate_rust_snippets(&gs_args) + ContractCliAction::GenerateSnippets(gs_arg) => { + meta_config_opt.generate_rust_snippets(&gs_arg); + meta_config_opt.reload_sc_config(); + meta_config_opt.generate_proxy() + }, + ContractCliAction::GenerateProxies(proxy_args) => { + if proxy_args.compare { + meta_config_opt.compare_proxy() + } else { + meta_config_opt.generate_proxy() + } }, } } diff --git a/framework/meta-lib/src/contract.rs b/framework/meta-lib/src/contract.rs new file mode 100644 index 0000000000..7df5486e73 --- /dev/null +++ b/framework/meta-lib/src/contract.rs @@ -0,0 +1,7 @@ +pub mod generate_proxy; +pub mod generate_snippets; +pub mod meta_abi; +pub mod meta_config; +pub mod sc_config; +pub mod wasm_cargo_toml_data; +pub mod wasm_cargo_toml_generate; diff --git a/framework/meta-lib/src/contract/generate_proxy.rs b/framework/meta-lib/src/contract/generate_proxy.rs new file mode 100644 index 0000000000..3a7443d612 --- /dev/null +++ b/framework/meta-lib/src/contract/generate_proxy.rs @@ -0,0 +1,4 @@ +pub mod proxy_crate_gen; +pub mod proxy_gen_main; +mod proxy_generator; +mod proxy_process_type_name; diff --git a/framework/meta-lib/src/contract/generate_proxy/proxy_crate_gen.rs b/framework/meta-lib/src/contract/generate_proxy/proxy_crate_gen.rs new file mode 100644 index 0000000000..8b5960577d --- /dev/null +++ b/framework/meta-lib/src/contract/generate_proxy/proxy_crate_gen.rs @@ -0,0 +1,8 @@ +use std::fs::File; + +#[must_use] +pub(crate) fn create_file(proxy_file_name: &str) -> File { + let file = format!("../{proxy_file_name}"); + + File::create(file).expect("could not write proxy file") +} diff --git a/framework/meta-lib/src/contract/generate_proxy/proxy_gen_main.rs b/framework/meta-lib/src/contract/generate_proxy/proxy_gen_main.rs new file mode 100644 index 0000000000..d6c913a0e4 --- /dev/null +++ b/framework/meta-lib/src/contract/generate_proxy/proxy_gen_main.rs @@ -0,0 +1,70 @@ +use colored::Colorize; +use std::fs; + +use multiversx_sc::abi::ContractAbi; + +use crate::contract::sc_config::ProxyConfigSerde; + +use super::{ + super::meta_config::MetaConfig, proxy_crate_gen::create_file, proxy_generator::ProxyGenerator, +}; + +const PROXY_COMPARE_ERR_MSG: &str = "Contract has been modified and proxies have not been updated. Regenerate proxies to avoid inconsistencies."; + +impl MetaConfig { + pub fn generate_proxy(&mut self) { + let default_proxy = ProxyConfigSerde::new(); + write_proxy_with_explicit_path(&default_proxy, self); + for proxy_config in self.sc_config.proxy_configs.clone() { + write_proxy_with_explicit_path(&proxy_config, self); + } + } + + pub fn compare_proxy(&mut self) { + for proxy_config in self.sc_config.proxy_configs.clone() { + compare_proxy_explicit_path(&proxy_config, self); + } + } +} + +fn compare_proxy_explicit_path(proxy_config: &ProxyConfigSerde, meta_config: &MetaConfig) { + let contract_abi = extract_contract_abi(proxy_config, meta_config); + let mut temp = Vec::::new(); + let mut proxy_generator = + ProxyGenerator::new(meta_config, &mut temp, proxy_config, contract_abi); + proxy_generator.write_proxy_to_file(); + + let existent_proxy_path = format!("../{}", proxy_config.path); + let existent_proxy = fs::read_to_string(existent_proxy_path).unwrap(); + let newly_gen_proxy = String::from_utf8(temp).unwrap(); + + if existent_proxy != newly_gen_proxy { + panic!("{}", PROXY_COMPARE_ERR_MSG.to_string().red()); + } +} + +fn write_proxy_with_explicit_path(proxy_config: &ProxyConfigSerde, meta_config: &MetaConfig) { + let contract_abi = extract_contract_abi(proxy_config, meta_config); + let mut file = create_file(&proxy_config.path); + let mut proxy_generator = + ProxyGenerator::new(meta_config, &mut file, proxy_config, contract_abi); + proxy_generator.write_proxy_to_file(); +} + +fn extract_contract_abi<'a>( + proxy_config: &'a ProxyConfigSerde, + meta_config: &'a MetaConfig, +) -> &'a ContractAbi { + if proxy_config.variant.is_some() { + let variant = proxy_config.variant.as_ref().unwrap(); + for contract_variant in &meta_config.sc_config.contracts { + if variant == &contract_variant.public_name_snake_case() { + return &contract_variant.abi; + } + } + + panic!("No variant with name \"{}\" in multicontract", variant); + } + + &meta_config.original_contract_abi +} diff --git a/framework/meta-lib/src/contract/generate_proxy/proxy_generator.rs b/framework/meta-lib/src/contract/generate_proxy/proxy_generator.rs new file mode 100644 index 0000000000..d2e0b22036 --- /dev/null +++ b/framework/meta-lib/src/contract/generate_proxy/proxy_generator.rs @@ -0,0 +1,691 @@ +use std::fmt::Display; + +use multiversx_sc::abi::{ + ContractAbi, EndpointAbi, EnumVariantDescription, InputAbi, OutputAbi, StructFieldDescription, + TypeContents, TypeDescription, +}; + +use crate::contract::{meta_config::MetaConfig, sc_config::ProxyConfigSerde}; + +use super::proxy_process_type_name::{ + extract_paths, extract_struct_crate, process_rust_type, proxy_methods_type_name, + proxy_type_name, +}; + +const PRELUDE: &str = "// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] +"; + +const IMPORTS: &str = "use multiversx_sc::proxy_imports::*;"; + +const ZERO: &str = "0"; + +/// Types defined in the framework don't need to be generated again in the proxy. +const TYPES_FROM_FRAMEWORK: &[&str] = &[ + "EsdtTokenPayment", + "EgldOrEsdtTokenPayment", + "EsdtTokenData", + "EgldOrEsdtTokenIdentifier", + "EgldOrEsdtTokenPayment", + "EgldOrMultiEsdtPayment", + "EsdtTokenData", + "EsdtLocalRole", + "EsdtTokenType", +]; + +pub struct ProxyGenerator<'a> { + #[allow(dead_code)] + pub meta_config: &'a MetaConfig, + pub file: Option<&'a mut dyn std::io::Write>, + pub proxy_config: &'a ProxyConfigSerde, + pub contract_abi: &'a ContractAbi, +} + +impl<'a> ProxyGenerator<'a> { + pub fn new( + meta_config: &'a MetaConfig, + file: &'a mut dyn std::io::Write, + proxy_config: &'a ProxyConfigSerde, + contract_abi: &'a ContractAbi, + ) -> Self { + Self { + meta_config, + file: Some(file), + proxy_config, + contract_abi, + } + } + + fn write(&mut self, s: impl Display) { + let file = self.file.as_mut().unwrap(); + file.write_all(s.to_string().as_bytes()).unwrap(); + } + + fn writeln(&mut self, s: impl Display) { + self.write(s); + self.write("\n"); + } + + pub fn write_proxy_to_file(&mut self) { + self.write_header(); + self.write_tx_proxy_type_def(); + self.write_impl_for_tx_proxy(); + self.write_struct_tx_proxy_methods(); + self.write_content(); + self.write_types(); + } + + fn write_header(&mut self) { + self.writeln(PRELUDE); + match &self.proxy_config.override_import { + Some(override_import) => self.writeln(override_import), + None => self.writeln(IMPORTS), + } + } + + fn write_tx_proxy_type_def(&mut self) { + let proxy_type_name = proxy_type_name(&self.contract_abi.name); + self.writeln(format!( + r#" +pub struct {proxy_type_name};"# + )); + } + + fn write_impl_for_tx_proxy(&mut self) { + let proxy_type_name = proxy_type_name(&self.contract_abi.name); + let proxy_methods_type_name = proxy_methods_type_name(&self.contract_abi.name); + self.writeln(format!( + r#" +impl TxProxyTrait for {proxy_type_name} +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{{ + type TxProxyMethods = {proxy_methods_type_name}; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods {{ + {proxy_methods_type_name} {{ wrapped_tx: tx }} + }} +}}"# + )); + } + + fn write_struct_tx_proxy_methods(&mut self) { + let proxy_methods_type_name = proxy_methods_type_name(&self.contract_abi.name); + self.writeln(format!( + r#" +pub struct {proxy_methods_type_name} +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{{ + wrapped_tx: Tx, +}}"# + )); + } + + fn write_content(&mut self) { + if !self.contract_abi.constructors.is_empty() { + self.write_constructors(); + } + + if !self.contract_abi.upgrade_constructors.is_empty() { + self.write_upgrades(); + } + + if !self.contract_abi.endpoints.is_empty() { + self.write_endpoints(); + } + } + + fn write_types(&mut self) { + for (_, type_description) in &self.contract_abi.type_descriptions.0 { + if self.contract_abi.get_crate_name_for_code() + != extract_struct_crate(type_description.names.rust.as_str()) + { + continue; + } + + let type_name = self.adjust_type_name_with_api(&type_description.names.rust); + if TYPES_FROM_FRAMEWORK.contains(&type_name.as_str()) { + continue; + } + + match &type_description.contents { + TypeContents::Enum(enum_variants) => { + self.write_enum(enum_variants, type_description, &type_name) + }, + TypeContents::Struct(struct_fields) => { + self.write_struct(struct_fields, type_description, &type_name) + }, + TypeContents::NotSpecified => {}, + TypeContents::ExplicitEnum(_) => {}, + } + } + } + + fn write_constructors(&mut self) { + let constructors: Vec = self.contract_abi.constructors.clone(); + + self.write_header_impl_constructor(); + for (i, constructor_abi) in constructors.into_iter().enumerate() { + if i > 0 { + self.writeln(""); + } + self.write_constructor_header(&constructor_abi); + self.write_constructor_content(&constructor_abi); + self.write_end_of_function(); + } + + self.writeln("}"); + } + + fn write_upgrades(&mut self) { + self.write_header_impl_upgrade(); + for (i, upgrade) in self + .contract_abi + .upgrade_constructors + .clone() + .into_iter() + .enumerate() + { + if i > 0 { + self.writeln(""); + } + self.write_upgrade_header(&upgrade); + self.write_upgrade_content(&upgrade); + self.write_end_of_function(); + } + + self.writeln("}"); + } + + fn write_endpoints(&mut self) { + let endpoints: Vec = self.contract_abi.endpoints.clone(); + + self.write_header_impl_endpoints(); + for (i, endpoint_abi) in endpoints.into_iter().enumerate() { + if i > 0 { + self.writeln(""); + } + self.write_endpoint_header(&endpoint_abi); + self.write_endpoint_content(&endpoint_abi); + self.write_end_of_function(); + } + + self.writeln("}"); + } + + fn write_header_impl_constructor(&mut self) { + let proxy_methods_type_name = proxy_methods_type_name(&self.contract_abi.name); + self.writeln(format!( + r#" +#[rustfmt::skip] +impl {proxy_methods_type_name} +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{{"# + )); + } + + fn write_header_impl_upgrade(&mut self) { + let proxy_methods_type_name = proxy_methods_type_name(&self.contract_abi.name); + self.writeln(format!( + r#" +#[rustfmt::skip] +impl {proxy_methods_type_name} +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{{"# + )); + } + + fn write_header_impl_endpoints(&mut self) { + let proxy_methods_type_name = proxy_methods_type_name(&self.contract_abi.name); + self.writeln(format!( + r#" +#[rustfmt::skip] +impl {proxy_methods_type_name} +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{{"# + )); + } + + fn write_constructor_header(&mut self, constructor_abi: &EndpointAbi) { + self.write_fn_signature(constructor_abi); + self.write_constructor_output(constructor_abi); + } + + fn write_upgrade_header(&mut self, constructor_abi: &EndpointAbi) { + self.write_fn_signature(constructor_abi); + self.write_upgrade_output(constructor_abi); + } + + fn write_endpoint_header(&mut self, constructor_abi: &EndpointAbi) { + self.write_fn_signature(constructor_abi); + self.write_endpoint_output(constructor_abi); + } + + fn write_constructor_content(&mut self, constructor_abi: &EndpointAbi) { + self.writeln(" self.wrapped_tx"); + if constructor_abi.payable_in_tokens.is_empty() { + self.writeln(" .payment(NotPayable)"); + } + self.writeln(" .raw_deploy()"); + for input in constructor_abi.inputs.iter() { + self.writeln(format!(" .argument(&{})", input.arg_name)); + } + self.writeln(" .original_result()"); + } + + fn write_upgrade_content(&mut self, constructor_abi: &EndpointAbi) { + self.writeln(" self.wrapped_tx"); + if constructor_abi.payable_in_tokens.is_empty() { + self.writeln(" .payment(NotPayable)"); + } + self.writeln(" .raw_upgrade()"); + for input in constructor_abi.inputs.iter() { + self.writeln(format!(" .argument(&{})", input.arg_name)); + } + self.writeln(" .original_result()"); + } + + fn write_endpoint_content(&mut self, endpoint: &EndpointAbi) { + self.writeln(" self.wrapped_tx"); + + if endpoint.payable_in_tokens.is_empty() { + self.writeln(" .payment(NotPayable)"); + } + + self.writeln(format!(" .raw_call(\"{}\")", endpoint.name)); + + for input in endpoint.inputs.iter() { + self.writeln(format!(" .argument(&{})", input.arg_name)); + } + + self.writeln(" .original_result()"); + } + + fn write_fn_signature(&mut self, endpoint: &EndpointAbi) { + self.write_endpoint_docs(&endpoint.docs); + self.write_function_header_endpoint(&endpoint.rust_method_name); + self.write_args(&endpoint.inputs); + self.write_parameters(&endpoint.inputs); + } + + fn write_endpoint_docs(&mut self, docs: &Vec) { + for doc in docs { + self.writeln(format!(" /// {doc} ")); + } + } + + fn write_function_header_endpoint(&mut self, rust_method_name: &String) { + self.write(format!(" pub fn {rust_method_name}")); + } + + fn write_args(&mut self, inputs: &[InputAbi]) { + if inputs.is_empty() { + return; + } + + self.writeln("<"); + + for (index, input) in inputs.iter().enumerate() { + self.write_argument(index, &input.type_names.rust); + } + + self.write(" >"); + } + + fn write_argument(&mut self, index: usize, rust_name: &str) { + let adjusted = self.adjust_type_name_with_env_api(rust_name); + self.writeln(format!(" Arg{index}: ProxyArg<{adjusted}>,")); + } + + fn write_parameters(&mut self, inputs: &[InputAbi]) { + self.writeln("("); + self.writeln(" self,"); + for (index, input) in inputs.iter().enumerate() { + self.writeln(format!(" {}: Arg{index},", &input.arg_name)); + } + self.write(" ) "); + } + + fn write_constructor_output(&mut self, abi: &EndpointAbi) { + self.write("-> TxTypedDeploy {"); + } + + fn write_upgrade_output(&mut self, abi: &EndpointAbi) { + self.write("-> TxTypedUpgrade {"); + } + + fn write_endpoint_output(&mut self, abi: &EndpointAbi) { + self.write("-> TxTypedCall {"); + } + + fn write_payment_type(&mut self, abi: &EndpointAbi) { + if abi.payable_in_tokens.is_empty() { + self.write("NotPayable, "); + } else { + self.write("(), "); + } + } + + fn parse_and_write_outputs(&mut self, outputs: &[OutputAbi]) { + match outputs.len() { + 0 => { + self.write("()"); + }, + 1 => { + let adjusted = self.adjust_type_name_with_env_api(&outputs[0].type_names.rust); + self.write(adjusted); + }, + _ => { + self.write(format!("MultiValue{}<", outputs.len())); + for (i, output) in outputs.iter().enumerate() { + if i > 0 { + self.write(", "); + } + let adjusted = self.adjust_type_name_with_env_api(&output.type_names.rust); + self.write(adjusted); + } + self.write(">"); + }, + } + } + + fn write_enum( + &mut self, + enum_variants: &Vec, + type_description: &TypeDescription, + name: &str, + ) { + if self.enum_contains_struct_variant(enum_variants) { + self.write("\n#[rustfmt::skip]"); + } + + self.start_write_type("enum", type_description, name); + + if enum_variants.is_empty() { + self.writeln("}"); + return; + } + + self.writeln(""); + + for variant in enum_variants { + self.write(format!(" {}", variant.name)); + if variant.fields.is_empty() { + self.writeln(","); + continue; + } + + if variant.fields[0].name == ZERO { + self.write_tuple_in_variant(&variant.fields); + } else { + self.write_struct_in_variant(&variant.fields); + } + } + self.writeln("}"); + } + + fn write_struct( + &mut self, + struct_fields: &Vec, + type_description: &TypeDescription, + name: &str, + ) { + self.start_write_type("struct", type_description, name); + + if struct_fields.is_empty() { + self.writeln("}"); + return; + } + + self.writeln(""); + + for field in struct_fields { + let adjusted_type_name = self.adjust_type_name_with_api(&field.field_type.rust); + self.writeln(format!(" pub {}: {adjusted_type_name},", field.name)); + } + + self.writeln("}"); + } + + fn write_tuple_in_variant(&mut self, fields: &[StructFieldDescription]) { + self.write("("); + for (i, field) in fields.iter().enumerate() { + if i > 0 { + self.write(", "); + } + let adjusted_type_name = self.adjust_type_name_with_api(&field.field_type.rust); + self.write(adjusted_type_name); + } + + self.writeln("),"); + } + + fn write_struct_in_variant(&mut self, fields: &[StructFieldDescription]) { + self.writeln(" {"); + + for field in fields { + let adjusted_type_name = self.adjust_type_name_with_api(&field.field_type.rust); + self.writeln(format!(" {}: {adjusted_type_name},", field.name,)); + } + + self.writeln(" },"); + } + + pub fn clean_paths(&mut self, rust_type: &str) -> String { + let paths = extract_paths(rust_type); + + let processed_paths = self.process_paths(&paths); + + let processed_rust_type = process_rust_type(rust_type.to_string(), paths, processed_paths); + + self.rename_path_with_custome_config(&processed_rust_type) + } + + fn start_write_type( + &mut self, + type_type: &str, + type_description: &TypeDescription, + name: &str, + ) { + self.writeln(""); + self.writeln("#[type_abi]"); + self.write_macro_attributes(&type_description.macro_attributes); + self.write(format!(r#"pub {type_type} {name}"#)); + + if name.contains("") { + self.writeln( + " +where + Api: ManagedTypeApi,", + ); + } else { + self.write(" "); + } + + self.write("{"); + } + + pub fn write_macro_attributes(&mut self, macro_attributes: &[String]) { + if macro_attributes.is_empty() { + self.writeln("#[derive(TopEncode, TopDecode)]"); + } else { + self.writeln(format!("#[derive({})]", macro_attributes.join(", "))); + } + } + + fn adjust_type_name_with_env_api(&mut self, original_rust_name: &str) -> String { + self.clean_paths( + &original_rust_name + .replace("multiversx_sc::api::uncallable::UncallableApi", "Env::Api") + .replace("$API", "Env::Api"), + ) + } + + fn adjust_type_name_with_api(&mut self, original_rust_name: &str) -> String { + self.clean_paths( + &original_rust_name + .replace("multiversx_sc::api::uncallable::UncallableApi", "Api") + .replace("$API", "Api"), + ) + } + + fn write_end_of_function(&mut self) { + self.writeln(" }"); + } + + fn rename_path_with_custome_config(&self, processed_type: &str) -> String { + let mut renamed_processed_type = processed_type.to_owned(); + + if let Some(paths_rename) = &self.proxy_config.path_rename { + for path_rename in paths_rename { + if processed_type.contains(&path_rename.from) { + renamed_processed_type = + renamed_processed_type.replace(&path_rename.from, &path_rename.to); + } + } + } + + renamed_processed_type + } + + fn process_paths(&self, paths: &Vec) -> Vec { + let mut processed_paths: Vec = Vec::new(); + let crate_name = self.contract_abi.get_crate_name_for_code(); + + for path in paths { + let type_rust_name = path.split("::").last().unwrap(); + if crate_name == extract_struct_crate(path) + || TYPES_FROM_FRAMEWORK.contains(&type_rust_name) + { + processed_paths.push(type_rust_name.to_string()); + } else { + processed_paths.push(path.to_string()); + } + } + + processed_paths + } + + fn enum_contains_struct_variant(&self, enum_variants: &Vec) -> bool { + for variant in enum_variants { + if variant.fields.is_empty() { + continue; + } + + if variant.fields[0].name != ZERO { + return true; + } + } + + false + } +} + +#[cfg(test)] +pub mod tests { + use multiversx_sc::abi::{BuildInfoAbi, ContractAbi, ContractCrateBuildAbi, FrameworkBuildAbi}; + + use crate::contract::{meta_config::MetaConfig, sc_config::ProxyConfigSerde}; + + use super::ProxyGenerator; + + #[test] + fn clean_paths_unsanitized_test() { + let build_info = BuildInfoAbi { + contract_crate: ContractCrateBuildAbi { + name: "contract-crate", + version: "0.0.0", + git_version: "0.0.0", + }, + framework: FrameworkBuildAbi::create(), + }; + + let original_contract_abi = ContractAbi::new(build_info, &[""], "contract-crate", false); + let meta_config = MetaConfig::create(original_contract_abi, false); + let mut proxy_generator = ProxyGenerator { + meta_config: &meta_config, + file: None, + proxy_config: &ProxyConfigSerde::new(), + contract_abi: &meta_config.original_contract_abi, + }; + + let cleaned_path_unsanitized = proxy_generator.clean_paths( + "(other_crate::contract_crate::TestStruct, Option>)", + ); + let expected_result_unsanitized = + "(other_crate::contract_crate::TestStruct, Option>)"; + + assert_eq!( + expected_result_unsanitized, + cleaned_path_unsanitized.as_str() + ); + } + + #[test] + fn clean_paths_sanitized_test() { + let build_info = BuildInfoAbi { + contract_crate: ContractCrateBuildAbi { + name: "contract-crate", + version: "0.0.0", + git_version: "0.0.0", + }, + framework: FrameworkBuildAbi::create(), + }; + + let original_contract_abi = ContractAbi::new(build_info, &[""], "contract-crate", false); + let meta_config = MetaConfig::create(original_contract_abi, false); + let mut proxy_generator = ProxyGenerator { + meta_config: &meta_config, + file: None, + proxy_config: &ProxyConfigSerde::new(), + contract_abi: &meta_config.original_contract_abi, + }; + + let cleaned_path_sanitized = proxy_generator.clean_paths( + "(contract_crate::other_crate::TestStruct, Option>)", + ); + let expected_result_sanitized = "(TestStruct, Option>)"; + + assert_eq!(expected_result_sanitized, cleaned_path_sanitized.as_str()); + } +} diff --git a/framework/meta-lib/src/contract/generate_proxy/proxy_process_type_name.rs b/framework/meta-lib/src/contract/generate_proxy/proxy_process_type_name.rs new file mode 100644 index 0000000000..350243d662 --- /dev/null +++ b/framework/meta-lib/src/contract/generate_proxy/proxy_process_type_name.rs @@ -0,0 +1,37 @@ +pub(super) fn proxy_type_name(contract_trait_name: &str) -> String { + format!("{contract_trait_name}Proxy") +} + +pub(super) fn proxy_methods_type_name(contract_trait_name: &str) -> String { + format!("{contract_trait_name}ProxyMethods") +} + +pub(super) fn extract_struct_crate(struct_path: &str) -> String { + let crate_name = struct_path.split("::").next().unwrap_or(struct_path); + crate_name.to_string() +} + +pub(super) fn process_rust_type( + rust_type: String, + paths: Vec, + processed_paths: Vec, +) -> String { + let mut processed_rust_type: String = rust_type.to_string().clone(); + for index in 0..paths.len() { + processed_rust_type = processed_rust_type.replace( + paths.get(index).unwrap(), + processed_paths.get(index).unwrap(), + ); + } + + processed_rust_type +} + +pub(super) fn extract_paths(rust_type: &str) -> Vec { + let delimiters = "<>,()[] "; + rust_type + .split(|c| delimiters.contains(c)) + .filter(|s| !s.is_empty()) + .map(|s| s.to_string()) + .collect() +} diff --git a/framework/meta/src/cmd/contract/generate_snippets.rs b/framework/meta-lib/src/contract/generate_snippets.rs similarity index 100% rename from framework/meta/src/cmd/contract/generate_snippets.rs rename to framework/meta-lib/src/contract/generate_snippets.rs diff --git a/framework/meta/src/cmd/contract/generate_snippets/snippet_crate_gen.rs b/framework/meta-lib/src/contract/generate_snippets/snippet_crate_gen.rs similarity index 55% rename from framework/meta/src/cmd/contract/generate_snippets/snippet_crate_gen.rs rename to framework/meta-lib/src/contract/generate_snippets/snippet_crate_gen.rs index d65b1b6094..fc02e3f648 100644 --- a/framework/meta/src/cmd/contract/generate_snippets/snippet_crate_gen.rs +++ b/framework/meta-lib/src/contract/generate_snippets/snippet_crate_gen.rs @@ -1,9 +1,17 @@ +use colored::Colorize; use std::{ - fs::{self, File}, + fs::{self, File, OpenOptions}, io::Write, }; +use crate::version_history; + static SNIPPETS_SOURCE_FILE_NAME: &str = "interactor_main.rs"; +static SC_CONFIG_PATH: &str = "../sc-config.toml"; +static FULL_PROXY_ENTRY: &str = r#"[[proxy]] +path = "interact-rs/src/proxy.rs" + "#; +static PROXY_PATH: &str = "interact-rs/src/proxy.rs"; pub(crate) fn create_snippets_folder(snippets_folder_path: &str) { // returns error if folder already exists, so we ignore the result @@ -52,6 +60,8 @@ pub(crate) fn create_snippets_cargo_toml( } }; + let last_release_version = &version_history::LAST_VERSION; + writeln!( &mut file, r#"[package] @@ -69,10 +79,17 @@ path = "src/{SNIPPETS_SOURCE_FILE_NAME}" path = ".." [dependencies.multiversx-sc-snippets] -version = "0.47.5" +version = "{last_release_version}" -# [workspace] +[dependencies.multiversx-sc] +version = "{last_release_version}" +[dependencies] +clap = {{ version = "4.4.7", features = ["derive"] }} +serde = {{ version = "1.0", features = ["derive"] }} +toml = "0.8.6" + +# [workspace] "# ) .unwrap(); @@ -92,7 +109,48 @@ pub(crate) fn create_and_get_lib_file(snippets_folder_path: &str, overwrite: boo } else { match File::options().create_new(true).write(true).open(&lib_path) { Ok(f) => f, - Err(_) => panic!("{lib_path} file already exists, --overwrite option was not provided"), + Err(_) => { + println!( + "{}", + format!("{lib_path} file already exists, --overwrite option was not provided",) + .yellow() + ); + File::options().write(true).open(&lib_path).unwrap() + }, } } } + +pub(crate) fn create_sc_config_file(overwrite: bool) { + // check if the file should be overwritten or if it already exists + let mut file = if overwrite || !file_exists(SC_CONFIG_PATH) { + File::create(SC_CONFIG_PATH).unwrap() + } else { + // file already exists + let file = OpenOptions::new() + .read(true) + .append(true) + .open(SC_CONFIG_PATH) + .unwrap(); + + if file_contains_proxy_path(SC_CONFIG_PATH).unwrap_or(false) { + return; + } + + file + }; + + // write full proxy toml entry to the file + writeln!(&mut file, "\n{FULL_PROXY_ENTRY}").unwrap(); +} + +fn file_exists(path: &str) -> bool { + fs::metadata(path).is_ok() +} + +fn file_contains_proxy_path(file_path: &str) -> std::io::Result { + let file_content = fs::read_to_string(file_path)?; + let proxy_entry = format!("path = \"{}\"", PROXY_PATH); + + Ok(file_content.contains(&proxy_entry)) +} diff --git a/framework/meta/src/cmd/contract/generate_snippets/snippet_gen_common.rs b/framework/meta-lib/src/contract/generate_snippets/snippet_gen_common.rs similarity index 100% rename from framework/meta/src/cmd/contract/generate_snippets/snippet_gen_common.rs rename to framework/meta-lib/src/contract/generate_snippets/snippet_gen_common.rs diff --git a/framework/meta/src/cmd/contract/generate_snippets/snippet_gen_main.rs b/framework/meta-lib/src/contract/generate_snippets/snippet_gen_main.rs similarity index 62% rename from framework/meta/src/cmd/contract/generate_snippets/snippet_gen_main.rs rename to framework/meta-lib/src/contract/generate_snippets/snippet_gen_main.rs index b158bcd0ce..919420f485 100644 --- a/framework/meta/src/cmd/contract/generate_snippets/snippet_gen_main.rs +++ b/framework/meta-lib/src/contract/generate_snippets/snippet_gen_main.rs @@ -2,18 +2,18 @@ use std::fs::File; use multiversx_sc::abi::ContractAbi; -use crate::cli_args::GenerateSnippetsArgs; +use crate::cli::GenerateSnippetsArgs; use super::{ super::meta_config::MetaConfig, snippet_crate_gen::{ - create_and_get_lib_file, create_snippets_cargo_toml, create_snippets_folder, - create_snippets_gitignore, create_src_folder, + create_and_get_lib_file, create_sc_config_file, create_snippets_cargo_toml, + create_snippets_folder, create_snippets_gitignore, create_src_folder, }, - snippet_sc_functions_gen::write_state_struct_impl, + snippet_sc_functions_gen::write_interact_struct_impl, snippet_template_gen::{ - write_contract_type_alias, write_snippet_constants, write_snippet_imports, - write_snippet_main_function, write_state_struct_declaration, + write_interact_struct_declaration, write_snippet_constants, write_snippet_imports, + write_snippet_main_function, write_snippet_state_impl, write_state_struct_declaration, }, }; @@ -21,14 +21,12 @@ impl MetaConfig { pub fn generate_rust_snippets(&self, args: &GenerateSnippetsArgs) { let main_contract = self.sc_config.main_contract(); let crate_name = &main_contract.contract_name; - let snake_case_name = &main_contract.public_name_snake_case(); let wasm_output_file_path_expr = format!("\"mxsc:../output/{crate_name}.mxsc.json\""); let file = create_snippets_crate_and_get_lib_file(&self.snippets_dir, crate_name, args.overwrite); write_snippets_to_file( file, &self.original_contract_abi, - snake_case_name, &wasm_output_file_path_expr, ); } @@ -44,19 +42,16 @@ fn create_snippets_crate_and_get_lib_file( create_snippets_gitignore(snippets_folder_path, overwrite); create_snippets_cargo_toml(snippets_folder_path, contract_crate_name, overwrite); create_src_folder(snippets_folder_path); + create_sc_config_file(overwrite); create_and_get_lib_file(snippets_folder_path, overwrite) } -fn write_snippets_to_file( - mut file: File, - abi: &ContractAbi, - snake_case_name: &str, - wasm_output_file_path_expr: &str, -) { - write_snippet_imports(&mut file, snake_case_name); +fn write_snippets_to_file(mut file: File, abi: &ContractAbi, wasm_output_file_path_expr: &str) { + write_snippet_imports(&mut file); write_snippet_constants(&mut file); - write_contract_type_alias(&mut file, snake_case_name); write_snippet_main_function(&mut file, abi); write_state_struct_declaration(&mut file); - write_state_struct_impl(&mut file, abi, wasm_output_file_path_expr); + write_snippet_state_impl(&mut file); + write_interact_struct_declaration(&mut file); + write_interact_struct_impl(&mut file, abi, wasm_output_file_path_expr); } diff --git a/framework/meta/src/cmd/contract/generate_snippets/snippet_sc_functions_gen.rs b/framework/meta-lib/src/contract/generate_snippets/snippet_sc_functions_gen.rs similarity index 58% rename from framework/meta/src/cmd/contract/generate_snippets/snippet_sc_functions_gen.rs rename to framework/meta-lib/src/contract/generate_snippets/snippet_sc_functions_gen.rs index 94b0cc8a43..09d6aa7660 100644 --- a/framework/meta/src/cmd/contract/generate_snippets/snippet_sc_functions_gen.rs +++ b/framework/meta-lib/src/contract/generate_snippets/snippet_sc_functions_gen.rs @@ -1,36 +1,31 @@ use std::{fs::File, io::Write}; -use multiversx_sc::abi::{ContractAbi, EndpointAbi, EndpointMutabilityAbi, InputAbi, OutputAbi}; +use multiversx_sc::abi::{ContractAbi, EndpointAbi, EndpointMutabilityAbi, InputAbi}; use super::{snippet_gen_common::write_newline, snippet_type_map::map_abi_type_to_rust_type}; -pub(crate) fn write_state_struct_impl( +pub(crate) fn write_interact_struct_impl( file: &mut File, abi: &ContractAbi, wasm_output_file_path_expr: &str, ) { writeln!( file, - r#"impl State {{ + r#"impl ContractInteract {{ async fn new() -> Self {{ let mut interactor = Interactor::new(GATEWAY).await; - let wallet_address = interactor.register_wallet(Wallet::from_pem_file(PEM).unwrap()); - let sc_addr_expr = if SC_ADDRESS == "" {{ - DEFAULT_ADDRESS_EXPR.to_string() - }} else {{ - "bech32:".to_string() + SC_ADDRESS - }}; + let wallet_address = interactor.register_wallet(test_wallets::alice()); + let contract_code = BytesValue::interpret_from( {}, &InterpreterContext::default(), ); - let contract = ContractType::new(sc_addr_expr); - State {{ + ContractInteract {{ interactor, wallet_address, contract_code, - contract, + state: State::load_state() }} }} "#, @@ -38,38 +33,40 @@ pub(crate) fn write_state_struct_impl( ) .unwrap(); - write_deploy_method_impl(file, &abi.constructors[0]); + write_deploy_method_impl(file, &abi.constructors[0], &abi.name); for endpoint_abi in &abi.endpoints { - write_endpoint_impl(file, endpoint_abi); + write_endpoint_impl(file, endpoint_abi, &abi.name); } // close impl block brackets writeln!(file, "}}").unwrap(); } -fn write_deploy_method_impl(file: &mut File, init_abi: &EndpointAbi) { +fn write_deploy_method_impl(file: &mut File, init_abi: &EndpointAbi, name: &String) { write_method_declaration(file, "deploy"); write_endpoint_args_declaration(file, &init_abi.inputs); + let proxy_name = format!("{}Proxy", name); - let output_type = map_output_types_to_rust_types(&init_abi.outputs); writeln!( file, - r#" let (new_address, _) = self + r#" let new_address = self .interactor - .sc_deploy_get_result::<_, {}>( - ScDeployStep::new() - .call(self.contract.{}({})) - .from(&self.wallet_address) - .code(&self.contract_code) - .expect(TxExpect::ok().additional_error_message("deploy failed: ")), - ) + .tx() + .from(&self.wallet_address) + .typed(proxy::{}) + .init({}) + .code(&self.contract_code) + .returns(ReturnsNewAddress) + .prepare_async() + .run() .await; -s let new_address_bech32 = bech32::encode(&new_address); + self.state + .set_address(Bech32Address::from_bech32_string(new_address_bech32.clone())); + println!("new address: {{new_address_bech32}}");"#, - output_type, - init_abi.rust_method_name, + proxy_name, endpoint_args_when_called(init_abi.inputs.as_slice()), ) .unwrap(); @@ -79,14 +76,14 @@ s write_newline(file); } -fn write_endpoint_impl(file: &mut File, endpoint_abi: &EndpointAbi) { +fn write_endpoint_impl(file: &mut File, endpoint_abi: &EndpointAbi, name: &String) { write_method_declaration(file, &endpoint_abi.rust_method_name); write_payments_declaration(file, &endpoint_abi.payable_in_tokens); write_endpoint_args_declaration(file, &endpoint_abi.inputs); if matches!(endpoint_abi.mutability, EndpointMutabilityAbi::Readonly) { - write_contract_query(file, endpoint_abi); + write_contract_query(file, endpoint_abi, name); } else { - write_contract_call(file, endpoint_abi); + write_contract_call(file, endpoint_abi, name); } // close method block brackets @@ -116,7 +113,7 @@ fn write_payments_declaration(file: &mut File, accepted_tokens: &[String]) { } else { writeln!( file, - " let token_id = b\"\"; + " let token_id = String::new(); let token_nonce = 0u64; let token_amount = {};", biguint_default.get_default_value_expr() @@ -133,7 +130,7 @@ fn write_endpoint_args_declaration(file: &mut File, inputs: &[InputAbi]) { } for input in inputs { - let rust_type = map_abi_type_to_rust_type(input.type_name.clone()); + let rust_type = map_abi_type_to_rust_type(input.type_names.abi.clone()); writeln!( file, " let {} = {};", @@ -157,31 +154,31 @@ fn endpoint_args_when_called(inputs: &[InputAbi]) -> String { result } -fn write_contract_call(file: &mut File, endpoint_abi: &EndpointAbi) { +fn write_contract_call(file: &mut File, endpoint_abi: &EndpointAbi, name: &String) { let payment_snippet = if endpoint_abi.payable_in_tokens.is_empty() { "" } else if endpoint_abi.payable_in_tokens[0] == "EGLD" { - "\n .egld_value(egld_amount)" + "\n .egld(egld_amount)" } else { - "\n .esdt_transfer(token_id.to_vec(), token_nonce, token_amount)" + "\n .payment((TokenIdentifier::from(token_id.as_str()), token_nonce, token_amount))" }; - let output_type = map_output_types_to_rust_types(&endpoint_abi.outputs); writeln!( file, - r#" let response: TypedResponse<{}> = self + r#" let response = self .interactor - .sc_call_use_result( - ScCallStep::new() - .call(self.contract.{}({})) - .from(&self.wallet_address){} - .expect(TxExpect::ok().additional_error_message("SC call failed: ")), - ) + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .typed(proxy::{}Proxy) + .{}({}){} + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() .await; - let result = response.result.unwrap(); - println!("Result: {{result:?}}");"#, - output_type, + println!("Result: {{response:?}}");"#, + name, endpoint_abi.rust_method_name, endpoint_args_when_called(endpoint_abi.inputs.as_slice()), payment_snippet, @@ -189,48 +186,24 @@ fn write_contract_call(file: &mut File, endpoint_abi: &EndpointAbi) { .unwrap(); } -fn write_contract_query(file: &mut File, endpoint_abi: &EndpointAbi) { - let output_type = map_output_types_to_rust_types(&endpoint_abi.outputs); +fn write_contract_query(file: &mut File, endpoint_abi: &EndpointAbi, name: &String) { writeln!( file, - r#" let result_value: {} = self + r#" let result_value = self .interactor - .vm_query(self.contract.{}({})) + .query() + .to(self.state.current_address()) + .typed(proxy::{}Proxy) + .{}({}) + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() .await; -"#, - output_type, + + println!("Result: {{result_value:?}}");"#, + name, endpoint_abi.rust_method_name, endpoint_args_when_called(endpoint_abi.inputs.as_slice()), ) .unwrap(); } - -fn map_output_types_to_rust_types(outputs: &[OutputAbi]) -> String { - let results_len = outputs.len(); - if results_len == 0 { - return "()".to_string(); - } - - // format to be the same as when multi-value is an argument - // for results, each type is a different array entry - let mut input_str = String::new(); - if results_len > 1 { - input_str += "multi"; - input_str += "<"; - } - - for (i, output) in outputs.iter().enumerate() { - input_str += &output.type_name; - - if i < results_len - 1 { - input_str += ","; - } - } - - if results_len > 1 { - input_str += ">"; - } - - let output_rust_type = map_abi_type_to_rust_type(input_str); - output_rust_type.get_type_name().to_string() -} diff --git a/framework/meta-lib/src/contract/generate_snippets/snippet_template_gen.rs b/framework/meta-lib/src/contract/generate_snippets/snippet_template_gen.rs new file mode 100644 index 0000000000..7223f1d6c4 --- /dev/null +++ b/framework/meta-lib/src/contract/generate_snippets/snippet_template_gen.rs @@ -0,0 +1,149 @@ +use std::{fs::File, io::Write}; + +use multiversx_sc::abi::ContractAbi; + +use super::snippet_gen_common::write_newline; + +pub(crate) fn write_snippet_imports(file: &mut File) { + writeln!( + file, + "#![allow(non_snake_case)] + +mod proxy; + +use multiversx_sc_snippets::imports::*; +use multiversx_sc_snippets::sdk; +use serde::{{Deserialize, Serialize}}; +use std::{{ + io::{{Read, Write}}, + path::Path, +}}; +" + ) + .unwrap(); + + write_newline(file); +} + +pub(crate) fn write_snippet_constants(file: &mut File) { + writeln!( + file, + "const GATEWAY: &str = sdk::blockchain::DEVNET_GATEWAY; +const STATE_FILE: &str = \"state.toml\"; +" + ) + .unwrap(); + + write_newline(file); +} + +pub(crate) fn write_snippet_main_function(file: &mut File, abi: &ContractAbi) { + writeln!( + file, + "#[tokio::main] +async fn main() {{ + env_logger::init(); + + let mut args = std::env::args(); + let _ = args.next(); + let cmd = args.next().expect(\"at least one argument required\"); + let mut interact = ContractInteract::new().await; + match cmd.as_str() {{" + ) + .unwrap(); + + // all contracts have a deploy snippet + writeln!(file, r#" "deploy" => interact.deploy().await,"#).unwrap(); + + for endpoint in &abi.endpoints { + writeln!( + file, + r#" "{}" => interact.{}().await,"#, + endpoint.name, endpoint.rust_method_name + ) + .unwrap(); + } + + // general case of "command not found" + close curly brackets + writeln!( + file, + " _ => panic!(\"unknown command: {{}}\", &cmd), + }} +}}" + ) + .unwrap(); + + write_newline(file); +} + +pub(crate) fn write_interact_struct_declaration(file: &mut File) { + writeln!( + file, + "struct ContractInteract {{ + interactor: Interactor, + wallet_address: Address, + contract_code: BytesValue, + state: State +}}" + ) + .unwrap(); + + write_newline(file); +} + +pub(crate) fn write_state_struct_declaration(file: &mut File) { + writeln!( + file, + " +#[derive(Debug, Default, Serialize, Deserialize)] +struct State {{ + contract_address: Option +}}" + ) + .unwrap(); + + write_newline(file); +} + +pub(crate) fn write_snippet_state_impl(file: &mut File) { + writeln!( + file, + r#"impl State {{ + // Deserializes state from file + pub fn load_state() -> Self {{ + if Path::new(STATE_FILE).exists() {{ + let mut file = std::fs::File::open(STATE_FILE).unwrap(); + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + toml::from_str(&content).unwrap() + }} else {{ + Self::default() + }} + }} + + /// Sets the contract address + pub fn set_address(&mut self, address: Bech32Address) {{ + self.contract_address = Some(address); + }} + + /// Returns the contract address + pub fn current_address(&self) -> &Bech32Address {{ + self.contract_address + .as_ref() + .expect("no known contract, deploy first") + }} + }} + + impl Drop for State {{ + // Serializes state to file + fn drop(&mut self) {{ + let mut file = std::fs::File::create(STATE_FILE).unwrap(); + file.write_all(toml::to_string(self).unwrap().as_bytes()) + .unwrap(); + }} + }}"# + ) + .unwrap(); + + write_newline(file); +} diff --git a/framework/meta/src/cmd/contract/generate_snippets/snippet_type_map.rs b/framework/meta-lib/src/contract/generate_snippets/snippet_type_map.rs similarity index 98% rename from framework/meta/src/cmd/contract/generate_snippets/snippet_type_map.rs rename to framework/meta-lib/src/contract/generate_snippets/snippet_type_map.rs index 803f8c6b29..1a0adb3423 100644 --- a/framework/meta/src/cmd/contract/generate_snippets/snippet_type_map.rs +++ b/framework/meta-lib/src/contract/generate_snippets/snippet_type_map.rs @@ -13,10 +13,6 @@ pub struct RustTypeString { } impl RustTypeString { - pub fn get_type_name(&self) -> &str { - &self.type_name - } - pub fn get_default_value_expr(&self) -> &str { if !self.contains_custom_types { &self.default_value_expr @@ -183,7 +179,7 @@ fn get_abi_type(abi_type_str: &str) -> AbiType { } } -fn handle_abi_type(type_string: &mut RustTypeString, abi_type_str: String) { +pub fn handle_abi_type(type_string: &mut RustTypeString, abi_type_str: String) { let abi_type = get_abi_type(&abi_type_str); match abi_type { AbiType::UserDefined(user_type) => { diff --git a/framework/meta/src/cmd/contract/meta_abi.rs b/framework/meta-lib/src/contract/meta_abi.rs similarity index 100% rename from framework/meta/src/cmd/contract/meta_abi.rs rename to framework/meta-lib/src/contract/meta_abi.rs diff --git a/framework/meta/src/cmd/contract/meta_config.rs b/framework/meta-lib/src/contract/meta_config.rs similarity index 93% rename from framework/meta/src/cmd/contract/meta_config.rs rename to framework/meta-lib/src/contract/meta_config.rs index f492884743..e26a4f4e16 100644 --- a/framework/meta/src/cmd/contract/meta_config.rs +++ b/framework/meta-lib/src/contract/meta_config.rs @@ -3,8 +3,8 @@ use std::fs; use multiversx_sc::abi::ContractAbi; use crate::{ - cli_args::BuildArgs, find_workspace::find_current_workspace, - print_util::print_workspace_target_dir, tools::check_tools_installed, CargoTomlContents, + cargo_toml_contents::CargoTomlContents, cli::BuildArgs, print_util::print_workspace_target_dir, + tools::check_tools_installed, tools::find_current_workspace, }; use super::{ @@ -40,6 +40,10 @@ impl MetaConfig { } } + pub fn reload_sc_config(&mut self) { + self.sc_config = ScConfig::load_from_crate_or_default("..", &self.original_contract_abi); + } + /// Generates all code for the wasm crate(s). pub fn generate_wasm_crates(&mut self) { self.remove_unexpected_wasm_crates(); @@ -175,7 +179,7 @@ fn copy_to_wasm_unmanaged_ei() { #[cfg(test)] mod tests { - use crate::cmd::contract::sc_config::ContractVariantProfile; + use crate::contract::sc_config::ContractVariantProfile; const EXPECTED_CARGO_TOML_CONTENTS: &str = "# Code generated by the multiversx-sc build system. DO NOT EDIT. @@ -201,11 +205,14 @@ debug = false panic = \"abort\" overflow-checks = false +[profile.dev] +panic = \"abort\" + [dependencies.test-crate-name] path = \"..\" [dependencies.multiversx-sc-wasm-adapter] -version = \"0.47.5\" +version = \"x.y.z\" path = \"../../../../framework/wasm-adapter\" [workspace] @@ -218,7 +225,7 @@ members = [\".\"] name: "test".to_string(), edition: "2021".to_string(), profile: ContractVariantProfile::default(), - framework_version: "0.47.5".to_string(), + framework_version: "x.y.z".to_string(), framework_path: Option::Some("../../../framework/base".to_string()), contract_features: Vec::::new(), }; diff --git a/framework/meta/src/cmd/contract/sc_config.rs b/framework/meta-lib/src/contract/sc_config.rs similarity index 89% rename from framework/meta/src/cmd/contract/sc_config.rs rename to framework/meta-lib/src/contract/sc_config.rs index 16ac60826e..2fac2e38eb 100644 --- a/framework/meta/src/cmd/contract/sc_config.rs +++ b/framework/meta-lib/src/contract/sc_config.rs @@ -3,6 +3,7 @@ mod contract_variant_builder; mod contract_variant_settings; mod contract_variant_validate; mod sc_config_model; +mod sc_config_proxy; mod sc_config_serde; mod wasm_build; mod wasm_clean; @@ -12,6 +13,7 @@ mod wasm_update; pub use contract_variant::ContractVariant; pub use contract_variant_settings::{ContractVariantProfile, ContractVariantSettings}; pub use sc_config_model::ScConfig; +pub use sc_config_proxy::ProxyConfigSerde; pub use sc_config_serde::{ ContractVariantProfileSerde, ContractVariantSerde, MultiContractGeneralSettingsSerde, ScConfigSerde, diff --git a/framework/meta/src/cmd/contract/sc_config/contract_variant.rs b/framework/meta-lib/src/contract/sc_config/contract_variant.rs similarity index 87% rename from framework/meta/src/cmd/contract/sc_config/contract_variant.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant.rs index 6b6cf70cc4..4f027e066e 100644 --- a/framework/meta/src/cmd/contract/sc_config/contract_variant.rs +++ b/framework/meta-lib/src/contract/sc_config/contract_variant.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; -use super::ContractVariantSettings; -use crate::cli_args::BuildArgs; +use super::{contract_variant_builder::default_wasm_crate_name, ContractVariantSettings}; +use crate::cli::BuildArgs; use multiversx_sc::abi::ContractAbi; /// Represents a contract created by the framework when building. @@ -35,6 +35,19 @@ pub struct ContractVariant { } impl ContractVariant { + pub fn default_from_abi(abi: &ContractAbi) -> Self { + let default_contract_config_name = abi.build_info.contract_crate.name.to_string(); + let wasm_crate_name = default_wasm_crate_name(&default_contract_config_name); + ContractVariant { + main: true, + settings: ContractVariantSettings::default(), + contract_id: default_contract_config_name.clone(), + contract_name: default_contract_config_name, + wasm_crate_name, + abi: abi.clone(), + } + } + pub fn public_name_snake_case(&self) -> String { self.contract_name.replace('-', "_") } @@ -154,6 +167,9 @@ impl ContractVariant { /// Should correspond to all wasm exported functions. pub fn all_exported_function_names(&self) -> Vec { let mut result = vec!["init".to_string()]; + if !self.abi.upgrade_constructors.is_empty() { + result.push("upgrade".to_string()) + } result.append(&mut self.endpoint_names()); if self.abi.has_callback { result.push("callBack".to_string()); @@ -169,6 +185,10 @@ impl std::fmt::Debug for ContractVariant { .field("config_name", &self.contract_id) .field("public_name", &self.contract_name) .field("num-constructors", &self.abi.constructors.len()) + .field( + "num-upgrade-constructors", + &self.abi.upgrade_constructors.len(), + ) .field("num-endpoints", &self.abi.endpoints.len()) .field("settings", &self.settings) .finish() diff --git a/framework/meta/src/cmd/contract/sc_config/contract_variant_builder.rs b/framework/meta-lib/src/contract/sc_config/contract_variant_builder.rs similarity index 90% rename from framework/meta/src/cmd/contract/sc_config/contract_variant_builder.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant_builder.rs index d447ab4a0a..bb6a439245 100644 --- a/framework/meta/src/cmd/contract/sc_config/contract_variant_builder.rs +++ b/framework/meta-lib/src/contract/sc_config/contract_variant_builder.rs @@ -169,11 +169,13 @@ fn collect_add_endpoints( fn build_contract_abi(builder: ContractVariantBuilder, original_abi: &ContractAbi) -> ContractAbi { let mut constructors = Vec::new(); + let mut upgrade_constructors = Vec::new(); let mut endpoints = Vec::new(); let mut promise_callbacks = Vec::new(); for endpoint_abi in builder.collected_endpoints { match endpoint_abi.endpoint_type { multiversx_sc::abi::EndpointTypeAbi::Init => constructors.push(endpoint_abi), + multiversx_sc::abi::EndpointTypeAbi::Upgrade => upgrade_constructors.push(endpoint_abi), multiversx_sc::abi::EndpointTypeAbi::Endpoint => endpoints.push(endpoint_abi), multiversx_sc::abi::EndpointTypeAbi::PromisesCallback => { promise_callbacks.push(endpoint_abi) @@ -188,6 +190,7 @@ fn build_contract_abi(builder: ContractVariantBuilder, original_abi: &ContractAb docs: original_abi.docs.clone(), name: original_abi.name.clone(), constructors, + upgrade_constructors, endpoints, promise_callbacks, events: original_abi.events.clone(), @@ -197,7 +200,7 @@ fn build_contract_abi(builder: ContractVariantBuilder, original_abi: &ContractAb } } -fn default_wasm_crate_name(contract_name: &str) -> String { +pub(crate) fn default_wasm_crate_name(contract_name: &str) -> String { format!("{contract_name}-wasm") } @@ -233,7 +236,7 @@ fn set_main_contract_flag( ) } else { let first_contract = contracts.get_mut(0).unwrap_or_else(|| { - panic!("Cannot set default contract because no optput contract was specified.") + panic!("Cannot set default contract because no output contract was specified.") }); first_contract.main = true; } @@ -260,22 +263,42 @@ impl ScConfig { .iter() .map(ContractVariantBuilder::map_from_config) .collect(); - collect_unlabelled_endpoints(&mut contract_builders, original_abi); - collect_labelled_endpoints(&mut contract_builders, original_abi); - collect_add_endpoints(&mut contract_builders, original_abi); - process_labels_for_contracts(&mut contract_builders, &config.labels_for_contracts); + collect_and_process_endpoints( + &mut contract_builders, + original_abi, + &config.labels_for_contracts, + ); + let mut contracts: Vec = contract_builders .into_values() .map(|builder| build_contract(builder, original_abi)) .collect(); + if contracts.is_empty() { + contracts.push(ContractVariant::default_from_abi(original_abi)); + } set_main_contract_flag(&mut contracts, &config.settings.main); validate_contract_variants(&contracts); + let default_contract_config_name = config.settings.main.clone().unwrap_or_default(); ScConfig { - default_contract_config_name: config.settings.main.clone().unwrap_or_default(), + default_contract_config_name, contracts, + proxy_configs: config.proxy.clone(), } } +} + +fn collect_and_process_endpoints( + contract_builders: &mut HashMap, + original_abi: &ContractAbi, + labels_for_contracts: &HashMap>, +) { + collect_unlabelled_endpoints(contract_builders, original_abi); + collect_labelled_endpoints(contract_builders, original_abi); + collect_add_endpoints(contract_builders, original_abi); + process_labels_for_contracts(contract_builders, labels_for_contracts); +} +impl ScConfig { /// Provides the config for the cases where no `multicontract.toml` file is available. /// /// The default configuration contains a single main contract, with all endpoints. @@ -292,6 +315,7 @@ impl ScConfig { wasm_crate_name, abi: original_abi.clone(), }], + proxy_configs: Vec::new(), } } diff --git a/framework/meta/src/cmd/contract/sc_config/contract_variant_settings.rs b/framework/meta-lib/src/contract/sc_config/contract_variant_settings.rs similarity index 96% rename from framework/meta/src/cmd/contract/sc_config/contract_variant_settings.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant_settings.rs index a6a40a4142..b0af57deef 100644 --- a/framework/meta/src/cmd/contract/sc_config/contract_variant_settings.rs +++ b/framework/meta-lib/src/contract/sc_config/contract_variant_settings.rs @@ -81,7 +81,7 @@ impl ContractVariantProfile { result.codegen_units = codegen_units; } if let Some(opt_level) = &serde_profile.opt_level { - result.opt_level = opt_level.clone(); + result.opt_level.clone_from(opt_level); } if let Some(lto) = serde_profile.lto { result.lto = lto; @@ -90,7 +90,7 @@ impl ContractVariantProfile { result.debug = debug; } if let Some(panic) = &serde_profile.panic { - result.panic = panic.clone(); + result.panic.clone_from(panic); } if let Some(overflow_checks) = serde_profile.overflow_checks { result.overflow_checks = overflow_checks; diff --git a/framework/meta/src/cmd/contract/sc_config/contract_variant_settings/contract_allocator.rs b/framework/meta-lib/src/contract/sc_config/contract_variant_settings/contract_allocator.rs similarity index 100% rename from framework/meta/src/cmd/contract/sc_config/contract_variant_settings/contract_allocator.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant_settings/contract_allocator.rs diff --git a/framework/meta/src/cmd/contract/sc_config/contract_variant_settings/stack_size.rs b/framework/meta-lib/src/contract/sc_config/contract_variant_settings/stack_size.rs similarity index 100% rename from framework/meta/src/cmd/contract/sc_config/contract_variant_settings/stack_size.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant_settings/stack_size.rs diff --git a/framework/meta/src/cmd/contract/sc_config/contract_variant_validate.rs b/framework/meta-lib/src/contract/sc_config/contract_variant_validate.rs similarity index 81% rename from framework/meta/src/cmd/contract/sc_config/contract_variant_validate.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant_validate.rs index a0c0acb886..7ea1572437 100644 --- a/framework/meta/src/cmd/contract/sc_config/contract_variant_validate.rs +++ b/framework/meta-lib/src/contract/sc_config/contract_variant_validate.rs @@ -9,28 +9,24 @@ pub fn validate_contract_variant(contract_variant: &ContractVariant) -> Result<( } fn check_single_constructor(contract_variant: &ContractVariant) -> Result<(), String> { - match contract_variant.abi.constructors.len() { - 0 => if has_upgrade(contract_variant) { - Ok(()) - } else { - Err("Missing constructor. Add a method annotated with `#[init]`.".to_string()) - }, - 1 => Ok(()), - _ => Err("More than one contrctructor present. Exactly one method annotated with `#[init]` is required.".to_string()), + match ( + contract_variant.abi.constructors.len(), + contract_variant.abi.upgrade_constructors.len(), + ) { + (0, 0) => Err("Missing constructor. Add a method annotated with `#[init]`.".to_string()), + (1, 0) | (0, 1) | (1, 1) => Ok(()), + (_, _) => Err("More than two constructors present. Exactly one method annotated with `#[init]` and/or another optional `#[upgrade]` is required. ".to_string()), } } -fn has_upgrade(contract_variant: &ContractVariant) -> bool { - contract_variant - .abi - .endpoints - .iter() - .any(|endpoint| endpoint.name == "upgrade") -} - /// Note: promise callbacks not included, since they have `#[call_value]` arguments, that are currently not modelled. fn validate_contract_var_args(abi: &ContractAbi) -> Result<(), String> { - for endpoint_abi in abi.constructors.iter().chain(abi.endpoints.iter()) { + for endpoint_abi in abi + .constructors + .iter() + .chain(abi.upgrade_constructors.iter()) + .chain(abi.endpoints.iter()) + { validate_endpoint_var_args_number(endpoint_abi)?; validate_endpoint_var_args_order(endpoint_abi)?; } @@ -69,7 +65,7 @@ fn validate_endpoint_var_args_order(endpoint_abi: &EndpointAbi) -> Result<(), St #[cfg(test)] mod tests { - use multiversx_sc::abi::{InputAbi, TypeName}; + use multiversx_sc::abi::{InputAbi, TypeNames}; use super::*; @@ -78,12 +74,12 @@ mod tests { let mut endpoint_def = EndpointAbi::default(); let var_arg_1 = InputAbi { arg_name: "arg_1".to_string(), - type_name: TypeName::new(), + type_names: TypeNames::new(), multi_arg: true, }; let var_arg_2 = InputAbi { arg_name: "arg_2".to_string(), - type_name: TypeName::new(), + type_names: TypeNames::new(), multi_arg: true, }; endpoint_def.inputs.push(var_arg_1); @@ -103,12 +99,12 @@ mod tests { let mut endpoint_def = EndpointAbi::default(); let arg = InputAbi { arg_name: "arg_1".to_string(), - type_name: TypeName::new(), + type_names: TypeNames::new(), multi_arg: false, }; let var_arg_1 = InputAbi { arg_name: "arg_2".to_string(), - type_name: TypeName::new(), + type_names: TypeNames::new(), multi_arg: true, }; diff --git a/framework/meta/src/cmd/contract/sc_config/sc_config_model.rs b/framework/meta-lib/src/contract/sc_config/sc_config_model.rs similarity index 93% rename from framework/meta/src/cmd/contract/sc_config/sc_config_model.rs rename to framework/meta-lib/src/contract/sc_config/sc_config_model.rs index 7f9ddbf5a9..076e91a2f7 100644 --- a/framework/meta/src/cmd/contract/sc_config/sc_config_model.rs +++ b/framework/meta-lib/src/contract/sc_config/sc_config_model.rs @@ -1,4 +1,7 @@ -use super::{contract_variant_validate::validate_contract_variant, ContractVariant}; +use super::{ + contract_variant_validate::validate_contract_variant, sc_config_proxy::ProxyConfigSerde, + ContractVariant, +}; /// Allowed file names for the SC config. /// @@ -15,6 +18,7 @@ pub const SC_CONFIG_FILE_NAMES: &[&str] = &["sc-config.toml", "multicontract.tom pub struct ScConfig { pub default_contract_config_name: String, pub contracts: Vec, + pub proxy_configs: Vec, } impl ScConfig { diff --git a/framework/meta-lib/src/contract/sc_config/sc_config_proxy.rs b/framework/meta-lib/src/contract/sc_config/sc_config_proxy.rs new file mode 100644 index 0000000000..88721fe6e7 --- /dev/null +++ b/framework/meta-lib/src/contract/sc_config/sc_config_proxy.rs @@ -0,0 +1,41 @@ +use serde::Deserialize; + +const DEFAULT_PATH: &str = "/output/proxy.rs"; + +#[derive(Deserialize, Default, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] +pub struct ProxyConfigSerde { + #[serde(default)] + pub path: String, + + #[serde(default)] + #[serde(rename = "override-import")] + pub override_import: Option, + + #[serde(default)] + #[serde(rename = "path-rename")] + pub path_rename: Option>, + + #[serde(default)] + pub variant: Option, +} + +impl ProxyConfigSerde { + pub fn new() -> Self { + Self { + path: DEFAULT_PATH.to_string(), + override_import: None, + path_rename: None, + variant: None, + } + } +} + +#[derive(Deserialize, Default, Debug, Clone, PartialEq, Eq)] +pub struct PathRename { + #[serde(default)] + pub from: String, + + #[serde(default)] + pub to: String, +} diff --git a/framework/meta/src/cmd/contract/sc_config/sc_config_serde.rs b/framework/meta-lib/src/contract/sc_config/sc_config_serde.rs similarity index 96% rename from framework/meta/src/cmd/contract/sc_config/sc_config_serde.rs rename to framework/meta-lib/src/contract/sc_config/sc_config_serde.rs index 4813fcfb09..c3c6b94d30 100644 --- a/framework/meta/src/cmd/contract/sc_config/sc_config_serde.rs +++ b/framework/meta-lib/src/contract/sc_config/sc_config_serde.rs @@ -1,6 +1,8 @@ use serde::Deserialize; use std::collections::HashMap; +use super::ProxyConfigSerde; + #[derive(Deserialize, Debug)] #[serde(deny_unknown_fields)] pub struct ScConfigSerde { @@ -9,6 +11,8 @@ pub struct ScConfigSerde { #[serde(default)] pub contracts: HashMap, #[serde(default)] + pub proxy: Vec, + #[serde(default)] #[serde(rename = "labels-for-contracts")] pub labels_for_contracts: HashMap>, } diff --git a/framework/meta/src/cmd/contract/sc_config/wasm_build.rs b/framework/meta-lib/src/contract/sc_config/wasm_build.rs similarity index 99% rename from framework/meta/src/cmd/contract/sc_config/wasm_build.rs rename to framework/meta-lib/src/contract/sc_config/wasm_build.rs index bfe0539738..d4b5f9d1de 100644 --- a/framework/meta/src/cmd/contract/sc_config/wasm_build.rs +++ b/framework/meta-lib/src/contract/sc_config/wasm_build.rs @@ -3,7 +3,7 @@ use std::{ffi::OsStr, fs, process::Command}; use super::ContractVariant; use crate::{ abi_json::ContractAbiJson, - cli_args::BuildArgs, + cli::BuildArgs, ei::EIVersion, ei_check_json::EiCheckJson, mxsc_file_json::{save_mxsc_file_json, MxscFileJson}, diff --git a/framework/meta/src/cmd/contract/sc_config/wasm_clean.rs b/framework/meta-lib/src/contract/sc_config/wasm_clean.rs similarity index 100% rename from framework/meta/src/cmd/contract/sc_config/wasm_clean.rs rename to framework/meta-lib/src/contract/sc_config/wasm_clean.rs diff --git a/framework/meta/src/cmd/contract/sc_config/wasm_crate_gen.rs b/framework/meta-lib/src/contract/sc_config/wasm_crate_gen.rs similarity index 92% rename from framework/meta/src/cmd/contract/sc_config/wasm_crate_gen.rs rename to framework/meta-lib/src/contract/sc_config/wasm_crate_gen.rs index 7dde9e9805..3b0a82c717 100644 --- a/framework/meta/src/cmd/contract/sc_config/wasm_crate_gen.rs +++ b/framework/meta-lib/src/contract/sc_config/wasm_crate_gen.rs @@ -18,6 +18,7 @@ const PREFIX_AUTO_GENERATED: &str = "; const NUM_INIT: usize = 1; +const NUM_UPGRADE: usize = 1; const NUM_ASYNC_CB: usize = 1; const VER_1_71: &str = "1.71.0-nightly"; @@ -26,7 +27,7 @@ const FEATURES_PRE_RUSTC_1_71: &str = " // Configuration that works with rustc < 1.71.0. // TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(alloc_error_handler, lang_items)] +#![feature(alloc_error_handler)] "; const VER_1_73: &str = "1.73.0-nightly"; @@ -35,13 +36,10 @@ const FEATURES_PRE_RUSTC_1_73: &str = " // Configuration that works with rustc < 1.73.0. // TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] "; const FEATURES_DEFAULT: &str = " #![no_std] -#![allow(internal_features)] -#![feature(lang_items)] "; impl ContractVariant { @@ -110,7 +108,17 @@ fn write_stat_comment(wasm_lib_file: &mut File, label: &str, number: usize) { impl ContractVariant { /// Writing some nicely formatted comments breaking down all exported functions. fn write_stat_comments(&self, wasm_lib_file: &mut File) { - write_stat_comment(wasm_lib_file, "Init:", NUM_INIT); + let mut total = self.abi.endpoints.len() + NUM_ASYNC_CB + self.abi.promise_callbacks.len(); + + if !self.abi.constructors.is_empty() { + write_stat_comment(wasm_lib_file, "Init:", NUM_INIT); + total += NUM_INIT; + } + if !self.abi.upgrade_constructors.is_empty() { + write_stat_comment(wasm_lib_file, "Upgrade:", NUM_UPGRADE); + total += NUM_UPGRADE; + } + write_stat_comment(wasm_lib_file, "Endpoints:", self.abi.endpoints.len()); if self.abi.has_callback { write_stat_comment(wasm_lib_file, "Async Callback:", NUM_ASYNC_CB); @@ -124,8 +132,6 @@ impl ContractVariant { self.abi.promise_callbacks.len(), ); } - let total = - self.abi.endpoints.len() + NUM_INIT + NUM_ASYNC_CB + self.abi.promise_callbacks.len(); write_stat_comment(wasm_lib_file, "Total number of exported functions:", total); } diff --git a/framework/meta/src/cmd/contract/sc_config/wasm_update.rs b/framework/meta-lib/src/contract/sc_config/wasm_update.rs similarity index 100% rename from framework/meta/src/cmd/contract/sc_config/wasm_update.rs rename to framework/meta-lib/src/contract/sc_config/wasm_update.rs diff --git a/framework/meta/src/cmd/contract/wasm_cargo_toml_data.rs b/framework/meta-lib/src/contract/wasm_cargo_toml_data.rs similarity index 100% rename from framework/meta/src/cmd/contract/wasm_cargo_toml_data.rs rename to framework/meta-lib/src/contract/wasm_cargo_toml_data.rs diff --git a/framework/meta/src/cmd/contract/wasm_cargo_toml_generate.rs b/framework/meta-lib/src/contract/wasm_cargo_toml_generate.rs similarity index 95% rename from framework/meta/src/cmd/contract/wasm_cargo_toml_generate.rs rename to framework/meta-lib/src/contract/wasm_cargo_toml_generate.rs index 06b99cfc92..90b33229be 100644 --- a/framework/meta/src/cmd/contract/wasm_cargo_toml_generate.rs +++ b/framework/meta-lib/src/contract/wasm_cargo_toml_generate.rs @@ -1,5 +1,7 @@ use super::wasm_cargo_toml_data::WasmCargoTomlData; -use crate::{cargo_toml_contents::change_from_base_to_adapter_path, CargoTomlContents}; +use crate::{ + cargo_toml_contents::change_from_base_to_adapter_path, cargo_toml_contents::CargoTomlContents, +}; const WASM_ADAPTER: &str = "multiversx-sc-wasm-adapter"; const CDYLIB_CRATE_TYPE: &str = "cdylib"; diff --git a/framework/meta/src/ei.rs b/framework/meta-lib/src/ei.rs similarity index 100% rename from framework/meta/src/ei.rs rename to framework/meta-lib/src/ei.rs diff --git a/framework/meta/src/ei/ei_1_0.rs b/framework/meta-lib/src/ei/ei_1_0.rs similarity index 100% rename from framework/meta/src/ei/ei_1_0.rs rename to framework/meta-lib/src/ei/ei_1_0.rs diff --git a/framework/meta/src/ei/ei_1_1.rs b/framework/meta-lib/src/ei/ei_1_1.rs similarity index 100% rename from framework/meta/src/ei/ei_1_1.rs rename to framework/meta-lib/src/ei/ei_1_1.rs diff --git a/framework/meta/src/ei/ei_1_2.rs b/framework/meta-lib/src/ei/ei_1_2.rs similarity index 100% rename from framework/meta/src/ei/ei_1_2.rs rename to framework/meta-lib/src/ei/ei_1_2.rs diff --git a/framework/meta/src/ei/ei_1_3.rs b/framework/meta-lib/src/ei/ei_1_3.rs similarity index 100% rename from framework/meta/src/ei/ei_1_3.rs rename to framework/meta-lib/src/ei/ei_1_3.rs diff --git a/framework/meta/src/ei/ei_version.rs b/framework/meta-lib/src/ei/ei_version.rs similarity index 100% rename from framework/meta/src/ei/ei_version.rs rename to framework/meta-lib/src/ei/ei_version.rs diff --git a/framework/meta/src/ei_check_json.rs b/framework/meta-lib/src/ei_check_json.rs similarity index 100% rename from framework/meta/src/ei_check_json.rs rename to framework/meta-lib/src/ei_check_json.rs diff --git a/framework/meta/src/esdt_attr_file_json.rs b/framework/meta-lib/src/esdt_attr_file_json.rs similarity index 100% rename from framework/meta/src/esdt_attr_file_json.rs rename to framework/meta-lib/src/esdt_attr_file_json.rs diff --git a/framework/meta-lib/src/lib.rs b/framework/meta-lib/src/lib.rs new file mode 100644 index 0000000000..ab24acae54 --- /dev/null +++ b/framework/meta-lib/src/lib.rs @@ -0,0 +1,18 @@ +pub mod abi_json; +pub mod cargo_toml_contents; +pub mod cli; +pub mod contract; +pub mod ei; +pub mod ei_check_json; +pub mod esdt_attr_file_json; +mod mxsc_file_json; +pub mod print_util; +mod report_info_json; +pub mod tools; +pub mod version; +pub mod version_history; + +#[macro_use] +extern crate lazy_static; + +pub use cli::{cli_main, multi_contract_config}; diff --git a/framework/meta/src/mxsc_file_json.rs b/framework/meta-lib/src/mxsc_file_json.rs similarity index 100% rename from framework/meta/src/mxsc_file_json.rs rename to framework/meta-lib/src/mxsc_file_json.rs diff --git a/framework/meta/src/print_util.rs b/framework/meta-lib/src/print_util.rs similarity index 100% rename from framework/meta/src/print_util.rs rename to framework/meta-lib/src/print_util.rs diff --git a/framework/meta/src/report_info_json.rs b/framework/meta-lib/src/report_info_json.rs similarity index 100% rename from framework/meta/src/report_info_json.rs rename to framework/meta-lib/src/report_info_json.rs diff --git a/framework/meta/src/tools.rs b/framework/meta-lib/src/tools.rs similarity index 87% rename from framework/meta/src/tools.rs rename to framework/meta-lib/src/tools.rs index 5bf45930ce..5be426c21e 100644 --- a/framework/meta/src/tools.rs +++ b/framework/meta-lib/src/tools.rs @@ -1,16 +1,17 @@ -pub mod find_workspace; +mod find_workspace; mod git_describe; pub mod twiggy; mod wasm_extractor; mod wasm_opt; mod wasm_to_wat; +pub use find_workspace::{find_current_workspace, find_workspace}; pub use git_describe::git_describe; pub use wasm_extractor::WasmInfo; pub use wasm_opt::run_wasm_opt; pub use wasm_to_wat::wasm_to_wat; -use crate::cli_args::BuildArgs; +use crate::cli::BuildArgs; pub fn check_tools_installed(build_args: &mut BuildArgs) { if build_args.wasm_opt && !wasm_opt::is_wasm_opt_installed() { diff --git a/framework/meta/src/tools/find_workspace.rs b/framework/meta-lib/src/tools/find_workspace.rs similarity index 100% rename from framework/meta/src/tools/find_workspace.rs rename to framework/meta-lib/src/tools/find_workspace.rs diff --git a/framework/meta/src/tools/git_describe.rs b/framework/meta-lib/src/tools/git_describe.rs similarity index 100% rename from framework/meta/src/tools/git_describe.rs rename to framework/meta-lib/src/tools/git_describe.rs diff --git a/framework/meta/src/tools/twiggy.rs b/framework/meta-lib/src/tools/twiggy.rs similarity index 100% rename from framework/meta/src/tools/twiggy.rs rename to framework/meta-lib/src/tools/twiggy.rs diff --git a/framework/meta/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs similarity index 100% rename from framework/meta/src/tools/wasm_extractor.rs rename to framework/meta-lib/src/tools/wasm_extractor.rs diff --git a/framework/meta/src/tools/wasm_opt.rs b/framework/meta-lib/src/tools/wasm_opt.rs similarity index 100% rename from framework/meta/src/tools/wasm_opt.rs rename to framework/meta-lib/src/tools/wasm_opt.rs diff --git a/framework/meta/src/tools/wasm_to_wat.rs b/framework/meta-lib/src/tools/wasm_to_wat.rs similarity index 100% rename from framework/meta/src/tools/wasm_to_wat.rs rename to framework/meta-lib/src/tools/wasm_to_wat.rs diff --git a/framework/meta/src/version.rs b/framework/meta-lib/src/version.rs similarity index 100% rename from framework/meta/src/version.rs rename to framework/meta-lib/src/version.rs diff --git a/framework/meta/src/version_history.rs b/framework/meta-lib/src/version_history.rs similarity index 96% rename from framework/meta/src/version_history.rs rename to framework/meta-lib/src/version_history.rs index dbd391af6e..d377a09e16 100644 --- a/framework/meta/src/version_history.rs +++ b/framework/meta-lib/src/version_history.rs @@ -3,7 +3,7 @@ use crate::{framework_version, framework_versions, version::FrameworkVersion}; /// The last version to be used for upgrades and templates. /// /// Should be edited every time a new version of the framework is released. -pub const LAST_VERSION: FrameworkVersion = framework_version!(0.47.5); +pub const LAST_VERSION: FrameworkVersion = framework_version!(0.50.3); /// Indicates where to stop with the upgrades. pub const LAST_UPGRADE_VERSION: FrameworkVersion = LAST_VERSION; @@ -63,6 +63,17 @@ pub const VERSIONS: &[FrameworkVersion] = framework_versions![ 0.47.3, 0.47.4, 0.47.5, + 0.47.6, + 0.47.7, + 0.47.8, + 0.48.0, + 0.48.1, + 0.49.0, + 0.50.0, + 0.50.1, + 0.50.2, + 0.50.3, + 0.51.0, ]; #[rustfmt::skip] @@ -85,6 +96,9 @@ pub const CHECK_AFTER_UPGRADE_TO: &[FrameworkVersion] = framework_versions![ 0.45.2, 0.46.0, 0.47.0, + 0.49.0, + 0.50.3, + 0.51.0, ]; pub const LOWER_VERSION_WITH_TEMPLATE_TAG: FrameworkVersion = framework_version!(0.43.0); diff --git a/framework/meta/tests/ei_test.rs b/framework/meta-lib/tests/ei_test.rs similarity index 98% rename from framework/meta/tests/ei_test.rs rename to framework/meta-lib/tests/ei_test.rs index 8ea4442b43..2a1bdb06bb 100644 --- a/framework/meta/tests/ei_test.rs +++ b/framework/meta-lib/tests/ei_test.rs @@ -1,4 +1,4 @@ -use multiversx_sc_meta::ei; +use multiversx_sc_meta_lib::ei; use std::collections::HashSet; diff --git a/framework/meta/tests/multi_contract_test.rs b/framework/meta-lib/tests/multi_contract_test.rs similarity index 97% rename from framework/meta/tests/multi_contract_test.rs rename to framework/meta-lib/tests/multi_contract_test.rs index a9896eb72c..4f2f20bdee 100644 --- a/framework/meta/tests/multi_contract_test.rs +++ b/framework/meta-lib/tests/multi_contract_test.rs @@ -1,5 +1,5 @@ use multiversx_sc::abi::{ContractAbi, EndpointAbi}; -use multiversx_sc_meta::cmd::contract::sc_config::{ScConfig, ScConfigSerde}; +use multiversx_sc_meta_lib::contract::sc_config::{ScConfig, ScConfigSerde}; fn get_serialized_toml() -> ScConfigSerde { toml::from_str( diff --git a/framework/meta/Cargo.toml b/framework/meta/Cargo.toml index a4554cf766..029bbfdb6e 100644 --- a/framework/meta/Cargo.toml +++ b/framework/meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-meta" -version = "0.47.5" +version = "0.50.3" edition = "2021" authors = [ @@ -12,49 +12,43 @@ readme = "README.md" repository = "https://github.com/multiversx/mx-sdk-rs" homepage = "https://multiversx.com/" documentation = "https://docs.multiversx.com/" -description = "MultiversX smart contract meta-programming tools and build system" +description = "MultiversX smart contract crate management standalone tool" keywords = ["multiversx", "blockchain", "contract", "debug"] categories = ["cryptography::cryptocurrencies", "development-tools::debugging"] [[bin]] name = "sc-meta" path = "src/main.rs" -required-features = ["standalone"] [features] -standalone = ["ruplacer", "reqwest", "zip", "copy_dir", "pathdiff", "common-path"] template-test-current = [] template-test-released = [] -# no other way to have a default feature in bin at the moment -# contract meta crates should add `default-features = false` -default = ["standalone"] - [dependencies] clap = { version = "4.4.7", features = ["derive"] } +tokio = { version = "1.24", features = ["full"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -rustc_version = "0.4" toml = { version = "0.8.6", features = ["preserve_order"] } colored = "2.0" -lazy_static = "1.4.0" convert_case = "0.6.0" -hex = "0.4" -wasmparser = "0.121.0" -wasmprinter = "0.2.71" semver = "1.0.20" +ruplacer = { version = "0.8.1", default-features = false } +reqwest = { version = "0.12", features = ["blocking", "json"] } +zip = { version = "2.1", features = ["deflate"], default-features = false } +copy_dir = "0.1.2" +pathdiff = "0.2.1" +common-path = "1.0.0" -ruplacer = { version = "0.8.1", default-features = false, optional = true } -reqwest = { version = "0.11.4", features = ["blocking", "json"], optional = true } -zip = { version = "0.6.4", features = ["deflate"], default-features = false, optional = true } -copy_dir = { version = "0.1.2", optional = true } -pathdiff = { version = "0.2.1", optional = true } -common-path = { version = "1.0.0", optional = true } +[dependencies.multiversx-sc-meta-lib] +version = "=0.50.3" +path = "../meta-lib" [dependencies.multiversx-sc] -version = "=0.47.5" +version = "=0.50.3" path = "../base" features = ["alloc", "num-bigint"] -[dev-dependencies] -multiversx-sc-meta = { path = ".", features = ["standalone"] } +[dependencies.multiversx-sc-snippets] +version = "=0.50.3" +path = "../snippets" diff --git a/framework/meta/README.md b/framework/meta/README.md index e9bc7f3e34..7f40ff3f38 100644 --- a/framework/meta/README.md +++ b/framework/meta/README.md @@ -1,9 +1,20 @@ -# Smart contract meta-programming +# Smart contract meta-programming tool [![crates.io](https://img.shields.io/crates/v/multiversx-sc-meta.svg)](https://crates.io/crates/multiversx-sc-meta) -A meta-programming utility that works with smart contract code metadata. +This is the standalone tool for creating and managing MultiversX smart contract crates. -It is responsible with creating the smart contract ABIs, generating the wasm crates, and, ultimately, building the contract binaries +## Install + +All you need to do to install is: + +``` +cargo install multiversx-sc-meta +``` + +It works on both stable and nightly Rust, requires rustc 1.78 or greater. + +## Documentation + +Please see the explanations and CLI specifiations here: https://docs.multiversx.com/developers/meta/sc-meta -For more about the build process, see https://docs.multiversx.com/developers/developer-reference/sc-build-reference/ diff --git a/framework/meta/src/cli.rs b/framework/meta/src/cli.rs new file mode 100644 index 0000000000..a29d017b81 --- /dev/null +++ b/framework/meta/src/cli.rs @@ -0,0 +1,5 @@ +mod cli_args_standalone; +mod cli_standalone_main; + +pub use cli_args_standalone::*; +pub use cli_standalone_main::*; diff --git a/framework/meta/src/cli_args/cli_args_standalone.rs b/framework/meta/src/cli/cli_args_standalone.rs similarity index 84% rename from framework/meta/src/cli_args/cli_args_standalone.rs rename to framework/meta/src/cli/cli_args_standalone.rs index a81d145dab..e66c83deb4 100644 --- a/framework/meta/src/cli_args/cli_args_standalone.rs +++ b/framework/meta/src/cli/cli_args_standalone.rs @@ -1,8 +1,7 @@ +use clap::{ArgAction, Args, Parser, Subcommand, ValueEnum}; use std::path::PathBuf; -use clap::{ArgAction, Args, Parser, Subcommand}; - -use super::{CliArgsToRaw, ContractCliAction}; +use multiversx_sc_meta_lib::cli::{CliArgsToRaw, ContractCliAction}; /// Parsed arguments of the meta crate CLI. #[derive(Default, PartialEq, Eq, Debug, Parser)] @@ -30,6 +29,9 @@ pub struct StandaloneCliArgs { #[derive(Clone, PartialEq, Eq, Debug, Subcommand)] pub enum StandaloneCliAction { + #[command(name = "install", about = "Installs framework dependencies")] + Install(InstallArgs), + #[command( about = "General info about the contract an libraries residing in the targetted directory.." )] @@ -45,12 +47,6 @@ pub enum StandaloneCliAction { )] Upgrade(UpgradeArgs), - #[command( - name = "local-deps", - about = "Generates a report on the local depedencies of contract crates. Will explore indirect depdencies too." - )] - LocalDeps(LocalDepsArgs), - #[command(name = "new", about = "Creates a contract by a pre-existing template")] Template(TemplateArgs), @@ -66,8 +62,19 @@ pub enum StandaloneCliAction { #[command(name = "test", about = "Runs cargo test")] Test(TestArgs), - #[command(name = "install", about = "Installs framework dependencies")] - Install(InstallArgs), + #[command(name = "test-coverage", about = "Run test coverage and output report")] + TestCoverage(TestCoverageArgs), + + #[command( + about = "Generates a scenario test initialized with real data fetched from the blockchain." + )] + Account(AccountArgs), + + #[command( + name = "local-deps", + about = "Generates a report on the local depedencies of contract crates. Will explore indirect depdencies too." + )] + LocalDeps(LocalDepsArgs), } #[derive(Default, Clone, PartialEq, Eq, Debug, Args)] @@ -107,6 +114,31 @@ pub struct TestArgs { pub nocapture: bool, } +#[derive(Default, Clone, PartialEq, Eq, Debug, ValueEnum)] +pub enum TestCoverageOutputFormat { + /// Markdown pretty-print summary + #[default] + Markdown, + + /// JSON summary + Json, +} + +#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] +pub struct TestCoverageArgs { + /// Output file path + #[arg(short, long, verbatim_doc_comment)] + pub output: String, + + /// Output format + #[arg(short, long, verbatim_doc_comment)] + pub format: Option, + + /// Ignore files by path patterns + #[arg(short = 'i', long = "ignore-filename-regex", verbatim_doc_comment)] + pub ignore_filename_regex: Vec, +} + #[derive(Default, Clone, PartialEq, Eq, Debug, Args)] pub struct AllArgs { #[command(subcommand)] @@ -279,6 +311,12 @@ pub enum InstallCommand { #[command(about = "Installs the `mx-scenario-go` tool")] MxScenarioGo(InstallMxScenarioGoArgs), + + #[command(name = "wasm32", about = "Installs the `wasm32` target")] + Wasm32(InstallWasm32Args), + + #[command(name = "wasm-opt", about = "Installs the `wasm-opt` tool")] + WasmOpt(InstallWasmOptArgs), } #[derive(Default, Clone, PartialEq, Eq, Debug, Args)] @@ -287,3 +325,21 @@ pub struct InstallMxScenarioGoArgs { #[arg(long, verbatim_doc_comment)] pub tag: Option, } + +#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] +pub struct InstallWasm32Args {} + +#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] +pub struct InstallWasmOptArgs {} + +#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] +pub struct AccountArgs { + /// Provide the target API you want the real data to come from + #[arg(long = "api")] + #[clap(global = true)] + pub api: Option, + + /// Provide the address you want to retrieve data from + #[arg(long = "address", verbatim_doc_comment)] + pub address: String, +} diff --git a/framework/meta/src/cmd/standalone.rs b/framework/meta/src/cli/cli_standalone_main.rs similarity index 56% rename from framework/meta/src/cmd/standalone.rs rename to framework/meta/src/cli/cli_standalone_main.rs index ddc8cef085..6c8c6a67b0 100644 --- a/framework/meta/src/cmd/standalone.rs +++ b/framework/meta/src/cli/cli_standalone_main.rs @@ -1,36 +1,27 @@ -mod all; -mod info; -pub mod install; -mod local_deps; -mod print_util; -pub mod scen_test_gen; -pub mod template; -pub mod test; -pub(crate) mod upgrade; - -use crate::cli_args::{StandaloneCliAction, StandaloneCliArgs}; -use all::call_all_meta; +use crate::cli::{StandaloneCliAction, StandaloneCliArgs}; +use crate::cmd::retrieve_address::retrieve_address; use clap::Parser; -use info::call_info; -use install::install; -use local_deps::local_deps; -use scen_test_gen::test_gen_tool; -use template::{create_contract, print_template_names}; -use test::test; -use upgrade::upgrade_sc; + +use crate::cmd::all::call_all_meta; +use crate::cmd::info::call_info; +use crate::cmd::install::install; +use crate::cmd::local_deps::local_deps; +use crate::cmd::scen_test_gen::test_gen_tool; +use crate::cmd::template::{create_contract, print_template_names}; +use crate::cmd::test::test; +use crate::cmd::test_coverage::test_coverage; +use crate::cmd::upgrade::upgrade_sc; /// Entry point in the program when calling it as a standalone tool. -pub fn cli_main_standalone() { +pub async fn cli_main_standalone() { let cli_args = StandaloneCliArgs::parse(); match &cli_args.command { Some(StandaloneCliAction::Info(args)) => call_info(args), + Some(StandaloneCliAction::Install(args)) => install(args), Some(StandaloneCliAction::All(args)) => call_all_meta(args), Some(StandaloneCliAction::Upgrade(args)) => { upgrade_sc(args); }, - Some(StandaloneCliAction::LocalDeps(args)) => { - local_deps(args); - }, Some(StandaloneCliAction::Template(args)) => { create_contract(args); }, @@ -41,7 +32,15 @@ pub fn cli_main_standalone() { test_gen_tool(args); }, Some(StandaloneCliAction::Test(args)) => test(args), - Some(StandaloneCliAction::Install(args)) => install(args), + Some(StandaloneCliAction::TestCoverage(args)) => { + test_coverage(args); + }, + Some(StandaloneCliAction::Account(args)) => { + retrieve_address(args).await; + }, + Some(StandaloneCliAction::LocalDeps(args)) => { + local_deps(args); + }, None => {}, } } diff --git a/framework/meta/src/cmd.rs b/framework/meta/src/cmd.rs index 7ec72dd6f2..a588f90162 100644 --- a/framework/meta/src/cmd.rs +++ b/framework/meta/src/cmd.rs @@ -1,4 +1,11 @@ -pub mod contract; - -#[cfg(feature = "standalone")] -pub mod standalone; +pub mod all; +pub mod info; +pub mod install; +pub mod local_deps; +pub mod print_util; +pub mod retrieve_address; +pub mod scen_test_gen; +pub mod template; +pub mod test; +pub mod test_coverage; +pub mod upgrade; diff --git a/framework/meta/src/cmd/standalone/all.rs b/framework/meta/src/cmd/all.rs similarity index 98% rename from framework/meta/src/cmd/standalone/all.rs rename to framework/meta/src/cmd/all.rs index 91af64ea56..8483981a04 100644 --- a/framework/meta/src/cmd/standalone/all.rs +++ b/framework/meta/src/cmd/all.rs @@ -1,6 +1,6 @@ use super::print_util::{print_all_command, print_all_count, print_all_index}; use crate::{ - cli_args::AllArgs, + cli::AllArgs, folder_structure::{dir_pretty_print, RelevantDirectories}, }; use std::{path::Path, process::Command}; diff --git a/framework/meta/src/cmd/contract/generate_snippets/snippet_template_gen.rs b/framework/meta/src/cmd/contract/generate_snippets/snippet_template_gen.rs deleted file mode 100644 index 0feb12e562..0000000000 --- a/framework/meta/src/cmd/contract/generate_snippets/snippet_template_gen.rs +++ /dev/null @@ -1,114 +0,0 @@ -use std::{fs::File, io::Write}; - -use multiversx_sc::abi::ContractAbi; - -use super::snippet_gen_common::write_newline; - -pub(crate) fn write_snippet_imports(file: &mut File, contract_crate_name: &str) { - writeln!( - file, - "#![allow(non_snake_case)] - -use {contract_crate_name}::ProxyTrait as _; -use {contract_crate_name}::*; - -use multiversx_sc_snippets::{{ - env_logger, - erdrs::wallet::Wallet, - multiversx_sc::{{codec::multi_types::*, types::*}}, - multiversx_sc_scenario::{{ - api::StaticApi, - bech32, - scenario_format::interpret_trait::{{InterpretableFrom, InterpreterContext}}, - scenario_model::*, - ContractInfo, - }}, - sdk, tokio, Interactor, -}}; -" - ) - .unwrap(); - - write_newline(file); -} - -pub(crate) fn write_snippet_constants(file: &mut File) { - writeln!( - file, - "const GATEWAY: &str = sdk::blockchain::DEVNET_GATEWAY; -const PEM: &str = \"alice.pem\"; -const SC_ADDRESS: &str = \"\"; - -const SYSTEM_SC_BECH32: &str = \"erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u\"; -const DEFAULT_ADDRESS_EXPR: &str = - \"0x0000000000000000000000000000000000000000000000000000000000000000\"; -const TOKEN_ISSUE_COST: u64 = 50_000_000_000_000_000;" - ) - .unwrap(); - - write_newline(file); -} - -pub(crate) fn write_contract_type_alias(file: &mut File, contract_crate_name: &str) { - writeln!( - file, - "type ContractType = ContractInfo<{contract_crate_name}::Proxy>;" - ) - .unwrap(); - - write_newline(file); -} - -pub(crate) fn write_snippet_main_function(file: &mut File, abi: &ContractAbi) { - writeln!( - file, - "#[tokio::main] -async fn main() {{ - env_logger::init(); - - let mut args = std::env::args(); - let _ = args.next(); - let cmd = args.next().expect(\"at least one argument required\"); - let mut state = State::new().await; - match cmd.as_str() {{" - ) - .unwrap(); - - // all contracts have a deploy snippet - writeln!(file, r#" "deploy" => state.deploy().await,"#).unwrap(); - - for endpoint in &abi.endpoints { - writeln!( - file, - r#" "{}" => state.{}().await,"#, - endpoint.name, endpoint.rust_method_name - ) - .unwrap(); - } - - // general case of "command not found" + close curly brackets - writeln!( - file, - " _ => panic!(\"unknown command: {{}}\", &cmd), - }} -}}" - ) - .unwrap(); - - write_newline(file); -} - -pub(crate) fn write_state_struct_declaration(file: &mut File) { - writeln!( - file, - "struct State {{ - interactor: Interactor, - wallet_address: Address, - contract_code: BytesValue, - contract: ContractType, -}}" - ) - .unwrap(); - - write_newline(file); -} diff --git a/framework/meta/src/cmd/standalone/info.rs b/framework/meta/src/cmd/info.rs similarity index 95% rename from framework/meta/src/cmd/standalone/info.rs rename to framework/meta/src/cmd/info.rs index 07df89b2d0..2d36399474 100644 --- a/framework/meta/src/cmd/standalone/info.rs +++ b/framework/meta/src/cmd/info.rs @@ -1,6 +1,6 @@ use super::upgrade::print_tree_dir_metadata; use crate::{ - cli_args::InfoArgs, + cli::InfoArgs, folder_structure::{dir_pretty_print, RelevantDirectories}, version_history::LAST_UPGRADE_VERSION, }; diff --git a/framework/meta/src/cmd/install.rs b/framework/meta/src/cmd/install.rs new file mode 100644 index 0000000000..256f7640e7 --- /dev/null +++ b/framework/meta/src/cmd/install.rs @@ -0,0 +1,39 @@ +mod install_scenario_go; +mod install_wasm_tools; +mod system_info; + +use crate::cli::{ + InstallArgs, InstallCommand, InstallMxScenarioGoArgs, InstallWasm32Args, InstallWasmOptArgs, +}; + +use self::install_scenario_go::ScenarioGoInstaller; + +pub fn install(args: &InstallArgs) { + let command = args + .command + .as_ref() + .expect("command expected after `install`"); + + match command { + InstallCommand::All => { + install_scenario_go(&InstallMxScenarioGoArgs::default()); + install_wasm32(&InstallWasm32Args::default()); + install_wasm_opt(&InstallWasmOptArgs::default()); + }, + InstallCommand::MxScenarioGo(sg_args) => install_scenario_go(sg_args), + InstallCommand::Wasm32(wam32_args) => install_wasm32(wam32_args), + InstallCommand::WasmOpt(wasm_opt_args) => install_wasm_opt(wasm_opt_args), + } +} + +fn install_scenario_go(sg_args: &InstallMxScenarioGoArgs) { + ScenarioGoInstaller::new(sg_args.tag.clone()).install(); +} + +fn install_wasm32(_wasm32_args: &InstallWasm32Args) { + install_wasm_tools::install_wasm32_target(); +} + +fn install_wasm_opt(_wasm_opt_args: &InstallWasmOptArgs) { + install_wasm_tools::install_wasm_opt(); +} diff --git a/framework/meta/src/cmd/standalone/install/install_scenario_go.rs b/framework/meta/src/cmd/install/install_scenario_go.rs similarity index 98% rename from framework/meta/src/cmd/standalone/install/install_scenario_go.rs rename to framework/meta/src/cmd/install/install_scenario_go.rs index 0a5798f792..2351ab2621 100644 --- a/framework/meta/src/cmd/standalone/install/install_scenario_go.rs +++ b/framework/meta/src/cmd/install/install_scenario_go.rs @@ -5,7 +5,7 @@ use std::{ path::{Path, PathBuf}, }; -use crate::print_util::println_green; +use multiversx_sc_meta_lib::print_util::println_green; use super::system_info::{get_system_info, SystemInfo}; @@ -16,6 +16,7 @@ const CARGO_HOME: &str = env!("CARGO_HOME"); #[derive(Clone, Debug)] pub struct ScenarioGoRelease { + #[allow(dead_code)] pub tag_name: String, pub download_url: String, } diff --git a/framework/meta/src/cmd/install/install_wasm_tools.rs b/framework/meta/src/cmd/install/install_wasm_tools.rs new file mode 100644 index 0000000000..90577107fe --- /dev/null +++ b/framework/meta/src/cmd/install/install_wasm_tools.rs @@ -0,0 +1,23 @@ +use std::process::Command; + +pub fn install_wasm32_target() { + let cmd = Command::new("rustup") + .args(vec!["target", "add", "wasm32-unknown-unknown"]) + .status() + .expect("failed to execute `rustup`"); + + assert!(cmd.success(), "failed to install wasm32 target"); + + println!("wasm32 target installed successfully"); +} + +pub fn install_wasm_opt() { + let cmd = Command::new("cargo") + .args(vec!["install", "wasm-opt"]) + .status() + .expect("failed to execute `cargo`"); + + assert!(cmd.success(), "failed to install wasm-opt"); + + println!("wasm-opt installed successfully"); +} diff --git a/framework/meta/src/cmd/standalone/install/system_info.rs b/framework/meta/src/cmd/install/system_info.rs similarity index 100% rename from framework/meta/src/cmd/standalone/install/system_info.rs rename to framework/meta/src/cmd/install/system_info.rs diff --git a/framework/meta/src/cmd/standalone/local_deps.rs b/framework/meta/src/cmd/local_deps.rs similarity index 97% rename from framework/meta/src/cmd/standalone/local_deps.rs rename to framework/meta/src/cmd/local_deps.rs index 72f8bacdc8..7aed31a6d3 100644 --- a/framework/meta/src/cmd/standalone/local_deps.rs +++ b/framework/meta/src/cmd/local_deps.rs @@ -1,11 +1,11 @@ use crate::{ - cli_args::LocalDepsArgs, + cli::LocalDepsArgs, folder_structure::{ dir_pretty_print, RelevantDirectories, CARGO_TOML_FILE_NAME, FRAMEWORK_CRATE_NAMES, }, - CargoTomlContents, }; use common_path::common_path_all; +use multiversx_sc_meta_lib::cargo_toml_contents::CargoTomlContents; use serde::{Deserialize, Serialize}; use std::{ collections::{BTreeMap, LinkedList}, diff --git a/framework/meta/src/cmd/standalone/print_util.rs b/framework/meta/src/cmd/print_util.rs similarity index 100% rename from framework/meta/src/cmd/standalone/print_util.rs rename to framework/meta/src/cmd/print_util.rs diff --git a/framework/meta/src/cmd/retrieve_address.rs b/framework/meta/src/cmd/retrieve_address.rs new file mode 100644 index 0000000000..f20b5b8e05 --- /dev/null +++ b/framework/meta/src/cmd/retrieve_address.rs @@ -0,0 +1,9 @@ +use multiversx_sc_snippets::account_tool; + +use crate::cli::AccountArgs; + +/// Interprets arguments and call the account tool from `multiversx_sc_snippets`. +pub async fn retrieve_address(args: &AccountArgs) { + let api_string = args.api.clone().expect("API needs to be specified"); + account_tool::print_account_as_scenario_set_state(api_string, args.address.to_string()).await; +} diff --git a/framework/meta/src/cmd/standalone/scen_test_gen.rs b/framework/meta/src/cmd/scen_test_gen.rs similarity index 93% rename from framework/meta/src/cmd/standalone/scen_test_gen.rs rename to framework/meta/src/cmd/scen_test_gen.rs index a8e8aa7af8..5a7b6ef55a 100644 --- a/framework/meta/src/cmd/standalone/scen_test_gen.rs +++ b/framework/meta/src/cmd/scen_test_gen.rs @@ -5,7 +5,7 @@ mod stg_process_code; mod stg_section; mod stg_write; -use crate::cli_args::TestGenArgs; +use crate::cli::TestGenArgs; pub fn test_gen_tool(args: &TestGenArgs) { let path = if let Some(some_path) = &args.path { diff --git a/framework/meta/src/cmd/standalone/scen_test_gen/stg_main.rs b/framework/meta/src/cmd/scen_test_gen/stg_main.rs similarity index 100% rename from framework/meta/src/cmd/standalone/scen_test_gen/stg_main.rs rename to framework/meta/src/cmd/scen_test_gen/stg_main.rs diff --git a/framework/meta/src/cmd/standalone/scen_test_gen/stg_parse.rs b/framework/meta/src/cmd/scen_test_gen/stg_parse.rs similarity index 100% rename from framework/meta/src/cmd/standalone/scen_test_gen/stg_parse.rs rename to framework/meta/src/cmd/scen_test_gen/stg_parse.rs diff --git a/framework/meta/src/cmd/standalone/scen_test_gen/stg_print.rs b/framework/meta/src/cmd/scen_test_gen/stg_print.rs similarity index 100% rename from framework/meta/src/cmd/standalone/scen_test_gen/stg_print.rs rename to framework/meta/src/cmd/scen_test_gen/stg_print.rs diff --git a/framework/meta/src/cmd/standalone/scen_test_gen/stg_process_code.rs b/framework/meta/src/cmd/scen_test_gen/stg_process_code.rs similarity index 100% rename from framework/meta/src/cmd/standalone/scen_test_gen/stg_process_code.rs rename to framework/meta/src/cmd/scen_test_gen/stg_process_code.rs diff --git a/framework/meta/src/cmd/standalone/scen_test_gen/stg_section.rs b/framework/meta/src/cmd/scen_test_gen/stg_section.rs similarity index 100% rename from framework/meta/src/cmd/standalone/scen_test_gen/stg_section.rs rename to framework/meta/src/cmd/scen_test_gen/stg_section.rs diff --git a/framework/meta/src/cmd/standalone/scen_test_gen/stg_write.rs b/framework/meta/src/cmd/scen_test_gen/stg_write.rs similarity index 100% rename from framework/meta/src/cmd/standalone/scen_test_gen/stg_write.rs rename to framework/meta/src/cmd/scen_test_gen/stg_write.rs diff --git a/framework/meta/src/cmd/standalone/install.rs b/framework/meta/src/cmd/standalone/install.rs deleted file mode 100644 index e96f23ad70..0000000000 --- a/framework/meta/src/cmd/standalone/install.rs +++ /dev/null @@ -1,24 +0,0 @@ -mod install_scenario_go; -mod system_info; - -use crate::cli_args::{InstallArgs, InstallCommand, InstallMxScenarioGoArgs}; - -use self::install_scenario_go::ScenarioGoInstaller; - -pub fn install(args: &InstallArgs) { - let command = args - .command - .as_ref() - .expect("command expected after `install`"); - - match command { - InstallCommand::All => { - install_scenario_go(&InstallMxScenarioGoArgs::default()); - }, - InstallCommand::MxScenarioGo(sg_args) => install_scenario_go(sg_args), - } -} - -fn install_scenario_go(sg_args: &InstallMxScenarioGoArgs) { - ScenarioGoInstaller::new(sg_args.tag.clone()).install(); -} diff --git a/framework/meta/src/cmd/standalone/template.rs b/framework/meta/src/cmd/template.rs similarity index 100% rename from framework/meta/src/cmd/standalone/template.rs rename to framework/meta/src/cmd/template.rs diff --git a/framework/meta/src/cmd/standalone/template/contract_creator.rs b/framework/meta/src/cmd/template/contract_creator.rs similarity index 99% rename from framework/meta/src/cmd/standalone/template/contract_creator.rs rename to framework/meta/src/cmd/template/contract_creator.rs index ae55c79b39..65e45f4d47 100644 --- a/framework/meta/src/cmd/standalone/template/contract_creator.rs +++ b/framework/meta/src/cmd/template/contract_creator.rs @@ -1,7 +1,7 @@ use convert_case::{Case, Casing}; use crate::{ - cli_args::TemplateArgs, + cli::TemplateArgs, version::FrameworkVersion, version_history::{validate_template_tag, LAST_TEMPLATE_VERSION}, }; diff --git a/framework/meta/src/cmd/standalone/template/contract_creator_target.rs b/framework/meta/src/cmd/template/contract_creator_target.rs similarity index 100% rename from framework/meta/src/cmd/standalone/template/contract_creator_target.rs rename to framework/meta/src/cmd/template/contract_creator_target.rs diff --git a/framework/meta/src/cmd/standalone/template/copy_util.rs b/framework/meta/src/cmd/template/copy_util.rs similarity index 100% rename from framework/meta/src/cmd/standalone/template/copy_util.rs rename to framework/meta/src/cmd/template/copy_util.rs diff --git a/framework/meta/src/cmd/standalone/template/repo_source.rs b/framework/meta/src/cmd/template/repo_source.rs similarity index 100% rename from framework/meta/src/cmd/standalone/template/repo_source.rs rename to framework/meta/src/cmd/template/repo_source.rs diff --git a/framework/meta/src/cmd/standalone/template/repo_temp_download.rs b/framework/meta/src/cmd/template/repo_temp_download.rs similarity index 100% rename from framework/meta/src/cmd/standalone/template/repo_temp_download.rs rename to framework/meta/src/cmd/template/repo_temp_download.rs diff --git a/framework/meta/src/cmd/standalone/template/repo_version.rs b/framework/meta/src/cmd/template/repo_version.rs similarity index 100% rename from framework/meta/src/cmd/standalone/template/repo_version.rs rename to framework/meta/src/cmd/template/repo_version.rs diff --git a/framework/meta/src/cmd/standalone/template/template_adjuster.rs b/framework/meta/src/cmd/template/template_adjuster.rs similarity index 82% rename from framework/meta/src/cmd/standalone/template/template_adjuster.rs rename to framework/meta/src/cmd/template/template_adjuster.rs index 6751fb175c..e1ac5ad827 100644 --- a/framework/meta/src/cmd/standalone/template/template_adjuster.rs +++ b/framework/meta/src/cmd/template/template_adjuster.rs @@ -1,18 +1,20 @@ use super::{template_metadata::TemplateMetadata, ContractCreatorTarget}; use crate::{ - cmd::standalone::upgrade::upgrade_common::{rename_files, replace_in_files}, + cmd::upgrade::upgrade_common::{rename_files, replace_in_files}, version::FrameworkVersion, version_history::is_template_with_autogenerated_wasm, - CargoTomlContents, }; use convert_case::{Case, Casing}; +use multiversx_sc_meta_lib::cargo_toml_contents::CargoTomlContents; use ruplacer::Query; use toml::value::Table; const TEST_DIRECTORY: &str = "./tests"; +const INTERACT_DIRECTORY: &str = "./interact"; const ROOT_CARGO_TOML: &str = "./Cargo.toml"; const META_CARGO_TOML: &str = "./meta/Cargo.toml"; const WASM_CARGO_TOML: &str = "./wasm/Cargo.toml"; +const INTERACT_CARGO_TOML: &str = "./interact/Cargo.toml"; pub struct TemplateAdjuster { pub metadata: TemplateMetadata, @@ -24,6 +26,7 @@ impl TemplateAdjuster { self.update_dependencies_root(); self.update_dependencies_meta(); self.update_dependencies_wasm(args_tag); + self.update_dependencies_interact(); } fn update_dependencies_root(&self) { @@ -34,7 +37,11 @@ impl TemplateAdjuster { remove_paths_from_deps(&mut toml, &[]); } - toml.add_workspace(&[".", "meta"]); + if self.metadata.has_interactor { + toml.add_workspace(&[".", "meta", "interact"]); + } else { + toml.add_workspace(&[".", "meta"]); + } toml.save_to_file(&cargo_toml_path); } @@ -65,12 +72,28 @@ impl TemplateAdjuster { toml.save_to_file(&cargo_toml_path); } + fn update_dependencies_interact(&self) { + if !self.metadata.has_interactor { + return; + } + + let cargo_toml_path = self.target.contract_dir().join(INTERACT_CARGO_TOML); + let mut toml = CargoTomlContents::load_from_file(&cargo_toml_path); + + if !self.keep_paths { + remove_paths_from_deps(&mut toml, &[&self.metadata.name]); + } + + toml.save_to_file(&cargo_toml_path); + } + pub fn rename_template_to(&self) { self.rename_trait_to(); self.rename_in_cargo_toml_root(); self.rename_in_cargo_toml_meta(); self.rename_in_cargo_toml_wasm(); self.rename_in_tests(); + self.rename_in_interactor(); self.rename_solution_files(); } @@ -81,6 +104,8 @@ impl TemplateAdjuster { let old_name = self.metadata.name.to_case(Case::Snake); let new_package = format!("{new_name}::"); let old_package = format!("{old_name}::"); + let new_proxy_mod = format!("{new_name}_proxy"); + let old_proxy_mod = format!("{old_name}_proxy"); replace_in_files( &self.target.contract_dir(), @@ -88,8 +113,15 @@ impl TemplateAdjuster { &[ Query::substring(old_trait, &new_trait), Query::substring(&old_package, &new_package), + Query::substring(&old_proxy_mod, &new_proxy_mod), ][..], ); + + replace_in_files( + &self.target.contract_dir(), + "*sc-config.toml", + &[Query::substring(&old_proxy_mod, &new_proxy_mod)][..], + ); } fn rename_in_cargo_toml_root(&self) { @@ -193,6 +225,19 @@ impl TemplateAdjuster { ); } + fn rename_in_interactor(&self) { + let old_mxsc = mxsc_file_name(&self.metadata.name); + let new_mxsc = mxsc_file_name(&self.target.new_name); + + let queries = vec![Query::substring(&old_mxsc, &new_mxsc)]; + + replace_in_files( + &self.target.contract_dir().join(INTERACT_DIRECTORY), + "*.rs", + &queries, + ); + } + fn rename_solution_files(&self) { let new_name = self.target.new_name.to_case(Case::Snake); let new_src_name = rs_file_name(&new_name); diff --git a/framework/meta/src/cmd/standalone/template/template_list.rs b/framework/meta/src/cmd/template/template_list.rs similarity index 94% rename from framework/meta/src/cmd/standalone/template/template_list.rs rename to framework/meta/src/cmd/template/template_list.rs index dfe74d1efe..1d297179b7 100644 --- a/framework/meta/src/cmd/standalone/template/template_list.rs +++ b/framework/meta/src/cmd/template/template_list.rs @@ -1,4 +1,4 @@ -use crate::cli_args::TemplateListArgs; +use crate::cli::TemplateListArgs; use super::{contract_creator::get_repo_version, template_source::template_sources, RepoSource}; diff --git a/framework/meta/src/cmd/standalone/template/template_metadata.rs b/framework/meta/src/cmd/template/template_metadata.rs similarity index 96% rename from framework/meta/src/cmd/standalone/template/template_metadata.rs rename to framework/meta/src/cmd/template/template_metadata.rs index 2f47f47617..b2113d21b3 100644 --- a/framework/meta/src/cmd/standalone/template/template_metadata.rs +++ b/framework/meta/src/cmd/template/template_metadata.rs @@ -7,6 +7,9 @@ pub struct TemplateMetadata { pub src_file: String, pub rename_pairs: Vec<(String, String)>, pub files_include: Vec, + + #[serde(default)] + pub has_interactor: bool, } #[cfg(test)] diff --git a/framework/meta/src/cmd/standalone/template/template_source.rs b/framework/meta/src/cmd/template/template_source.rs similarity index 100% rename from framework/meta/src/cmd/standalone/template/template_source.rs rename to framework/meta/src/cmd/template/template_source.rs diff --git a/framework/meta/src/cmd/standalone/test.rs b/framework/meta/src/cmd/test.rs similarity index 97% rename from framework/meta/src/cmd/standalone/test.rs rename to framework/meta/src/cmd/test.rs index 66964b3d60..828d9c9859 100644 --- a/framework/meta/src/cmd/standalone/test.rs +++ b/framework/meta/src/cmd/test.rs @@ -2,7 +2,7 @@ use std::process::Command; use colored::Colorize; -use crate::cli_args::TestArgs; +use crate::cli::TestArgs; pub fn test(test_args: &TestArgs) { let path = test_args.path.as_deref().unwrap_or("./"); diff --git a/framework/meta/src/cmd/test_coverage.rs b/framework/meta/src/cmd/test_coverage.rs new file mode 100644 index 0000000000..363fcc9372 --- /dev/null +++ b/framework/meta/src/cmd/test_coverage.rs @@ -0,0 +1,27 @@ +mod cargo; +mod error; +mod llvm_cov; +mod render; +mod run; +mod util; + +use crate::{ + cli::{TestCoverageArgs, TestCoverageOutputFormat}, + cmd::test_coverage::{cargo::get_workspace_root, run::run_test_coverage}, +}; +use std::process; + +pub fn test_coverage(args: &TestCoverageArgs) { + let root_path = get_workspace_root().unwrap(); + if let Err(err) = run_test_coverage( + &root_path, + &args.output, + args.format + .as_ref() + .unwrap_or(&TestCoverageOutputFormat::default()), + &args.ignore_filename_regex, + ) { + eprintln!("{}", err); + process::exit(1); + } +} diff --git a/framework/meta/src/cmd/test_coverage/cargo.rs b/framework/meta/src/cmd/test_coverage/cargo.rs new file mode 100644 index 0000000000..10023290c9 --- /dev/null +++ b/framework/meta/src/cmd/test_coverage/cargo.rs @@ -0,0 +1,98 @@ +use crate::cmd::test_coverage::error::TestCoverageError; +use serde::Deserialize; +use std::process::Command; + +pub fn get_workspace_root() -> Result { + let output = Command::new("cargo") + .args(["metadata", "--no-deps", "--format-version=1"]) + .output() + .map_err(|e| TestCoverageError::Cargo(format!("{}", e)))?; + + let metadata: serde_json::Value = serde_json::from_slice(&output.stdout) + .map_err(|_| TestCoverageError::Cargo("invalid manifest data".into()))?; + + let Some(workspace_root) = metadata["workspace_root"].as_str() else { + return Err(TestCoverageError::Cargo("invalid manifest data".into())); + }; + + Ok(workspace_root.to_owned()) +} + +#[derive(Debug, Clone, Deserialize)] +struct PartialCompilerArtifactMessage { + filenames: Vec, + profile: PartialCompilerArtifactProfile, +} + +#[derive(Debug, Clone, Deserialize)] +struct PartialCompilerArtifactProfile { + test: Option, +} + +pub fn run_instrumented_tests(path: &str) -> Result<(), TestCoverageError> { + let Ok(status) = Command::new("cargo") + .current_dir(path) + .env("RUSTFLAGS", "-C instrument-coverage") + .args(vec!["test", "--tests"]) + .status() + else { + return Err(TestCoverageError::Cargo( + "can't run instrumented tests".into(), + )); + }; + + if !status.success() { + return Err(TestCoverageError::Cargo( + "can't run instrumented tests".into(), + )); + } + + Ok(()) +} + +pub fn get_instrumented_test_binaries_paths(path: &str) -> Result, TestCoverageError> { + let Ok(output) = Command::new("cargo") + .current_dir(path) + .env("RUSTFLAGS", "-C instrument-coverage") + .args(vec!["test", "--tests", "--no-run", "--message-format=json"]) + .output() + else { + return Err(TestCoverageError::Cargo( + "can't get test binaries paths".into(), + )); + }; + + if !output.status.success() { + return Err(TestCoverageError::Cargo( + "can't get test binaries paths".into(), + )); + } + + let output = String::from_utf8_lossy(&output.stdout); + let messages = output.split('\n').collect::>(); + + let mut result = vec![]; + for message in messages { + let Ok(message) = serde_json::from_str::(message) else { + continue; + }; + + let Some("compiler-artifact") = message.get("reason").and_then(|val| val.as_str()) else { + continue; + }; + + let Ok(mut message) = serde_json::from_value::(message) + else { + continue; + }; + + let is_test = message.profile.test.unwrap_or_default(); + if !is_test { + continue; + } + + result.append(&mut message.filenames); + } + + Ok(result) +} diff --git a/framework/meta/src/cmd/test_coverage/error.rs b/framework/meta/src/cmd/test_coverage/error.rs new file mode 100644 index 0000000000..16334d203b --- /dev/null +++ b/framework/meta/src/cmd/test_coverage/error.rs @@ -0,0 +1,34 @@ +use std::{ + error::Error, + fmt::{Display, Formatter}, +}; + +#[derive(Debug)] +pub enum TestCoverageError { + MissingDependency(String), + FsError(String), + Cargo(String), + LlvmProfdata(String), + LlvmCov(String), +} + +impl Error for TestCoverageError {} + +impl Display for TestCoverageError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let message = match self { + TestCoverageError::MissingDependency(dep) => + format!("Missing dependency {dep}. Make sure you have {dep} installed on your system and it's available in PATH."), + + TestCoverageError::FsError(msg) => + format!("FS operation failed: {msg}"), + TestCoverageError::Cargo(msg) => + format!("Failed to run cargo: {msg}"), + TestCoverageError::LlvmProfdata(msg) => + format!("llvm-profdata error: {msg}"), + TestCoverageError::LlvmCov(msg) => + format!("llvm-cov error: {msg}"), + }; + write!(f, "TestCoverageRenderError: {}", message) + } +} diff --git a/framework/meta/src/cmd/test_coverage/llvm_cov.rs b/framework/meta/src/cmd/test_coverage/llvm_cov.rs new file mode 100644 index 0000000000..5cb139e6de --- /dev/null +++ b/framework/meta/src/cmd/test_coverage/llvm_cov.rs @@ -0,0 +1,128 @@ +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use std::{path::PathBuf, process::Command}; + +use super::error::TestCoverageError; + +const DEFAULT_IGNORE_FILENAME_REGEX: [&str; 2] = ["/.cargo/registry", "rustc/"]; + +#[derive(Serialize, Deserialize)] +pub struct Coverage { + pub files: Vec, + pub totals: Summary, +} + +#[derive(Serialize, Deserialize)] +pub struct SummaryItem { + pub count: u64, + pub covered: u64, + pub percent: f64, +} + +#[derive(Serialize, Deserialize)] +pub struct Summary { + pub functions: SummaryItem, + pub lines: SummaryItem, + pub instantiations: SummaryItem, + pub regions: SummaryItem, +} + +#[derive(Serialize, Deserialize)] +pub struct FileSummary { + pub filename: String, + pub summary: Summary, +} + +fn parse_llvm_cov_output(output: &str) -> Result { + let llvm_cov_output: Value = serde_json::from_str(output) + .map_err(|_| TestCoverageError::LlvmCov("invalid output data".into()))?; + + let Some(coverage) = llvm_cov_output.get("data").and_then(|data| data.get(0)) else { + return Err(TestCoverageError::LlvmCov("invalid output data".into())); + }; + + let coverage = serde_json::from_value(coverage.to_owned()) + .map_err(|_| TestCoverageError::LlvmCov("invalid output data".into()))?; + + Ok(coverage) +} + +pub fn combine_instrumentation_results( + root_dir: &str, + profraw_files: &Vec, +) -> Result { + let Ok(output) = Command::new("llvm-profdata") + .current_dir(root_dir) + .args(vec!["merge", "-o", "merged.profdata", "-sparse"]) + .args(profraw_files) + .status() + else { + return Err(TestCoverageError::LlvmProfdata( + "can't merge profraw files".into(), + )); + }; + + if !output.success() { + return Err(TestCoverageError::LlvmProfdata( + "can't merge profraw files".into(), + )); + } + + let output_path = PathBuf::from(root_dir) + .join("merged.profdata") + .canonicalize() + .map_err(|_| { + TestCoverageError::FsError("can't get canonical path for merged.profdata".into()) + })?; + + Ok(output_path.to_string_lossy().to_string()) +} + +pub fn export_coverage_summary( + root_dir: &str, + profdata_file: &str, + binary_files: &[String], + ignore_filename_regex: &[String], +) -> Result { + let objects = binary_files + .iter() + .flat_map(|path| vec!["-object", path.as_str()]) + .collect::>(); + + let mut ignore_filename_regex = ignore_filename_regex + .iter() + .map(|s| format!("--ignore-filename-regex={}", s)) + .collect::>(); + + for ignore in DEFAULT_IGNORE_FILENAME_REGEX { + ignore_filename_regex.push(format!("--ignore-filename-regex={}", ignore)); + } + + let Ok(output) = Command::new("llvm-cov") + .current_dir(root_dir) + .arg("export") + .args(&objects) + .args(&ignore_filename_regex) + .args([ + &format!("--instr-profile={}", profdata_file), + "--summary-only", + "--format=text", + ]) + .output() + else { + return Err(TestCoverageError::LlvmCov( + "can't export coverage summary.".into(), + )); + }; + + if !output.status.success() { + return Err(TestCoverageError::LlvmCov( + "can't export coverage summary".into(), + )); + } + + let coverage = String::from_utf8_lossy(&output.stdout).to_string(); + let coverage = parse_llvm_cov_output(&coverage)?; + + Ok(coverage) +} diff --git a/framework/meta/src/cmd/test_coverage/render.rs b/framework/meta/src/cmd/test_coverage/render.rs new file mode 100644 index 0000000000..58d65adc06 --- /dev/null +++ b/framework/meta/src/cmd/test_coverage/render.rs @@ -0,0 +1,86 @@ +use super::llvm_cov::{Coverage, FileSummary, Summary}; + +use std::fmt::Write; + +fn writeln_output_str>(output: &mut String, input: S) { + output.write_str(&format!("{}\n", input.as_ref())).ok(); +} + +pub fn render_coverage(output: &mut String, coverage: &Coverage, root: &str) { + render_header(output); + render_totals(output, &coverage.totals); + render_files(output, &coverage.files, root); +} + +fn render_header(output: &mut String) { + writeln_output_str(output, "# Coverage Summary\n"); +} + +fn render_totals(output: &mut String, summary: &Summary) { + writeln_output_str(output, "## Totals"); + + writeln_output_str(output, "| | Count | Covered | % |"); + writeln_output_str(output, "|---|---|---|---|"); + writeln_output_str( + output, + format!( + "| Lines | {} | {} | {:.2} |", + summary.lines.count, summary.lines.covered, summary.lines.percent + ), + ); + writeln_output_str( + output, + format!( + "| Regions | {} | {} | {:.2} |", + summary.regions.count, summary.regions.covered, summary.regions.percent + ), + ); + writeln_output_str( + output, + format!( + "| Functions | {} | {} | {:.2} |", + summary.functions.count, summary.functions.covered, summary.functions.percent + ), + ); + writeln_output_str( + output, + format!( + "| Instantiations | {} | {} | {:.2} |\n", + summary.instantiations.count, + summary.instantiations.covered, + summary.instantiations.percent + ), + ); +} + +fn render_files(output: &mut String, files: &[FileSummary], root: &str) { + writeln_output_str(output, "## Files"); + writeln_output_str(output, "
Expand\n"); + writeln_output_str( + output, + "| File | Lines | Regions | Functions | Instantiations |", + ); + writeln_output_str(output, "|---|---|---|---|---|"); + for file in files { + render_file(output, file, root); + } + + writeln_output_str(output, "
"); +} + +fn render_file(output: &mut String, file: &FileSummary, root: &str) { + let summary = &file.summary; + let filename = file.filename.strip_prefix(root).unwrap_or(&file.filename); + + writeln_output_str( + output, + format!( + "| {} | {:.2}% | {:.2}% | {:.2}% | {:.2}% |", + filename, + summary.lines.percent, + summary.regions.percent, + summary.functions.percent, + summary.instantiations.percent + ), + ); +} diff --git a/framework/meta/src/cmd/test_coverage/run.rs b/framework/meta/src/cmd/test_coverage/run.rs new file mode 100644 index 0000000000..edb165824b --- /dev/null +++ b/framework/meta/src/cmd/test_coverage/run.rs @@ -0,0 +1,61 @@ +use std::fs; + +use crate::{ + cli::TestCoverageOutputFormat, + cmd::test_coverage::{ + cargo::{get_instrumented_test_binaries_paths, run_instrumented_tests}, + error::TestCoverageError, + llvm_cov::{combine_instrumentation_results, export_coverage_summary}, + render::render_coverage, + util::{ + cleanup_file, cleanup_many_files, deep_find_files_with_ext, ensure_dependencies_in_path, + }, + }, +}; + +pub fn run_test_coverage( + root_path: &str, + output_path: &str, + output_format: &TestCoverageOutputFormat, + ignore_filename_regex: &[String], +) -> Result<(), TestCoverageError> { + ensure_dependencies_in_path()?; + + run_instrumented_tests(root_path)?; + let test_binaries = get_instrumented_test_binaries_paths(root_path)?; + + let instrumentation_output_files = deep_find_files_with_ext(root_path, "profraw")?; + + let combined_instrumentation_output = + combine_instrumentation_results(root_path, &instrumentation_output_files)?; + + cleanup_many_files(&instrumentation_output_files)?; + + let coverage = export_coverage_summary( + root_path, + &combined_instrumentation_output, + &test_binaries, + ignore_filename_regex, + )?; + + cleanup_file(&combined_instrumentation_output)?; + + let mut output = String::new(); + + match output_format { + TestCoverageOutputFormat::Markdown => { + render_coverage(&mut output, &coverage, root_path); + }, + TestCoverageOutputFormat::Json => { + output = serde_json::to_string_pretty(&coverage).unwrap(); + }, + }; + + let Ok(_) = fs::write(output_path, output) else { + return Err(TestCoverageError::FsError(format!( + "failed to write to {output_path}" + ))); + }; + + Ok(()) +} diff --git a/framework/meta/src/cmd/test_coverage/util.rs b/framework/meta/src/cmd/test_coverage/util.rs new file mode 100644 index 0000000000..39c47fc2fb --- /dev/null +++ b/framework/meta/src/cmd/test_coverage/util.rs @@ -0,0 +1,56 @@ +use crate::cmd::test_coverage::error::TestCoverageError; +use std::{fs, process::Command}; + +const DEPENDENCIES: [&str; 2] = ["llvm-cov", "llvm-profdata"]; + +pub fn ensure_dependencies_in_path() -> Result<(), TestCoverageError> { + for dependency in DEPENDENCIES.iter() { + let Ok(_) = Command::new(dependency).arg("--version").output() else { + return Err(TestCoverageError::MissingDependency(dependency.to_string())); + }; + } + + Ok(()) +} + +pub fn deep_find_files_with_ext(dir: &str, ext: &str) -> Result, TestCoverageError> { + let mut result = vec![]; + + let dir_contents = fs::read_dir(dir) + .map_err(|_| TestCoverageError::FsError(format!("failed to read dir at path {dir}")))?; + + for entry in dir_contents { + let entry = entry.map_err(|_| { + TestCoverageError::FsError(format!("failed to read entry in dir at path {dir}")) + })?; + let path = entry.path(); + if path.is_dir() { + result.append(&mut deep_find_files_with_ext(path.to_str().unwrap(), ext)?); + } else if path.is_file() { + if let Some(file_ext) = path.extension() { + if file_ext == ext { + result.push(path.to_str().unwrap().to_string()); + } + } + } + } + + Ok(result) +} + +pub fn cleanup_many_files(files: &Vec) -> Result<(), TestCoverageError> { + for file in files { + fs::remove_file(file).map_err(|_| { + TestCoverageError::FsError(format!("failed to remove file at path {file}")) + })?; + } + + Ok(()) +} + +pub fn cleanup_file(file: &str) -> Result<(), TestCoverageError> { + fs::remove_file(file) + .map_err(|_| TestCoverageError::FsError(format!("failed to remove file at path {file}")))?; + + Ok(()) +} diff --git a/framework/meta/src/cmd/standalone/upgrade.rs b/framework/meta/src/cmd/upgrade.rs similarity index 93% rename from framework/meta/src/cmd/standalone/upgrade.rs rename to framework/meta/src/cmd/upgrade.rs index d7ced05dba..ab14b75075 100644 --- a/framework/meta/src/cmd/standalone/upgrade.rs +++ b/framework/meta/src/cmd/upgrade.rs @@ -2,6 +2,7 @@ mod upgrade_0_31; mod upgrade_0_32; mod upgrade_0_39; mod upgrade_0_45; +mod upgrade_0_51; pub(crate) mod upgrade_common; mod upgrade_print; mod upgrade_selector; diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_0_31.rs b/framework/meta/src/cmd/upgrade/upgrade_0_31.rs similarity index 100% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_0_31.rs rename to framework/meta/src/cmd/upgrade/upgrade_0_31.rs diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_0_32.rs b/framework/meta/src/cmd/upgrade/upgrade_0_32.rs similarity index 100% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_0_32.rs rename to framework/meta/src/cmd/upgrade/upgrade_0_32.rs diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_0_39.rs b/framework/meta/src/cmd/upgrade/upgrade_0_39.rs similarity index 96% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_0_39.rs rename to framework/meta/src/cmd/upgrade/upgrade_0_39.rs index 0ccd8dbf81..2f04a01610 100644 --- a/framework/meta/src/cmd/standalone/upgrade/upgrade_0_39.rs +++ b/framework/meta/src/cmd/upgrade/upgrade_0_39.rs @@ -6,10 +6,8 @@ use super::{ }, upgrade_print::*, }; -use crate::{ - folder_structure::{DirectoryType, RelevantDirectory}, - CargoTomlContents, -}; +use crate::folder_structure::{DirectoryType, RelevantDirectory}; +use multiversx_sc_meta_lib::cargo_toml_contents::CargoTomlContents; use ruplacer::Query; use toml::{value::Table, Value}; diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_0_45.rs b/framework/meta/src/cmd/upgrade/upgrade_0_45.rs similarity index 90% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_0_45.rs rename to framework/meta/src/cmd/upgrade/upgrade_0_45.rs index 21aa59ca1c..7082f92f97 100644 --- a/framework/meta/src/cmd/standalone/upgrade/upgrade_0_45.rs +++ b/framework/meta/src/cmd/upgrade/upgrade_0_45.rs @@ -1,10 +1,8 @@ use std::path::Path; use super::upgrade_common::version_bump_in_cargo_toml; -use crate::{ - folder_structure::{DirectoryType, RelevantDirectory}, - CargoTomlContents, -}; +use crate::folder_structure::{DirectoryType, RelevantDirectory}; +use multiversx_sc_meta_lib::cargo_toml_contents::CargoTomlContents; use toml::Value; /// Migrate `0.44.0` to `0.45.0`, including the version bump. diff --git a/framework/meta/src/cmd/upgrade/upgrade_0_51.rs b/framework/meta/src/cmd/upgrade/upgrade_0_51.rs new file mode 100644 index 0000000000..d5f4cdb03a --- /dev/null +++ b/framework/meta/src/cmd/upgrade/upgrade_0_51.rs @@ -0,0 +1,54 @@ +use super::upgrade_common::{replace_in_files, version_bump_in_cargo_toml}; +use super::upgrade_print::*; +use crate::folder_structure::{DirectoryType, RelevantDirectory}; +use multiversx_sc_meta_lib::cargo_toml_contents::CargoTomlContents; +use ruplacer::Query; +use std::path::Path; +use toml::Value; + +/// Migrate `0.50` to `0.51.0`, including the version bump. +pub fn upgrade_to_51_0(dir: &RelevantDirectory) { + if dir.dir_type == DirectoryType::Contract { + v_0_51_prepare_meta(dir.path.as_ref()); + } + v_0_51_replace_in_files(dir.path.as_ref()); + + let (from_version, to_version) = dir.upgrade_in_progress.clone().unwrap(); + version_bump_in_cargo_toml(&dir.path, &from_version, &to_version); +} + +fn v_0_51_replace_in_files(sc_crate_path: &Path) { + replace_in_files( + sc_crate_path, + "*rs", + &[Query::substring( + "multiversx_sc_meta", + "multiversx_sc_meta_lib", + )][..], + ); +} + +fn v_0_51_prepare_meta(sc_crate_path: &Path) { + let cargo_toml_path = sc_crate_path.join("meta/Cargo.toml"); + assert!( + cargo_toml_path.exists(), + "SC crate Cargo.toml not found: {}", + cargo_toml_path.display() + ); + let mut meta_cargo_toml = CargoTomlContents::load_from_file(&cargo_toml_path); + let deps = meta_cargo_toml.dependencies_mut(); + + print_cargo_dep_remove(cargo_toml_path.as_path(), "multiversx-sc-meta"); + let mut meta_value = deps + .remove("multiversx-sc-meta") + .expect("multiversx-sc-meta dependency not found in meta crate"); + + if let Some(Value::String(path)) = meta_value.get_mut("path") { + path.push_str("-lib"); + } + + print_cargo_dep_add(cargo_toml_path.as_path(), "multiversx-sc-meta"); + deps.insert("multiversx-sc-meta-lib".to_string(), meta_value); + + meta_cargo_toml.save_to_file(&cargo_toml_path); +} diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_common.rs b/framework/meta/src/cmd/upgrade/upgrade_common.rs similarity index 97% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_common.rs rename to framework/meta/src/cmd/upgrade/upgrade_common.rs index b4ed18d07c..5d97cbafe6 100644 --- a/framework/meta/src/cmd/standalone/upgrade/upgrade_common.rs +++ b/framework/meta/src/cmd/upgrade/upgrade_common.rs @@ -1,3 +1,14 @@ +use super::{upgrade_print::*, upgrade_settings::UpgradeSettings}; +use crate::{ + cmd::all::call_contract_meta, + folder_structure::{ + DirectoryType, RelevantDirectory, VersionReq, CARGO_TOML_FILE_NAME, FRAMEWORK_CRATE_NAMES, + }, + version::FrameworkVersion, +}; +use multiversx_sc_meta_lib::cargo_toml_contents::{ + CargoTomlContents, CARGO_TOML_DEPENDENCIES, CARGO_TOML_DEV_DEPENDENCIES, +}; use ruplacer::{Console, DirectoryPatcher, Query, Settings}; use std::{ fs, @@ -6,18 +17,6 @@ use std::{ }; use toml::Value; -use crate::{ - cargo_toml_contents::{CARGO_TOML_DEPENDENCIES, CARGO_TOML_DEV_DEPENDENCIES}, - cmd::standalone::all::call_contract_meta, - folder_structure::{ - DirectoryType, RelevantDirectory, VersionReq, CARGO_TOML_FILE_NAME, FRAMEWORK_CRATE_NAMES, - }, - version::FrameworkVersion, - CargoTomlContents, -}; - -use super::{upgrade_print::*, upgrade_settings::UpgradeSettings}; - /// Uses ruplacer. pub(crate) fn replace_in_files(sc_crate_path: &Path, file_type: &str, queries: &[Query]) { if !sc_crate_path.exists() { diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_print.rs b/framework/meta/src/cmd/upgrade/upgrade_print.rs similarity index 100% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_print.rs rename to framework/meta/src/cmd/upgrade/upgrade_print.rs diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_selector.rs b/framework/meta/src/cmd/upgrade/upgrade_selector.rs similarity index 92% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_selector.rs rename to framework/meta/src/cmd/upgrade/upgrade_selector.rs index e2d0ef4d86..0f958b176e 100644 --- a/framework/meta/src/cmd/standalone/upgrade/upgrade_selector.rs +++ b/framework/meta/src/cmd/upgrade/upgrade_selector.rs @@ -1,17 +1,18 @@ use crate::{ - cli_args::UpgradeArgs, - cmd::standalone::upgrade::upgrade_settings::UpgradeSettings, + cli::UpgradeArgs, + cmd::upgrade::upgrade_settings::UpgradeSettings, folder_structure::{dir_pretty_print, RelevantDirectories, RelevantDirectory}, - framework_version, version::FrameworkVersion, version_history::{versions_iter, CHECK_AFTER_UPGRADE_TO, LAST_UPGRADE_VERSION, VERSIONS}, }; +use multiversx_sc_meta_lib::framework_version; use super::{ upgrade_0_31::upgrade_to_31_0, upgrade_0_32::upgrade_to_32_0, upgrade_0_39::{postprocessing_after_39_0, upgrade_to_39_0}, upgrade_0_45::upgrade_to_45_0, + upgrade_0_51::upgrade_to_51_0, upgrade_common::{cargo_check, version_bump_in_cargo_toml}, upgrade_print::*, }; @@ -86,6 +87,8 @@ fn upgrade_function_selector(dir: &RelevantDirectory) { upgrade_to_39_0(dir) } else if framework_version!(0.45.0) == *to_version { upgrade_to_45_0(dir) + } else if framework_version!(0.51.0) == *to_version { + upgrade_to_51_0(dir) } else { version_bump_in_cargo_toml(&dir.path, from_version, to_version) } diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_settings.rs b/framework/meta/src/cmd/upgrade/upgrade_settings.rs similarity index 100% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_settings.rs rename to framework/meta/src/cmd/upgrade/upgrade_settings.rs diff --git a/framework/meta/src/folder_structure/relevant_directory.rs b/framework/meta/src/folder_structure/relevant_directory.rs index f49b1d07ca..95a7a3610b 100644 --- a/framework/meta/src/folder_structure/relevant_directory.rs +++ b/framework/meta/src/folder_structure/relevant_directory.rs @@ -1,4 +1,5 @@ -use crate::{version::FrameworkVersion, CargoTomlContents}; +use crate::version::FrameworkVersion; +use multiversx_sc_meta_lib::cargo_toml_contents::CargoTomlContents; use std::{ fs::{self, DirEntry}, path::{Path, PathBuf}, diff --git a/framework/meta/src/lib.rs b/framework/meta/src/lib.rs index 718ad4eea9..b74df97748 100644 --- a/framework/meta/src/lib.rs +++ b/framework/meta/src/lib.rs @@ -1,21 +1,31 @@ -pub mod abi_json; -mod cargo_toml_contents; -pub mod cli_args; +pub mod cli; pub mod cmd; -pub mod ei; -mod ei_check_json; -pub mod esdt_attr_file_json; pub mod folder_structure; -mod mxsc_file_json; -mod print_util; -mod report_info_json; -mod tools; -pub use tools::find_workspace; -pub mod version; -pub mod version_history; -#[macro_use] -extern crate lazy_static; +pub use multiversx_sc_meta_lib::abi_json; +pub use multiversx_sc_meta_lib::ei; +pub use multiversx_sc_meta_lib::ei_check_json; +pub use multiversx_sc_meta_lib::version; +pub use multiversx_sc_meta_lib::version_history; -pub use cargo_toml_contents::CargoTomlContents; -pub use cmd::contract::{cli_main, multi_contract_config}; +/// Backwards compatibility, please use `multiversx_sc_meta_lib::cli_main::()`. +/// +/// Failure to do so will result in slower build time. +#[deprecated( + since = "0.41.0", + note = "Backwards compatibility only, please use `cli_main` from crate `multiversx-sc-meta-lib` instead." +)] +pub fn cli_main() { + multiversx_sc_meta_lib::cli_main::() +} + +/// Backwards compatibility, please use `multiversx_sc_meta_lib::multi_contract_config::(contract_crate_path)`. +#[deprecated( + since = "0.41.0", + note = "Backwards compatibility only, please use `multi_contract_config` from crate `multiversx-sc-meta-lib` instead." +)] +pub fn multi_contract_config( + contract_crate_path: &std::path::Path, +) -> multiversx_sc_meta_lib::contract::sc_config::ScConfig { + multiversx_sc_meta_lib::multi_contract_config::(contract_crate_path) +} diff --git a/framework/meta/src/main.rs b/framework/meta/src/main.rs index 72b1eaef2c..bf9813b1d0 100644 --- a/framework/meta/src/main.rs +++ b/framework/meta/src/main.rs @@ -1,3 +1,4 @@ -fn main() { - multiversx_sc_meta::cmd::standalone::cli_main_standalone(); +#[tokio::main] +async fn main() { + multiversx_sc_meta::cli::cli_main_standalone().await; } diff --git a/framework/meta/tests/stg_process_code_test.rs b/framework/meta/tests/stg_process_code_test.rs index 827151aa99..e544935dbb 100644 --- a/framework/meta/tests/stg_process_code_test.rs +++ b/framework/meta/tests/stg_process_code_test.rs @@ -1,6 +1,4 @@ -use multiversx_sc_meta::cmd::standalone::scen_test_gen::{ - format_test_fn_go, process_code, DEFAULT_SETUP_GO, -}; +use multiversx_sc_meta::cmd::scen_test_gen::{format_test_fn_go, process_code, DEFAULT_SETUP_GO}; const GO_TEST_1: &str = r#"use multiversx_sc_scenario::*; diff --git a/framework/meta/tests/template_test.rs b/framework/meta/tests/template_test.rs index e3463d09a2..4b0fc0bc23 100644 --- a/framework/meta/tests/template_test.rs +++ b/framework/meta/tests/template_test.rs @@ -2,12 +2,12 @@ use std::{fs, process::Command}; use convert_case::{Case, Casing}; use multiversx_sc_meta::{ - cmd::standalone::template::{ + cmd::template::{ template_names_from_repo, ContractCreator, ContractCreatorTarget, RepoSource, RepoVersion, }, - find_workspace::find_current_workspace, version_history::{self, LAST_TEMPLATE_VERSION}, }; +use multiversx_sc_meta_lib::tools::find_current_workspace; const TEMPLATE_TEMP_DIR_NAME: &str = "template-test"; const BUILD_CONTRACTS: bool = true; @@ -33,6 +33,8 @@ fn test_template_list() { #[cfg_attr(not(feature = "template-test-current"), ignore)] fn template_current_adder() { template_test_current("adder", "examples", "new-adder"); + + cargo_check_interactor("examples", "new-adder"); } #[test] @@ -96,6 +98,8 @@ fn template_test_current(template_name: &str, sub_path: &str, new_name: &str) { #[cfg_attr(not(feature = "template-test-released"), ignore)] fn template_released_adder() { template_test_released("adder", "released-adder"); + + cargo_check_interactor("", "released-adder"); } #[test] @@ -198,3 +202,22 @@ pub fn build_contract(target: &ContractCreatorTarget) { assert!(exit_status.success(), "contract build process failed"); } + +fn cargo_check_interactor(sub_path: &str, new_name: &str) { + let workspace_path = find_current_workspace().unwrap(); + let target_path = workspace_path + .join(TEMPLATE_TEMP_DIR_NAME) + .join(sub_path) + .join(new_name) + .join("interact"); + + let exit_status = Command::new("cargo") + .arg("check") + .current_dir(target_path) + .spawn() + .expect("failed to spawn contract clean process") + .wait() + .expect("contract test process was not running"); + + assert!(exit_status.success(), "contract test process failed"); +} diff --git a/framework/scenario/Cargo.toml b/framework/scenario/Cargo.toml index 560cf08281..b41d274621 100644 --- a/framework/scenario/Cargo.toml +++ b/framework/scenario/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-scenario" -version = "0.47.5" +version = "0.50.3" edition = "2021" authors = [ @@ -17,7 +17,7 @@ keywords = ["multiversx", "blockchain", "contract", "debug"] categories = ["cryptography::cryptocurrencies", "development-tools::debugging"] [dependencies] -base64 = "0.21.5" +base64 = "0.22" num-bigint = "0.4" num-traits = "0.2" hex = "0.4" @@ -31,22 +31,19 @@ itertools = "0.12.0" colored = "2.0" clap = { version = "4.4.7", features = ["derive"] } tokio = { version = "1.24", features = ["full"] } - -[[bin]] -name = "sc-scenario" -path = "src/main.rs" +unwrap-infallible = "0.1.5" [features] run-go-tests = [] [dependencies.multiversx-sc] -version = "=0.47.5" +version = "=0.50.3" features = ["alloc", "num-bigint"] path = "../base" -[dependencies.multiversx-sc-meta] -version = "=0.47.5" -path = "../meta" +[dependencies.multiversx-sc-meta-lib] +version = "=0.50.3" +path = "../meta-lib" [dependencies.multiversx-chain-scenario-format] version = "0.22.2" @@ -56,9 +53,9 @@ path = "../../sdk/scenario-format" version = "0.2.0" [dependencies.multiversx-chain-vm] -version = "=0.8.3" +version = "=0.8.4" path = "../../vm" [dependencies.multiversx-sdk] -version = "=0.3.2" +version = "=0.4.1" path = "../../sdk/core" diff --git a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs index 6174bc06b7..0623270758 100644 --- a/framework/scenario/src/api/impl_vh/debug_handle_vh.rs +++ b/framework/scenario/src/api/impl_vh/debug_handle_vh.rs @@ -77,7 +77,7 @@ impl From for DebugHandle { } impl ManagedVecItem for DebugHandle { - const PAYLOAD_SIZE: usize = ::PAYLOAD_SIZE; + type PAYLOAD = ::PAYLOAD; const SKIPS_RESERIALIZATION: bool = ::SKIPS_RESERIALIZATION; diff --git a/framework/scenario/src/api/impl_vh/static_api.rs b/framework/scenario/src/api/impl_vh/static_api.rs index 7834227314..7e375a0c31 100644 --- a/framework/scenario/src/api/impl_vh/static_api.rs +++ b/framework/scenario/src/api/impl_vh/static_api.rs @@ -3,6 +3,7 @@ use multiversx_chain_vm::{ vm_hooks::{StaticApiVMHooksHandler, VMHooksDispatcher, VMHooksHandler}, }; use multiversx_sc::{api::RawHandle, types::Address}; +use std::sync::Mutex; use crate::debug_executor::StaticVarData; @@ -14,9 +15,9 @@ fn new_static_api_vh() -> VMHooksDispatcher { } thread_local! { - static STATIC_API_VH_CELL: VMHooksDispatcher = new_static_api_vh(); + static STATIC_API_VH_CELL: Mutex = Mutex::new(new_static_api_vh()); - static STATIC_API_STATIC_CELL: StaticVarData = StaticVarData::default(); + static STATIC_API_STATIC_CELL: Mutex = Mutex::new(StaticVarData::default()); } #[derive(Clone)] @@ -29,14 +30,20 @@ impl VMHooksApiBackend for StaticApiBackend { where F: FnOnce(&dyn VMHooks) -> R, { - STATIC_API_VH_CELL.with(|vh| f(vh)) + STATIC_API_VH_CELL.with(|vh_mutex| { + let vh = vh_mutex.lock().unwrap(); + f(&*vh) + }) } fn with_static_data(f: F) -> R where F: FnOnce(&StaticVarData) -> R, { - STATIC_API_STATIC_CELL.with(|data| f(data)) + STATIC_API_STATIC_CELL.with(|data_mutex| { + let data = data_mutex.lock().unwrap(); + f(&data) + }) } } @@ -50,6 +57,18 @@ impl StaticApi { pub fn is_current_address_placeholder(address: &Address) -> bool { address.as_array() == StaticApiVMHooksHandler::CURRENT_ADDRESS_PLACEHOLDER.as_array() } + + pub fn reset() { + STATIC_API_VH_CELL.with(|vh_mutex| { + let mut vh = vh_mutex.lock().unwrap(); + *vh = new_static_api_vh() + }); + + STATIC_API_STATIC_CELL.with(|data_mutex| { + let mut data = data_mutex.lock().unwrap(); + *data = StaticVarData::default() + }) + } } impl std::fmt::Debug for StaticApi { diff --git a/framework/scenario/src/api/local_api_vh/print_api_vh.rs b/framework/scenario/src/api/local_api_vh/print_api_vh.rs index 6774e9546d..6d3f9b3dbe 100644 --- a/framework/scenario/src/api/local_api_vh/print_api_vh.rs +++ b/framework/scenario/src/api/local_api_vh/print_api_vh.rs @@ -2,13 +2,13 @@ use std::cell::RefCell; use multiversx_sc::{ api::{PrintApi, PrintApiImpl}, - types::ManagedBufferCachedBuilder, + types::ManagedBufferBuilder, }; use crate::api::{VMHooksApi, VMHooksApiBackend}; thread_local!( - static PRINTED_MESSAGES: RefCell> = RefCell::new(Vec::new()) + static PRINTED_MESSAGES: RefCell> = const { RefCell::new(Vec::new()) } ); impl VMHooksApi { @@ -34,7 +34,7 @@ impl PrintApi for VMHooksApi { } impl PrintApiImpl for VMHooksApi { - type Buffer = ManagedBufferCachedBuilder; + type Buffer = ManagedBufferBuilder; fn print_buffer(&self, buffer: Self::Buffer) { let bytes = buffer.into_managed_buffer().to_boxed_bytes(); diff --git a/framework/scenario/src/api/managed_type_api_vh/managed_buffer_api_vh.rs b/framework/scenario/src/api/managed_type_api_vh/managed_buffer_api_vh.rs index 09e7d9137f..22a0c152cc 100644 --- a/framework/scenario/src/api/managed_type_api_vh/managed_buffer_api_vh.rs +++ b/framework/scenario/src/api/managed_type_api_vh/managed_buffer_api_vh.rs @@ -29,16 +29,14 @@ impl ManagedBufferApiImpl for VMHooksApi { fn mb_to_boxed_bytes(&self, handle: Self::ManagedBufferHandle) -> BoxedBytes { self.with_vm_hooks_ctx_1(&handle, |vh| { let len = vh.mbuffer_get_length(handle.get_raw_handle_unchecked()) as usize; - unsafe { - let mut res = BoxedBytes::allocate(len); - if len > 0 { - let _ = vh.mbuffer_get_bytes( - handle.get_raw_handle_unchecked(), - res.as_mut_ptr() as MemPtr, - ); - } - res + let mut res = BoxedBytes::zeros(len); + if len > 0 { + let _ = vh.mbuffer_get_bytes( + handle.get_raw_handle_unchecked(), + res.as_mut_ptr() as MemPtr, + ); } + res }) } diff --git a/framework/scenario/src/bech32.rs b/framework/scenario/src/bech32.rs index 4b72107bb8..aa224cee95 100644 --- a/framework/scenario/src/bech32.rs +++ b/framework/scenario/src/bech32.rs @@ -2,7 +2,8 @@ use bech32::{FromBase32, ToBase32, Variant}; use multiversx_sc::types::heap::Address; pub fn decode(bech32_address: &str) -> Address { - let (_, dest_address_bytes_u5, _) = bech32::decode(bech32_address).unwrap(); + let (_, dest_address_bytes_u5, _) = bech32::decode(bech32_address) + .unwrap_or_else(|err| panic!("bech32 decode error for {bech32_address}: {err}")); let dest_address_bytes = Vec::::from_base32(&dest_address_bytes_u5).unwrap(); if dest_address_bytes.len() != 32 { panic!("Invalid address length after decoding") diff --git a/framework/scenario/src/facade.rs b/framework/scenario/src/facade.rs index f53625895e..75a688a36a 100644 --- a/framework/scenario/src/facade.rs +++ b/framework/scenario/src/facade.rs @@ -1,11 +1,15 @@ mod contract_info; mod debugger_backend; +pub mod expr; +pub mod result_handlers; mod scenario_world; +mod scenario_world_register; mod scenario_world_runner; mod scenario_world_steps; mod scenario_world_steps_deprecated; mod scenario_world_whitebox; mod whitebox_contract; +pub mod world_tx; pub use contract_info::ContractInfo; pub use scenario_world::ScenarioWorld; diff --git a/framework/scenario/src/facade/contract_info.rs b/framework/scenario/src/facade/contract_info.rs index 35b3ee1afb..73b0f4935c 100644 --- a/framework/scenario/src/facade/contract_info.rs +++ b/framework/scenario/src/facade/contract_info.rs @@ -1,9 +1,14 @@ use std::ops::{Deref, DerefMut}; +use multiversx_sc::{ + abi::TypeAbiFrom, + types::{AnnotatedValue, ManagedBuffer, TxEnv, TxFrom, TxFromSpecified, TxTo, TxToSpecified}, +}; + use crate::multiversx_sc::{ api::ManagedTypeApi, - codec::{CodecFrom, EncodeErrorHandler, TopEncode, TopEncodeOutput}, - contract_base::ProxyObjBase, + codec::{EncodeErrorHandler, TopEncode, TopEncodeOutput}, + contract_base::ProxyObjNew, types::{Address, ManagedAddress}, }; @@ -11,12 +16,15 @@ use crate::scenario::model::{AddressKey, AddressValue}; /// Bundles a representation of a contract with the contract proxy, /// so that it can be easily called in the context of a blockchain mock. -pub struct ContractInfo { +pub struct ContractInfo { pub scenario_address_expr: AddressKey, - proxy_inst: P, + proxy_inst: P::ProxyTo, } -impl ContractInfo

{ +impl

ContractInfo

+where + P: ProxyObjNew, +{ pub fn new(address_expr: A) -> Self where AddressKey: From, @@ -32,49 +40,59 @@ impl ContractInfo

{ pub fn to_address(&self) -> Address { self.scenario_address_expr.to_address() } + + /// For historical reasons the proxy consumes its address whenever it is called. + /// + /// When using it in tests, as part of `ContractInfo`, + /// it is convenient to refresh it before each call. + /// + /// It is sort of a hack, designed to optimize proxy use in contracts, + /// while making it easier to use in tests. + fn refresh_proxy_address(&mut self) { + self.proxy_inst = + P::new_proxy_obj().contract(self.scenario_address_expr.value.clone().into()); + } } -impl From<&ContractInfo

> for AddressKey { +impl From<&ContractInfo

> for AddressKey { fn from(from: &ContractInfo

) -> Self { from.scenario_address_expr.clone() } } -impl From> for AddressKey { +impl From> for AddressKey { fn from(from: ContractInfo

) -> Self { from.scenario_address_expr } } -impl From<&ContractInfo

> for AddressValue { +impl From<&ContractInfo

> for AddressValue { fn from(from: &ContractInfo

) -> Self { AddressValue::from(&from.scenario_address_expr) } } -impl From> for AddressValue { +impl From> for AddressValue { fn from(from: ContractInfo

) -> Self { AddressValue::from(&from.scenario_address_expr) } } -impl Deref for ContractInfo

{ - type Target = P; +impl Deref for ContractInfo

{ + type Target = P::ProxyTo; fn deref(&self) -> &Self::Target { &self.proxy_inst } } -impl DerefMut for ContractInfo

{ +impl DerefMut for ContractInfo

{ fn deref_mut(&mut self) -> &mut Self::Target { - let proxy_inst = core::mem::replace(&mut self.proxy_inst, P::new_proxy_obj()); - let proxy_inst = proxy_inst.contract(self.scenario_address_expr.value.clone().into()); - let _ = core::mem::replace(&mut self.proxy_inst, proxy_inst); + self.refresh_proxy_address(); &mut self.proxy_inst } } -impl TopEncode for ContractInfo

{ +impl TopEncode for ContractInfo

{ fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> where O: TopEncodeOutput, @@ -86,7 +104,49 @@ impl TopEncode for ContractInfo

{ } } -impl CodecFrom> for Address {} -impl CodecFrom<&ContractInfo

> for Address {} -impl CodecFrom> for ManagedAddress {} -impl CodecFrom<&ContractInfo

> for ManagedAddress {} +impl TypeAbiFrom> for Address {} +impl TypeAbiFrom<&ContractInfo

> for Address {} +impl TypeAbiFrom> for ManagedAddress {} +impl TypeAbiFrom<&ContractInfo

> for ManagedAddress {} + +impl AnnotatedValue> for &ContractInfo

+where + Env: TxEnv, + P: ProxyObjNew, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.scenario_address_expr.original.as_str().into() + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + (&self.scenario_address_expr.value).into() + } +} + +impl TxFrom for &ContractInfo

+where + Env: TxEnv, + P: ProxyObjNew, +{ + fn resolve_address(&self, _env: &Env) -> ManagedAddress { + (&self.scenario_address_expr.value).into() + } +} +impl TxFromSpecified for &ContractInfo

+where + Env: TxEnv, + P: ProxyObjNew, +{ +} +impl TxTo for &ContractInfo

+where + Env: TxEnv, + P: ProxyObjNew, +{ +} +impl TxToSpecified for &ContractInfo

+where + Env: TxEnv, + P: ProxyObjNew, +{ +} diff --git a/framework/scenario/src/facade/expr.rs b/framework/scenario/src/facade/expr.rs new file mode 100644 index 0000000000..2ca60a5192 --- /dev/null +++ b/framework/scenario/src/facade/expr.rs @@ -0,0 +1,11 @@ +mod bech32_address; +mod file_path; +mod mxsc_path; +mod num_expr; +mod register_code_source; + +pub use bech32_address::Bech32Address; +pub use file_path::FilePath; +pub use mxsc_path::MxscPath; +pub use num_expr::NumExpr; +pub use register_code_source::RegisterCodeSource; diff --git a/framework/scenario/src/facade/expr/bech32_address.rs b/framework/scenario/src/facade/expr/bech32_address.rs new file mode 100644 index 0000000000..c404d17e27 --- /dev/null +++ b/framework/scenario/src/facade/expr/bech32_address.rs @@ -0,0 +1,205 @@ +use std::fmt::Display; + +use crate::bech32; +use multiversx_sc::{ + abi::TypeAbiFrom, + api::ManagedTypeApi, + codec::*, + types::{ + Address, AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom, TxFromSpecified, + TxTo, TxToSpecified, + }, +}; +use serde::{Deserialize, Serialize}; + +const BECH32_PREFIX: &str = "bech32:"; + +/// Wraps and address, and presents it as a bech32 expression wherever possible. +/// +/// In order to avoid repeated conversions, it redundantly keeps the bech32 representation inside. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Bech32Address { + address: Address, + bech32: String, +} + +impl From

for Bech32Address { + fn from(value: Address) -> Self { + let bech32 = bech32::encode(&value); + Bech32Address { + address: value, + bech32, + } + } +} + +impl From<&Address> for Bech32Address { + fn from(value: &Address) -> Self { + let bech32 = bech32::encode(value); + Bech32Address { + address: value.clone(), + bech32, + } + } +} + +impl Bech32Address { + pub fn from_bech32_string(bech32: String) -> Self { + let address = bech32::decode(&bech32); + Bech32Address { address, bech32 } + } + + pub fn to_bech32_str(&self) -> &str { + &self.bech32 + } + + pub fn to_bech32_string(&self) -> String { + self.bech32.to_owned() + } + + pub fn to_hex(&self) -> String { + hex::encode(&self.address) + } + + pub fn as_address(&self) -> &Address { + &self.address + } + + pub fn to_address(&self) -> Address { + self.address.clone() + } + + pub fn into_address(self) -> Address { + self.address + } + + pub fn to_bech32_expr(&self) -> String { + format!("{BECH32_PREFIX}{}", &self.bech32) + } +} + +impl AnnotatedValue> for Bech32Address +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.to_bech32_expr().into() + } + + fn to_value(&self, env: &Env) -> ManagedAddress { + self.address.to_value(env) + } +} + +impl TxFrom for Bech32Address +where + Env: TxEnv, +{ + fn resolve_address(&self, env: &Env) -> ManagedAddress { + self.address.resolve_address(env) + } +} +impl TxFromSpecified for Bech32Address where Env: TxEnv {} +impl TxTo for Bech32Address where Env: TxEnv {} +impl TxToSpecified for Bech32Address where Env: TxEnv {} + +impl AnnotatedValue> for &Bech32Address +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.to_bech32_expr().into() + } + + fn to_value(&self, env: &Env) -> ManagedAddress { + self.address.to_value(env) + } +} + +impl TxFrom for &Bech32Address +where + Env: TxEnv, +{ + fn resolve_address(&self, env: &Env) -> ManagedAddress { + self.address.resolve_address(env) + } +} +impl TxFromSpecified for &Bech32Address where Env: TxEnv {} +impl TxTo for &Bech32Address where Env: TxEnv {} +impl TxToSpecified for &Bech32Address where Env: TxEnv {} + +impl Display for Bech32Address { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.bech32) + } +} + +impl NestedEncode for Bech32Address { + fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> + where + O: NestedEncodeOutput, + H: EncodeErrorHandler, + { + self.address.dep_encode_or_handle_err(dest, h) + } +} + +impl TopEncode for Bech32Address { + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + self.address.top_encode_or_handle_err(output, h) + } +} + +impl NestedDecode for Bech32Address { + fn dep_decode_or_handle_err(input: &mut I, h: H) -> Result + where + I: NestedDecodeInput, + H: DecodeErrorHandler, + { + Ok(Bech32Address::from(Address::dep_decode_or_handle_err( + input, h, + )?)) + } +} + +impl TopDecode for Bech32Address { + fn top_decode_or_handle_err(input: I, h: H) -> Result + where + I: TopDecodeInput, + H: DecodeErrorHandler, + { + Ok(Bech32Address::from(Address::top_decode_or_handle_err( + input, h, + )?)) + } +} + +impl TypeAbiFrom for ManagedAddress where M: ManagedTypeApi {} +impl TypeAbiFrom<&Bech32Address> for ManagedAddress where M: ManagedTypeApi {} + +impl Serialize for Bech32Address { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.bech32.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for Bech32Address { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + // some old interactors have it serialized like this + let mut bech32 = String::deserialize(deserializer)?; + if let Some(stripped) = bech32.strip_prefix("bech32:") { + bech32 = stripped.to_string(); + } + Ok(Bech32Address::from_bech32_string(bech32)) + } +} diff --git a/framework/scenario/src/facade/expr/file_path.rs b/framework/scenario/src/facade/expr/file_path.rs new file mode 100644 index 0000000000..8d779a6fd1 --- /dev/null +++ b/framework/scenario/src/facade/expr/file_path.rs @@ -0,0 +1,45 @@ +use multiversx_chain_scenario_format::{ + interpret_trait::InterpreterContext, value_interpreter::interpret_string, +}; +use multiversx_sc::types::{AnnotatedValue, ManagedBuffer, TxCodeValue}; + +use crate::{ScenarioTxEnv, ScenarioTxEnvData}; + +use super::RegisterCodeSource; + +const FILE_PREFIX: &str = "file:"; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct FilePath<'a>(pub &'a str); + +impl<'a> FilePath<'a> { + pub fn eval_to_expr(&self) -> String { + format!("{FILE_PREFIX}{}", self.0) + } + + pub fn resolve_contents(&self, context: &InterpreterContext) -> Vec { + interpret_string(&format!("{FILE_PREFIX}{}", self.0), context) + } +} + +impl<'a, Env> AnnotatedValue> for FilePath<'a> +where + Env: ScenarioTxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.eval_to_expr().into() + } + + fn to_value(&self, env: &Env) -> ManagedBuffer { + self.resolve_contents(&env.env_data().interpreter_context()) + .into() + } +} + +impl<'a, Env> TxCodeValue for FilePath<'a> where Env: ScenarioTxEnv {} + +impl<'a> RegisterCodeSource for FilePath<'a> { + fn into_code(self, env_data: ScenarioTxEnvData) -> Vec { + self.resolve_contents(&env_data.interpreter_context()) + } +} diff --git a/framework/scenario/src/facade/expr/mxsc_path.rs b/framework/scenario/src/facade/expr/mxsc_path.rs new file mode 100644 index 0000000000..465eb5f097 --- /dev/null +++ b/framework/scenario/src/facade/expr/mxsc_path.rs @@ -0,0 +1,67 @@ +use multiversx_chain_scenario_format::{ + interpret_trait::InterpreterContext, value_interpreter::interpret_string, +}; +use multiversx_sc::types::{AnnotatedValue, ManagedBuffer, TxCodeValue}; + +use crate::{ScenarioTxEnv, ScenarioTxEnvData}; + +use super::RegisterCodeSource; + +const MXSC_PREFIX: &str = "mxsc:"; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct MxscPath<'a> { + path: &'a str, +} + +impl<'a> MxscPath<'a> { + pub const fn new(path: &'a str) -> Self { + MxscPath { path } + } +} + +impl<'a> MxscPath<'a> { + pub fn eval_to_expr(&self) -> String { + format!("{MXSC_PREFIX}{}", self.path) + } + + pub fn resolve_contents(&self, context: &InterpreterContext) -> Vec { + interpret_string(&format!("{MXSC_PREFIX}{}", self.path), context) + } +} + +impl<'a, Env> AnnotatedValue> for MxscPath<'a> +where + Env: ScenarioTxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.eval_to_expr().into() + } + + fn to_value(&self, env: &Env) -> ManagedBuffer { + self.resolve_contents(&env.env_data().interpreter_context()) + .into() + } +} + +impl<'a, Env> TxCodeValue for MxscPath<'a> where Env: ScenarioTxEnv {} + +impl<'a> RegisterCodeSource for MxscPath<'a> { + fn into_code(self, env_data: ScenarioTxEnvData) -> Vec { + self.resolve_contents(&env_data.interpreter_context()) + } +} + +#[cfg(test)] +pub mod tests { + use crate::imports::MxscPath; + + fn assert_eq_eval(expr: &'static str, expected: &str) { + assert_eq!(&MxscPath::new(expr).eval_to_expr(), expected); + } + + #[test] + fn test_address_value() { + assert_eq_eval("output/adder.mxsc.json", "mxsc:output/adder.mxsc.json"); + } +} diff --git a/framework/scenario/src/facade/expr/num_expr.rs b/framework/scenario/src/facade/expr/num_expr.rs new file mode 100644 index 0000000000..704f52496b --- /dev/null +++ b/framework/scenario/src/facade/expr/num_expr.rs @@ -0,0 +1,49 @@ +use crate::ScenarioTxEnv; + +use multiversx_chain_scenario_format::{ + interpret_trait::InterpreterContext, value_interpreter::interpret_string, +}; +use multiversx_sc::{ + api::ManagedTypeApi, + types::{AnnotatedValue, BigUint, ManagedBuffer, TxEgldValue, TxGasValue}, +}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct NumExpr<'a>(pub &'a str); + +fn interpret_big_uint(s: &str) -> BigUint +where + Api: ManagedTypeApi, +{ + let bytes = interpret_string(s, &InterpreterContext::new()); + BigUint::from_bytes_be(&bytes) +} + +impl<'a, Env> AnnotatedValue> for NumExpr<'a> +where + Env: ScenarioTxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.0.into() + } + + fn to_value(&self, _env: &Env) -> BigUint { + interpret_big_uint(self.0) + } +} + +impl<'a, Env> AnnotatedValue for NumExpr<'a> +where + Env: ScenarioTxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + self.0.into() + } + + fn to_value(&self, _env: &Env) -> u64 { + interpret_big_uint::(self.0).to_u64().unwrap() + } +} + +impl<'a, Env> TxEgldValue for NumExpr<'a> where Env: ScenarioTxEnv {} +impl<'a, Env> TxGasValue for NumExpr<'a> where Env: ScenarioTxEnv {} diff --git a/framework/scenario/src/facade/expr/register_code_source.rs b/framework/scenario/src/facade/expr/register_code_source.rs new file mode 100644 index 0000000000..d586498a0f --- /dev/null +++ b/framework/scenario/src/facade/expr/register_code_source.rs @@ -0,0 +1,28 @@ +use multiversx_chain_scenario_format::value_interpreter::interpret_string; + +use crate::ScenarioTxEnvData; + +/// Used when registering a contract for debugging. +/// +/// Any type that implements this trait can be passed to the `register_contract` method, and to its variants. +pub trait RegisterCodeSource { + fn into_code(self, env_data: ScenarioTxEnvData) -> Vec; +} + +impl RegisterCodeSource for &str { + fn into_code(self, env_data: ScenarioTxEnvData) -> Vec { + interpret_string(self, &env_data.interpreter_context()) + } +} + +impl RegisterCodeSource for String { + fn into_code(self, env_data: ScenarioTxEnvData) -> Vec { + self.as_str().into_code(env_data) + } +} + +impl RegisterCodeSource for &String { + fn into_code(self, env_data: ScenarioTxEnvData) -> Vec { + self.as_str().into_code(env_data) + } +} diff --git a/framework/scenario/src/facade/result_handlers.rs b/framework/scenario/src/facade/result_handlers.rs new file mode 100644 index 0000000000..1893647b45 --- /dev/null +++ b/framework/scenario/src/facade/result_handlers.rs @@ -0,0 +1,19 @@ +mod expect_error; +mod expect_message; +mod expect_status; +mod expect_value; +mod returns_message; +mod returns_new_bech32_address; +mod returns_new_token_identifier; +mod returns_status; +mod with_tx_raw_response; + +pub use expect_error::ExpectError; +pub use expect_message::ExpectMessage; +pub use expect_status::ExpectStatus; +pub use expect_value::ExpectValue; +pub use returns_message::ReturnsMessage; +pub use returns_new_bech32_address::ReturnsNewBech32Address; +pub use returns_new_token_identifier::ReturnsNewTokenIdentifier; +pub use returns_status::ReturnsStatus; +pub use with_tx_raw_response::WithRawTxResponse; diff --git a/framework/scenario/src/facade/result_handlers/expect_error.rs b/framework/scenario/src/facade/result_handlers/expect_error.rs new file mode 100644 index 0000000000..a06a227424 --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/expect_error.rs @@ -0,0 +1,33 @@ +use multiversx_chain_scenario_format::serde_raw::ValueSubTree; +use multiversx_sc::types::{RHListItem, RHListItemExec, TxEnv}; + +use crate::scenario_model::{BytesValue, CheckValue, TxExpect, TxResponse}; + +/// Verifies that transaction result error matches the given one. +/// +/// Can only be used in tests and interactors, not available in contracts. +pub struct ExpectError<'a>(pub u64, pub &'a str); + +impl<'a, Env, Original> RHListItem for ExpectError<'a> +where + Env: TxEnv, +{ + type Returns = (); +} + +impl<'a, Env, Original> RHListItemExec for ExpectError<'a> +where + Env: TxEnv, +{ + fn item_tx_expect(&self, mut prev: TxExpect) -> TxExpect { + prev.status = CheckValue::Equal(self.0.into()); + let expect_message_expr = BytesValue { + value: self.1.to_string().into_bytes(), + original: ValueSubTree::Str(format!("str:{}", self.1)), + }; + prev.message = CheckValue::Equal(expect_message_expr); + prev + } + + fn item_process_result(self, _: &TxResponse) -> Self::Returns {} +} diff --git a/framework/scenario/src/facade/result_handlers/expect_message.rs b/framework/scenario/src/facade/result_handlers/expect_message.rs new file mode 100644 index 0000000000..af5fa2a429 --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/expect_message.rs @@ -0,0 +1,36 @@ +use multiversx_chain_scenario_format::serde_raw::ValueSubTree; +use multiversx_sc::types::{RHListItem, RHListItemExec, TxEnv}; + +use crate::scenario_model::{BytesValue, CheckValue, TxExpect, TxResponse, U64Value}; + +/// Verifies that transaction result message matches the given one. +/// +/// Can only be used in tests and interactors, not available in contracts. +pub struct ExpectMessage<'a>(pub &'a str); + +impl<'a, Env, Original> RHListItem for ExpectMessage<'a> +where + Env: TxEnv, +{ + type Returns = (); +} + +impl<'a, Env, Original> RHListItemExec for ExpectMessage<'a> +where + Env: TxEnv, +{ + fn item_tx_expect(&self, mut prev: TxExpect) -> TxExpect { + if prev.status.is_equal_to(U64Value::empty()) { + prev.status = CheckValue::Star; + } + + let expect_message_expr = BytesValue { + value: self.0.to_string().into_bytes(), + original: ValueSubTree::Str(format!("str:{}", self.0)), + }; + prev.message = CheckValue::Equal(expect_message_expr); + prev + } + + fn item_process_result(self, _: &TxResponse) -> Self::Returns {} +} diff --git a/framework/scenario/src/facade/result_handlers/expect_status.rs b/framework/scenario/src/facade/result_handlers/expect_status.rs new file mode 100644 index 0000000000..127982739b --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/expect_status.rs @@ -0,0 +1,27 @@ +use multiversx_sc::types::{RHListItem, RHListItemExec, TxEnv}; + +use crate::scenario_model::{CheckValue, TxExpect, TxResponse}; + +/// Verifies that transaction result status matches the given one. +/// +/// Can only be used in tests and interactors, not available in contracts. +pub struct ExpectStatus(pub u64); + +impl RHListItem for ExpectStatus +where + Env: TxEnv, +{ + type Returns = (); +} + +impl RHListItemExec for ExpectStatus +where + Env: TxEnv, +{ + fn item_tx_expect(&self, mut prev: TxExpect) -> TxExpect { + prev.status = CheckValue::Equal(self.0.into()); + prev + } + + fn item_process_result(self, _: &TxResponse) -> Self::Returns {} +} diff --git a/framework/scenario/src/facade/result_handlers/expect_value.rs b/framework/scenario/src/facade/result_handlers/expect_value.rs new file mode 100644 index 0000000000..582737cb84 --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/expect_value.rs @@ -0,0 +1,41 @@ +use multiversx_sc::{ + abi::TypeAbiFrom, + codec::TopEncodeMulti, + types::{RHListItem, RHListItemExec, TxEnv}, +}; + +use crate::scenario_model::{BytesValue, CheckValue, TxExpect, TxResponse}; + +/// Verifies that transaction result matches the given value. +/// +/// Can only be used in tests and interactors, not available in contracts. +pub struct ExpectValue(pub T); + +impl RHListItem for ExpectValue +where + Env: TxEnv, + T: TopEncodeMulti, + Original: TypeAbiFrom, +{ + type Returns = (); +} + +impl RHListItemExec for ExpectValue +where + Env: TxEnv, + T: TopEncodeMulti, + Original: TypeAbiFrom, +{ + fn item_tx_expect(&self, mut prev: TxExpect) -> TxExpect { + let mut encoded = Vec::>::new(); + self.0.multi_encode(&mut encoded).expect("encoding error"); + let out_values = encoded + .into_iter() + .map(|value| CheckValue::Equal(BytesValue::from(value))) + .collect(); + prev.out = CheckValue::Equal(out_values); + prev + } + + fn item_process_result(self, _: &TxResponse) -> Self::Returns {} +} diff --git a/framework/scenario/src/facade/result_handlers/returns_message.rs b/framework/scenario/src/facade/result_handlers/returns_message.rs new file mode 100644 index 0000000000..64164e05ef --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/returns_message.rs @@ -0,0 +1,29 @@ +use multiversx_sc::types::{RHListItem, RHListItemExec, TxEnv}; + +use crate::scenario_model::{CheckValue, TxExpect, TxResponse}; + +/// Indicates that the error status will be returned. +/// +/// Can only be used in tests and interactors, not available in contracts. +pub struct ReturnsMessage; + +impl RHListItem for ReturnsMessage +where + Env: TxEnv, +{ + type Returns = String; +} + +impl RHListItemExec for ReturnsMessage +where + Env: TxEnv, +{ + fn item_tx_expect(&self, mut prev: TxExpect) -> TxExpect { + prev.message = CheckValue::Star; + prev + } + + fn item_process_result(self, raw_result: &TxResponse) -> Self::Returns { + raw_result.tx_error.message.clone() + } +} diff --git a/framework/scenario/src/facade/result_handlers/returns_new_bech32_address.rs b/framework/scenario/src/facade/result_handlers/returns_new_bech32_address.rs new file mode 100644 index 0000000000..6e898c6088 --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/returns_new_bech32_address.rs @@ -0,0 +1,27 @@ +use multiversx_sc::types::{RHListItem, RHListItemExec, TxEnv}; + +use crate::{facade::expr::Bech32Address, scenario_model::TxResponse}; + +/// Indicates that the newly deployed address will be returned after a deploy. +pub struct ReturnsNewBech32Address; + +impl RHListItem for ReturnsNewBech32Address +where + Env: TxEnv, +{ + type Returns = Bech32Address; +} + +impl RHListItemExec for ReturnsNewBech32Address +where + Env: TxEnv, +{ + fn item_process_result(self, tx_response: &TxResponse) -> Self::Returns { + let new_address = tx_response + .new_deployed_address + .clone() + .expect("missing returned address"); + + new_address.into() + } +} diff --git a/framework/scenario/src/facade/result_handlers/returns_new_token_identifier.rs b/framework/scenario/src/facade/result_handlers/returns_new_token_identifier.rs new file mode 100644 index 0000000000..a459706d22 --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/returns_new_token_identifier.rs @@ -0,0 +1,27 @@ +use multiversx_sc::types::RHListItemExec; + +use crate::{ + multiversx_sc::types::{RHListItem, TxEnv}, + scenario_model::TxResponse, +}; + +pub struct ReturnsNewTokenIdentifier; + +impl RHListItem for ReturnsNewTokenIdentifier +where + Env: TxEnv, +{ + type Returns = String; +} + +impl RHListItemExec for ReturnsNewTokenIdentifier +where + Env: TxEnv, +{ + fn item_process_result(self, raw_result: &TxResponse) -> Self::Returns { + raw_result + .new_issued_token_identifier + .clone() + .expect("missing returned token identifier") + } +} diff --git a/framework/scenario/src/facade/result_handlers/returns_status.rs b/framework/scenario/src/facade/result_handlers/returns_status.rs new file mode 100644 index 0000000000..184163619d --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/returns_status.rs @@ -0,0 +1,36 @@ +use multiversx_sc::types::{RHListItem, RHListItemExec, TxEnv}; + +use crate::scenario_model::{CheckValue, TxExpect, TxResponse, U64Value}; + +/// Indicates that the error status will be returned. +/// +/// Can only be used in tests and interactors, not available in contracts. +pub struct ReturnsStatus; + +impl RHListItem for ReturnsStatus +where + Env: TxEnv, +{ + type Returns = u64; +} + +impl RHListItemExec for ReturnsStatus +where + Env: TxEnv, +{ + fn item_tx_expect(&self, mut prev: TxExpect) -> TxExpect { + if let CheckValue::Equal(U64Value { + value: 0, + original: _, + }) = prev.status + { + prev.status = CheckValue::Star; + } + + prev + } + + fn item_process_result(self, raw_result: &TxResponse) -> Self::Returns { + raw_result.tx_error.status + } +} diff --git a/framework/scenario/src/facade/result_handlers/with_tx_raw_response.rs b/framework/scenario/src/facade/result_handlers/with_tx_raw_response.rs new file mode 100644 index 0000000000..f67d3b0f48 --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/with_tx_raw_response.rs @@ -0,0 +1,30 @@ +use multiversx_sc::{ + codec::TopDecodeMulti, + types::{RHListItem, RHListItemExec, TxEnv}, +}; + +use crate::scenario_model::TxResponse; + +/// Wraps a closure that handles a `TxResponse` object. +pub struct WithRawTxResponse(pub F) +where + F: FnOnce(&TxResponse); + +impl RHListItem for WithRawTxResponse +where + Env: TxEnv, + F: FnOnce(&TxResponse), +{ + type Returns = (); +} + +impl RHListItemExec for WithRawTxResponse +where + Env: TxEnv, + Original: TopDecodeMulti, + F: FnOnce(&TxResponse), +{ + fn item_process_result(self, raw_result: &TxResponse) -> Self::Returns { + (self.0)(raw_result) + } +} diff --git a/framework/scenario/src/facade/scenario_world.rs b/framework/scenario/src/facade/scenario_world.rs index d760c1743a..056cbbe7f7 100644 --- a/framework/scenario/src/facade/scenario_world.rs +++ b/framework/scenario/src/facade/scenario_world.rs @@ -1,20 +1,10 @@ -use multiversx_chain_scenario_format::interpret_trait::InterpretableFrom; use multiversx_chain_vm::world_mock::BlockchainState; -use multiversx_sc_meta::cmd::contract::sc_config::ContractVariant; use crate::{ - api::DebugApi, - debug_executor::ContractContainer, - multiversx_sc::{ - api, - contract_base::{CallableContractBuilder, ContractAbiProvider}, - }, scenario::{run_trace::ScenarioTrace, run_vm::ScenarioVMRunner}, - scenario_format::{interpret_trait::InterpreterContext, value_interpreter::interpret_string}, - scenario_model::BytesValue, vm_go_tool::run_mx_scenario_go, }; -use multiversx_sc_meta::find_workspace::find_current_workspace; +use multiversx_sc_meta_lib::tools::find_current_workspace; use std::path::{Path, PathBuf}; use super::debugger_backend::DebuggerBackend; @@ -113,8 +103,11 @@ impl ScenarioWorld { self } - /// Tells the tests where the crate lies relative to the workspace. - /// This ensures that the paths are set correctly, including in debug mode. + /// Older versions of the Rust compiler were setting a wrong path in the environment when debugging. + /// This method was made as a workaround to avoid this problem. + /// + /// Fortunately, the issue was fixed in Rust, and so this function is no longer necessary. + #[deprecated(since = "0.50.2", note = "No longer needed, simply delete.")] pub fn set_current_dir_from_workspace(&mut self, relative_path: &str) -> &mut Self { let mut path = find_current_workspace().unwrap(); path.push(relative_path); @@ -126,100 +119,6 @@ impl ScenarioWorld { &self.current_dir } - pub fn interpreter_context(&self) -> InterpreterContext { - InterpreterContext::default() - .with_dir(self.current_dir.clone()) - .with_allowed_missing_files() - } - - /// Convenient way of creating a code expression based on the current context - /// (i.e. with the paths resolved, as configured). - pub fn code_expression(&self, path: &str) -> BytesValue { - BytesValue::interpret_from(path, &self.interpreter_context()) - } - - pub fn register_contract_container( - &mut self, - expression: &str, - contract_container: ContractContainer, - ) { - let contract_bytes = interpret_string(expression, &self.interpreter_context()); - self.get_mut_debugger_backend() - .vm_runner - .contract_map_ref - .lock() - .register_contract(contract_bytes, contract_container); - } - - /// Links a contract path in a test to a contract implementation. - pub fn register_contract( - &mut self, - expression: &str, - contract_builder: B, - ) { - self.register_contract_container( - expression, - ContractContainer::new(contract_builder.new_contract_obj::(), None, false), - ) - } - - #[deprecated( - since = "0.37.0", - note = "Got renamed to `register_contract`, but not completely removed, in order to ease test migration. Please replace with `register_contract`." - )] - pub fn register_contract_builder( - &mut self, - expression: &str, - contract_builder: B, - ) { - self.register_contract(expression, contract_builder) - } - - /// Links a contract path in a test to a multi-contract output. - /// - /// This simulates the effects of building such a contract with only part of the endpoints. - pub fn register_partial_contract( - &mut self, - expression: &str, - contract_builder: B, - sub_contract_name: &str, - ) where - Abi: ContractAbiProvider, - B: CallableContractBuilder, - { - let multi_contract_config = - multiversx_sc_meta::multi_contract_config::(self.current_dir.as_path()); - let contract_variant = multi_contract_config.find_contract(sub_contract_name); - self.register_contract_variant(expression, contract_builder, contract_variant); - } - - /// Links a contract path in a test to a multi-contract output. - /// - /// This simulates the effects of building such a contract with only part of the endpoints. - pub fn register_contract_variant( - &mut self, - expression: &str, - contract_builder: B, - contract_variant: &ContractVariant, - ) where - B: CallableContractBuilder, - { - let contract_obj = if contract_variant.settings.external_view { - contract_builder.new_contract_obj::>() - } else { - contract_builder.new_contract_obj::() - }; - - self.register_contract_container( - expression, - ContractContainer::new( - contract_obj, - Some(contract_variant.all_exported_function_names()), - contract_variant.settings.panic_message, - ), - ); - } - /// Exports current scenario to a JSON file, as created. pub fn write_scenario_trace>(&mut self, file_path: P) { if let Some(trace) = &mut self.get_mut_debugger_backend().trace { diff --git a/framework/scenario/src/facade/scenario_world_register.rs b/framework/scenario/src/facade/scenario_world_register.rs new file mode 100644 index 0000000000..1faf45d040 --- /dev/null +++ b/framework/scenario/src/facade/scenario_world_register.rs @@ -0,0 +1,112 @@ +use crate::{ + api::DebugApi, + debug_executor::ContractContainer, + multiversx_sc::{ + api, + contract_base::{CallableContractBuilder, ContractAbiProvider}, + }, + scenario_format::interpret_trait::InterpreterContext, + scenario_model::BytesValue, + ScenarioWorld, +}; +use multiversx_chain_scenario_format::interpret_trait::InterpretableFrom; + +use multiversx_sc_meta_lib::contract::sc_config::ContractVariant; + +use super::expr::RegisterCodeSource; + +impl ScenarioWorld { + pub fn interpreter_context(&self) -> InterpreterContext { + InterpreterContext::default() + .with_dir(self.current_dir.clone()) + .with_allowed_missing_files() + } + + /// Convenient way of creating a code expression based on the current context + /// (i.e. with the paths resolved, as configured). + pub fn code_expression(&self, path: &str) -> BytesValue { + BytesValue::interpret_from(path, &self.interpreter_context()) + } + + pub fn register_contract_container( + &mut self, + expression: impl RegisterCodeSource, + contract_container: ContractContainer, + ) { + let contract_bytes = expression.into_code(self.new_env_data()); + self.get_mut_debugger_backend() + .vm_runner + .contract_map_ref + .lock() + .register_contract(contract_bytes, contract_container); + } + + /// Links a contract path in a test to a contract implementation. + pub fn register_contract( + &mut self, + expression: impl RegisterCodeSource, + contract_builder: B, + ) { + self.register_contract_container( + expression, + ContractContainer::new(contract_builder.new_contract_obj::(), None, false), + ) + } + + #[deprecated( + since = "0.37.0", + note = "Got renamed to `register_contract`, but not completely removed, in order to ease test migration. Please replace with `register_contract`." + )] + pub fn register_contract_builder( + &mut self, + expression: &str, + contract_builder: B, + ) { + self.register_contract(expression, contract_builder) + } + + /// Links a contract path in a test to a multi-contract output. + /// + /// This simulates the effects of building such a contract with only part of the endpoints. + pub fn register_partial_contract( + &mut self, + expression: impl RegisterCodeSource, + contract_builder: B, + sub_contract_name: &str, + ) where + Abi: ContractAbiProvider, + B: CallableContractBuilder, + { + let multi_contract_config = + multiversx_sc_meta_lib::multi_contract_config::(self.current_dir.as_path()); + let contract_variant = multi_contract_config.find_contract(sub_contract_name); + self.register_contract_variant(expression, contract_builder, contract_variant); + } + + /// Links a contract path in a test to a multi-contract output. + /// + /// This simulates the effects of building such a contract with only part of the endpoints. + pub fn register_contract_variant( + &mut self, + expression: impl RegisterCodeSource, + contract_builder: B, + contract_variant: &ContractVariant, + ) where + B: CallableContractBuilder, + { + let contract_obj = if contract_variant.settings.external_view { + contract_builder.new_contract_obj::>() + } else { + contract_builder.new_contract_obj::() + }; + + self.register_contract_container( + expression, + ContractContainer::new( + contract_obj, + Some(contract_variant.all_exported_function_names()), + contract_variant.settings.panic_message, + ), + ); + } +} diff --git a/framework/scenario/src/facade/scenario_world_steps.rs b/framework/scenario/src/facade/scenario_world_steps.rs index 37bc5e88c3..7f786d9e65 100644 --- a/framework/scenario/src/facade/scenario_world_steps.rs +++ b/framework/scenario/src/facade/scenario_world_steps.rs @@ -1,9 +1,15 @@ -use multiversx_sc::types::{heap::Address, ContractCall}; +#![allow(deprecated)] + +use multiversx_sc::{ + abi::TypeAbiFrom, + codec::TopDecodeMulti, + types::{heap::Address, ContractCall}, +}; use crate::{ api::StaticApi, facade::ScenarioWorld, - multiversx_sc::codec::{CodecFrom, TopEncodeMulti}, + multiversx_sc::codec::TopEncodeMulti, scenario::{model::*, ScenarioRunner}, }; @@ -29,6 +35,10 @@ impl ScenarioWorld { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub fn sc_call_use_raw_response(&mut self, mut step: S, use_raw_response: F) -> &mut Self where S: AsMut, @@ -40,6 +50,10 @@ impl ScenarioWorld { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub fn sc_call_use_result( &mut self, step: TypedScCall, @@ -47,7 +61,7 @@ impl ScenarioWorld { ) -> &mut Self where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, F: FnOnce(TypedResponse), { self.sc_call_use_raw_response(step, |response| { @@ -56,13 +70,17 @@ impl ScenarioWorld { }) } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub fn sc_call_get_result( &mut self, mut step: TypedScCall, ) -> RequestedResult where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.run_sc_call_step(&mut step.sc_call_step); let response = unwrap_response(&step.sc_call_step.response); @@ -79,6 +97,10 @@ impl ScenarioWorld { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub fn sc_query_use_raw_response(&mut self, mut step: S, use_raw_response: F) -> &mut Self where S: AsMut, @@ -91,6 +113,10 @@ impl ScenarioWorld { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub fn sc_query_use_result( &mut self, step: TypedScQuery, @@ -98,7 +124,7 @@ impl ScenarioWorld { ) -> &mut Self where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, F: FnOnce(TypedResponse), { self.sc_query_use_raw_response(step, |response| { @@ -107,13 +133,17 @@ impl ScenarioWorld { }) } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub fn sc_query_get_result( &mut self, mut step: TypedScQuery, ) -> RequestedResult where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.run_sc_query_step(&mut step.sc_query_step); let response = unwrap_response(&step.sc_query_step.response); @@ -129,7 +159,7 @@ impl ScenarioWorld { pub fn quick_query(&mut self, contract_call: CC) -> RequestedResult where CC: ContractCall, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.sc_query_get_result(ScQueryStep::new().call(contract_call)) } @@ -143,6 +173,10 @@ impl ScenarioWorld { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub fn sc_deploy_use_raw_response( &mut self, mut step: S, @@ -159,6 +193,10 @@ impl ScenarioWorld { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub fn sc_deploy_use_result( &mut self, step: TypedScDeploy, @@ -166,7 +204,7 @@ impl ScenarioWorld { ) -> &mut Self where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, F: FnOnce(Address, TypedResponse), { self.sc_deploy_use_raw_response(step, |response| { @@ -176,13 +214,17 @@ impl ScenarioWorld { }) } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub fn sc_deploy_get_result( &mut self, mut step: TypedScDeploy, ) -> (Address, RequestedResult) where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.run_sc_deploy_step(&mut step.sc_deploy_step); let response = unwrap_response(&step.sc_deploy_step.response); @@ -223,7 +265,7 @@ impl TypedScCallExecutor for ScenarioWorld { ) -> RequestedResult where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.sc_call_get_result(typed_sc_call) } @@ -236,7 +278,7 @@ impl TypedScDeployExecutor for ScenarioWorld { ) -> (Address, RequestedResult) where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.sc_deploy_get_result(typed_sc_call) } @@ -254,7 +296,7 @@ impl TypedScQueryExecutor for ScenarioWorld { ) -> RequestedResult where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.sc_query_get_result(typed_sc_query) } diff --git a/framework/scenario/src/facade/world_tx.rs b/framework/scenario/src/facade/world_tx.rs new file mode 100644 index 0000000000..a2d7373a42 --- /dev/null +++ b/framework/scenario/src/facade/world_tx.rs @@ -0,0 +1,11 @@ +mod scenario_check_state; +mod scenario_exec_call; +mod scenario_exec_deploy; +mod scenario_query_call; +mod scenario_rh_impl; +mod scenario_set_state; +mod scenario_tx_env; + +pub use scenario_exec_call::ScenarioEnvExec; +pub use scenario_query_call::ScenarioEnvQuery; +pub use scenario_tx_env::{ScenarioTxEnv, ScenarioTxEnvData, ScenarioTxRun}; diff --git a/framework/scenario/src/facade/world_tx/scenario_check_state.rs b/framework/scenario/src/facade/world_tx/scenario_check_state.rs new file mode 100644 index 0000000000..3f5423419a --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_check_state.rs @@ -0,0 +1,237 @@ +use std::collections::{btree_map::Entry, BTreeMap}; + +use multiversx_chain_scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext}; +use multiversx_sc::{ + codec::{top_encode_to_vec_u8, TopEncode}, + types::{AnnotatedValue, BigUint, ManagedAddress, ManagedBuffer, TokenIdentifier}, +}; + +use crate::{ + api::StaticApi, + scenario::{ + tx_to_step::{ + address_annotated, big_uint_annotated, bytes_annotated, token_identifier_annotated, + u64_annotated, + }, + ScenarioRunner, + }, + scenario_model::{ + AddressKey, BytesKey, BytesValue, CheckAccount, CheckEsdt, CheckEsdtData, + CheckEsdtInstances, CheckEsdtMap, CheckEsdtMapContents, CheckStateStep, CheckStorage, + CheckStorageDetails, CheckValue, + }, + ScenarioTxEnvData, ScenarioWorld, +}; + +impl ScenarioWorld { + pub fn check_account(&mut self, address: A) -> CheckStateBuilder<'_> + where + A: AnnotatedValue>, + { + let address_value = address_annotated(&self.new_env_data(), &address); + CheckStateBuilder::new(self, address_value.into()) + } +} + +pub struct CheckStateBuilder<'w> { + world: &'w mut ScenarioWorld, + check_state_step: CheckStateStep, + current_account: CheckAccount, + current_address: AddressKey, +} + +impl<'w> CheckStateBuilder<'w> { + pub(crate) fn new(world: &'w mut ScenarioWorld, address: AddressKey) -> CheckStateBuilder<'w> { + let mut builder = CheckStateBuilder { + world, + check_state_step: CheckStateStep::new(), + current_account: CheckAccount::new(), + current_address: AddressKey::default(), + }; + builder.reset_account(address); + builder + } + + fn new_env_data(&self) -> ScenarioTxEnvData { + self.world.new_env_data() + } + + /// Starts building of a new account. + pub fn check_account(mut self, address: A) -> Self + where + A: AnnotatedValue>, + { + self.add_current_acount(); + let env = self.new_env_data(); + let address_value = address_annotated(&env, &address); + self.reset_account(address_value.into()); + self + } + + fn add_current_acount(&mut self) { + if let Entry::Vacant(entry) = self + .check_state_step + .accounts + .accounts + .entry(core::mem::take(&mut self.current_address)) + { + entry.insert(core::mem::take(&mut self.current_account)); + }; + } + + fn reset_account(&mut self, address: AddressKey) { + self.current_address = address; + self.current_account = CheckAccount::default(); + } + + /// Finished and sets all account in the blockchain mock. + fn commit_accounts(&mut self) { + self.add_current_acount(); + self.world.run_check_state_step(&self.check_state_step); + } + + /// Forces value drop and commit accounts. + pub fn commit(self) {} + + pub fn nonce(mut self, nonce: V) -> Self + where + V: AnnotatedValue, + { + let env = self.new_env_data(); + self.current_account.nonce = CheckValue::Equal(u64_annotated(&env, &nonce)); + self + } + + pub fn balance(mut self, balance: V) -> Self + where + V: AnnotatedValue>, + { + let env = self.new_env_data(); + self.current_account.balance = CheckValue::Equal(big_uint_annotated(&env, &balance)); + self + } + + pub fn code(mut self, code: V) -> Self + where + V: AnnotatedValue>, + { + let env = self.new_env_data(); + let code_value = bytes_annotated(&env, code); + + self.current_account.code = CheckValue::Equal(code_value); + self + } + + pub fn code_metadata(mut self, code_metadata_expr: V) -> Self + where + BytesValue: InterpretableFrom, + { + self.current_account.code_metadata = CheckValue::Equal(BytesValue::interpret_from( + code_metadata_expr, + &InterpreterContext::default(), + )); + self + } + + pub fn esdt_balance(mut self, token_id: K, balance: V) -> Self + where + K: AnnotatedValue>, + V: AnnotatedValue>, + { + let env = self.new_env_data(); + let token_id_key = token_identifier_annotated(&env, token_id); + let balance_value = big_uint_annotated(&env, &balance); + + match &mut self.current_account.esdt { + CheckEsdtMap::Unspecified | CheckEsdtMap::Star => { + let mut new_esdt_map = BTreeMap::new(); + let _ = new_esdt_map.insert(token_id_key, CheckEsdt::Short(balance_value)); + + let new_check_esdt_map = CheckEsdtMapContents { + contents: new_esdt_map, + other_esdts_allowed: true, + }; + + self.current_account.esdt = CheckEsdtMap::Equal(new_check_esdt_map); + }, + CheckEsdtMap::Equal(check_esdt_map) => { + if check_esdt_map.contents.contains_key(&token_id_key) { + let prev_entry = check_esdt_map.contents.get_mut(&token_id_key).unwrap(); + match prev_entry { + CheckEsdt::Short(prev_balance_check) => *prev_balance_check = balance_value, + CheckEsdt::Full(prev_esdt_check) => match prev_esdt_check.instances { + CheckEsdtInstances::Star => todo!(), + CheckEsdtInstances::Equal(_) => todo!(), + }, + } + } + }, + } + + self + } + + pub fn esdt_nft_balance_and_attributes( + mut self, + token_id: K, + nonce: N, + balance: V, + attributes: T, + ) -> Self + where + K: AnnotatedValue>, + N: AnnotatedValue, + V: AnnotatedValue>, + T: TopEncode, + { + let env = self.new_env_data(); + let token_id_key = token_identifier_annotated(&env, token_id); + let nonce_value = u64_annotated(&env, &nonce); + let balance_value = big_uint_annotated(&env, &balance); + let attributes_value = top_encode_to_vec_u8(&attributes).unwrap(); + + if let CheckEsdtMap::Unspecified = &self.current_account.esdt { + let mut check_esdt = CheckEsdt::Full(CheckEsdtData::default()); + + check_esdt.add_balance_and_attributes_check( + nonce_value, + balance_value, + attributes_value, + ); + + let mut new_esdt_map = BTreeMap::new(); + let _ = new_esdt_map.insert(token_id_key, check_esdt); + + let new_check_esdt_map = CheckEsdtMapContents { + contents: new_esdt_map, + other_esdts_allowed: true, + }; + + self.current_account.esdt = CheckEsdtMap::Equal(new_check_esdt_map); + } + + self + } + + pub fn check_storage(mut self, key: &str, value: &str) -> Self { + let mut details = match &self.current_account.storage { + CheckStorage::Star => CheckStorageDetails::default(), + CheckStorage::Equal(details) => details.clone(), + }; + details.storages.insert( + BytesKey::interpret_from(key, &InterpreterContext::default()), + CheckValue::Equal(BytesValue::interpret_from( + value, + &InterpreterContext::default(), + )), + ); + self.current_account.storage = CheckStorage::Equal(details); + self + } +} + +impl<'w> Drop for CheckStateBuilder<'w> { + fn drop(&mut self) { + self.commit_accounts(); + } +} diff --git a/framework/scenario/src/facade/world_tx/scenario_exec_call.rs b/framework/scenario/src/facade/world_tx/scenario_exec_call.rs new file mode 100644 index 0000000000..8905c7d14d --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_exec_call.rs @@ -0,0 +1,154 @@ +use multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{ + heap::H256, Code, FunctionCall, ManagedAddress, ManagedBuffer, NotPayable, RHListExec, Tx, + TxBaseWithEnv, TxEnv, TxEnvMockDeployAddress, TxEnvWithTxHash, TxFromSpecified, TxGas, + TxPayment, TxToSpecified, UpgradeCall, + }, +}; + +use crate::{ + api::StaticApi, + imports::MxscPath, + scenario::tx_to_step::{address_annotated, TxToStep}, + scenario_model::{SetStateStep, TxExpect, TxResponse}, + ScenarioTxEnv, ScenarioTxRun, ScenarioWorld, +}; + +use super::ScenarioTxEnvData; + +/// Environment for executing transactions. +pub struct ScenarioEnvExec<'w> { + pub world: &'w mut ScenarioWorld, + pub data: ScenarioTxEnvData, +} + +impl<'w> TxEnv for ScenarioEnvExec<'w> { + type Api = StaticApi; + + type RHExpect = TxExpect; + + fn resolve_sender_address(&self) -> ManagedAddress { + panic!("Explicit sender address expected") + } + + fn default_gas_annotation(&self) -> ManagedBuffer { + self.data.default_gas_annotation() + } + + fn default_gas_value(&self) -> u64 { + self.data.default_gas_value() + } +} + +impl<'w> TxEnvMockDeployAddress for ScenarioEnvExec<'w> { + fn mock_deploy_new_address(&mut self, from: &From, new_address: NA) + where + From: TxFromSpecified, + NA: multiversx_sc::types::AnnotatedValue>, + { + let from_value = address_annotated(self, from); + let sender_nonce = self + .world + .get_state() + .accounts + .get(&from_value.to_vm_address()) + .expect("sender does not exist") + .nonce; + let new_address_value = address_annotated(self, &new_address); + + self.world.set_state_step(SetStateStep::new().new_address( + from_value, + sender_nonce, + new_address_value, + )); + } +} + +impl<'w> ScenarioTxEnv for ScenarioEnvExec<'w> { + fn env_data(&self) -> &ScenarioTxEnvData { + &self.data + } +} + +impl<'w, From, To, Payment, Gas, RH> ScenarioTxRun + for Tx, From, To, Payment, Gas, FunctionCall, RH> +where + From: TxFromSpecified>, + To: TxToSpecified>, + Payment: TxPayment>, + Gas: TxGas>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + fn run(self) -> Self::Returns { + let mut step_wrapper = self.tx_to_step(); + step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); + step_wrapper.env.world.sc_call(&mut step_wrapper.step); + step_wrapper.process_result() + } +} + +impl<'w, From, To, RH> ScenarioTxRun + for Tx< + ScenarioEnvExec<'w>, + From, + To, + NotPayable, + (), + UpgradeCall, Code>>, + RH, + > +where + From: TxFromSpecified>, + To: TxToSpecified>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + fn run(self) -> Self::Returns { + let mut step_wrapper = self.tx_to_step(); + step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); + step_wrapper.env.world.sc_call(&mut step_wrapper.step); + step_wrapper.process_result() + } +} + +impl<'w> TxEnvWithTxHash for ScenarioEnvExec<'w> { + fn set_tx_hash(&mut self, tx_hash: H256) { + assert!(self.data.tx_hash.is_none(), "tx hash set twice"); + self.data.tx_hash = Some(tx_hash); + } +} + +impl ScenarioWorld { + pub fn tx(&mut self) -> TxBaseWithEnv> { + let data = self.new_env_data(); + let env = ScenarioEnvExec { world: self, data }; + Tx::new_with_env(env) + } + + pub fn chain_call(&mut self, f: F) -> &mut Self + where + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, + RH: RHListExec, + F: FnOnce( + TxBaseWithEnv, + ) + -> Tx, RH>, + { + let env = self.new_env_data(); + let tx_base = TxBaseWithEnv::new_with_env(env); + let tx = f(tx_base); + let mut step_wrapper = tx.tx_to_step(); + self.sc_call(&mut step_wrapper.step); + step_wrapper.process_result(); + self + } +} diff --git a/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs b/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs new file mode 100644 index 0000000000..40fbbaa878 --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs @@ -0,0 +1,74 @@ +use multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{ + Code, DeployCall, RHListExec, Tx, TxBaseWithEnv, TxCodeValue, TxFromSpecified, TxGas, + TxPayment, + }, +}; + +use crate::{ + scenario::tx_to_step::TxToStep, scenario_model::TxResponse, ScenarioEnvExec, ScenarioTxRun, + ScenarioWorld, +}; + +use super::ScenarioTxEnvData; + +impl<'w, From, Payment, Gas, CodeValue, RH> ScenarioTxRun + for Tx< + ScenarioEnvExec<'w>, + From, + (), + Payment, + Gas, + DeployCall, Code>, + RH, + > +where + From: TxFromSpecified>, + Payment: TxPayment>, + Gas: TxGas>, + CodeValue: TxCodeValue>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + fn run(self) -> Self::Returns { + let mut step_wrapper = self.tx_to_step(); + step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); + step_wrapper.env.world.sc_deploy(&mut step_wrapper.step); + step_wrapper.process_result() + } +} + +impl ScenarioWorld { + pub fn chain_deploy(&mut self, f: F) -> &mut Self + where + From: TxFromSpecified, + Payment: TxPayment, + Gas: TxGas, + CodeValue: TxCodeValue, + RH: RHListExec, + F: FnOnce( + TxBaseWithEnv, + ) -> Tx< + ScenarioTxEnvData, + From, + (), + Payment, + Gas, + DeployCall>, + RH, + >, + { + let env = self.new_env_data(); + let tx_base = TxBaseWithEnv::new_with_env(env); + let tx = f(tx_base); + + let mut step_wrapper = tx.tx_to_step(); + self.sc_deploy(&mut step_wrapper.step); + step_wrapper.process_result(); + + self + } +} diff --git a/framework/scenario/src/facade/world_tx/scenario_query_call.rs b/framework/scenario/src/facade/world_tx/scenario_query_call.rs new file mode 100644 index 0000000000..dc416439b4 --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_query_call.rs @@ -0,0 +1,87 @@ +use multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{ + FunctionCall, ManagedAddress, ManagedBuffer, RHListExec, Tx, TxBaseWithEnv, TxEnv, + TxNoPayment, TxToSpecified, + }, +}; + +use crate::{ + api::StaticApi, + scenario::tx_to_step::TxToQueryStep, + scenario_model::{TxExpect, TxResponse}, + ScenarioTxEnv, ScenarioTxEnvData, ScenarioTxRun, ScenarioWorld, +}; + +pub struct ScenarioEnvQuery<'w> { + pub world: &'w mut ScenarioWorld, + pub data: ScenarioTxEnvData, +} + +impl<'w> TxEnv for ScenarioEnvQuery<'w> { + type Api = StaticApi; + + type RHExpect = TxExpect; + + fn resolve_sender_address(&self) -> ManagedAddress { + panic!("Explicit sender address expected") + } + + fn default_gas_annotation(&self) -> ManagedBuffer { + self.data.default_gas_annotation() + } + + fn default_gas_value(&self) -> u64 { + self.data.default_gas_value() + } +} + +impl<'w> ScenarioTxEnv for ScenarioEnvQuery<'w> { + fn env_data(&self) -> &ScenarioTxEnvData { + &self.data + } +} + +impl<'w, To, Payment, RH> ScenarioTxRun + for Tx, (), To, Payment, (), FunctionCall, RH> +where + To: TxToSpecified>, + Payment: TxNoPayment>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + fn run(self) -> Self::Returns { + let mut step_wrapper = self.tx_to_query_step(); + step_wrapper.env.world.sc_query(&mut step_wrapper.step); + step_wrapper.process_result() + } +} + +impl ScenarioWorld { + pub fn query(&mut self) -> TxBaseWithEnv> { + let data = self.new_env_data(); + let env = ScenarioEnvQuery { world: self, data }; + Tx::new_with_env(env) + } + + pub fn chain_query(&mut self, f: F) -> &mut Self + where + To: TxToSpecified, + Payment: TxNoPayment, + RH: RHListExec, + F: FnOnce( + TxBaseWithEnv, + ) + -> Tx, RH>, + { + let env = self.new_env_data(); + let tx_base = TxBaseWithEnv::new_with_env(env); + let tx = f(tx_base); + let mut step_wrapper = tx.tx_to_query_step(); + self.sc_query(&mut step_wrapper.step); + step_wrapper.process_result(); + self + } +} diff --git a/framework/scenario/src/facade/world_tx/scenario_rh_impl.rs b/framework/scenario/src/facade/world_tx/scenario_rh_impl.rs new file mode 100644 index 0000000000..9d16b1b709 --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_rh_impl.rs @@ -0,0 +1,116 @@ +use multiversx_sc::{ + abi::{TypeAbi, TypeAbiFrom}, + codec::TopDecodeMulti, + types::{ + ManagedAddress, RHListItemExec, ReturnsNewAddress, ReturnsNewManagedAddress, + ReturnsRawResult, ReturnsResult, ReturnsResultAs, ReturnsResultUnmanaged, TxEnv, + WithNewAddress, WithResultAs, + }, +}; + +use crate::scenario_model::{TxResponse, TypedResponse}; + +impl RHListItemExec for ReturnsResult +where + Env: TxEnv, + Original: TopDecodeMulti, +{ + fn item_process_result(self, tx_response: &TxResponse) -> Self::Returns { + let response = TypedResponse::::from_raw(tx_response); + response + .result + .expect("ReturnsResult expects that transaction is successful") + } +} + +impl RHListItemExec for ReturnsResultAs +where + Env: TxEnv, + T: TopDecodeMulti + TypeAbiFrom, +{ + fn item_process_result(self, tx_response: &TxResponse) -> Self::Returns { + let response = TypedResponse::::from_raw(tx_response); + response + .result + .expect("ReturnsResultAs expects that transaction is successful") + } +} + +impl RHListItemExec for ReturnsResultUnmanaged +where + Env: TxEnv, + Original: TypeAbi, + Original::Unmanaged: TopDecodeMulti, +{ + fn item_process_result(self, tx_response: &TxResponse) -> Self::Returns { + let response = TypedResponse::::from_raw(tx_response); + response + .result + .expect("ReturnsResultUnmanaged expects that transaction is successful") + } +} + +impl RHListItemExec for WithResultAs +where + Env: TxEnv, + T: TopDecodeMulti + TypeAbiFrom, + F: FnOnce(T), +{ + fn item_process_result(self, tx_response: &TxResponse) -> Self::Returns { + let response = TypedResponse::::from_raw(tx_response); + let value = response + .result + .expect("ReturnsResult expects that transaction is successful"); + (self.f)(value); + } +} + +impl RHListItemExec for ReturnsNewAddress +where + Env: TxEnv, +{ + fn item_process_result(self, tx_response: &TxResponse) -> Self::Returns { + tx_response + .new_deployed_address + .clone() + .expect("missing returned address") + } +} + +impl RHListItemExec for ReturnsRawResult +where + Env: TxEnv, +{ + fn item_process_result(self, tx_response: &TxResponse) -> Self::Returns { + tx_response.out.clone().into() + } +} + +impl RHListItemExec for ReturnsNewManagedAddress +where + Env: TxEnv, +{ + fn item_process_result(self, tx_response: &TxResponse) -> Self::Returns { + let new_address = tx_response + .new_deployed_address + .clone() + .expect("missing returned address"); + + new_address.into() + } +} + +impl RHListItemExec for WithNewAddress +where + Env: TxEnv, + F: FnOnce(&ManagedAddress), +{ + fn item_process_result(self, tx_response: &TxResponse) -> Self::Returns { + let new_address = tx_response + .new_deployed_address + .clone() + .expect("missing returned address"); + + (self.f)(&ManagedAddress::from_address(&new_address)); + } +} diff --git a/framework/scenario/src/facade/world_tx/scenario_set_state.rs b/framework/scenario/src/facade/world_tx/scenario_set_state.rs new file mode 100644 index 0000000000..d036d647cd --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_set_state.rs @@ -0,0 +1,326 @@ +mod scenario_set_account; +mod scenario_set_block; +mod scenario_set_new_address; + +use crate::{ + imports::StaticApi, + scenario::{ + tx_to_step::{address_annotated, big_uint_annotated, u64_annotated}, + ScenarioRunner, + }, + scenario_model::{AddressKey, BigUintValue, NewAddress, SetStateStep}, + ScenarioTxEnvData, ScenarioWorld, +}; + +use multiversx_chain_vm::world_mock::EsdtInstanceMetadata; +use multiversx_sc::{ + proxy_imports::TopEncode, + types::{AnnotatedValue, BigUint, EsdtLocalRole, ManagedAddress}, +}; +use scenario_set_account::AccountItem; +use scenario_set_block::BlockItem; +use scenario_set_new_address::NewAddressItem; + +impl ScenarioWorld { + fn empty_builder(&mut self) -> SetStateBuilder<'_, ()> { + SetStateBuilder { + base: Some(SetStateBuilderBase::new(self)), + item: (), + } + } + + pub fn account(&mut self, address_expr: A) -> SetStateBuilder<'_, AccountItem> + where + A: AnnotatedValue>, + { + self.empty_builder().account(address_expr) + } + + pub fn new_address( + &mut self, + creator_address_expr: CA, + creator_nonce_expr: CN, + new_address_expr: NA, + ) -> SetStateBuilder<'_, NewAddressItem> + where + CA: AnnotatedValue>, + CN: AnnotatedValue, + NA: AnnotatedValue>, + { + self.empty_builder() + .new_address(creator_address_expr, creator_nonce_expr, new_address_expr) + } + + pub fn create_account_raw( + &mut self, + address: A, + egld_balance: V, + ) -> SetStateBuilder<'_, AccountItem> + where + A: AnnotatedValue>, + V: AnnotatedValue>, + { + self.empty_builder().account(address).balance(egld_balance) + } + + pub fn set_egld_balance(&mut self, address: A, balance: V) + where + A: AnnotatedValue>, + V: AnnotatedValue>, + { + let env = self.new_env_data(); + let address_value = address_annotated(&env, &address); + let balance_value = big_uint_annotated(&env, &balance); + let accounts = &mut self.get_mut_state().accounts; + for (vm_address_key, account) in accounts.iter_mut() { + if vm_address_key == &address_value.to_vm_address() { + account.egld_balance.clone_from(&balance_value.value); + } + } + } + + pub fn set_esdt_balance(&mut self, address: A, token_id: &[u8], balance: V) + where + A: AnnotatedValue>, + V: AnnotatedValue>, + { + let env = self.new_env_data(); + let address_value = address_annotated(&env, &address); + let balance_value = big_uint_annotated(&env, &balance); + let accounts = &mut self.get_mut_state().accounts; + for (vm_address, account) in accounts.iter_mut() { + if vm_address == &address_value.to_vm_address() { + account.esdt.set_esdt_balance( + token_id.to_vec(), + 0, + &balance_value.value, + EsdtInstanceMetadata::default(), + ) + } + } + } + + #[allow(clippy::too_many_arguments)] + pub fn set_nft_balance_all_properties( + &mut self, + address: A, + token_id: &[u8], + nonce: N, + balance: B, + attributes: T, + royalties: R, + creator: Option, + name: Option<&[u8]>, + hash: Option<&[u8]>, + uris: &[Vec], + ) where + A: AnnotatedValue>, + B: AnnotatedValue>, + N: AnnotatedValue, + R: AnnotatedValue, + C: AnnotatedValue>, + { + let env = self.new_env_data(); + let address_value = address_annotated(&env, &address); + let balance_value = big_uint_annotated(&env, &balance); + let nonce_value = u64_annotated(&env, &nonce); + let royalties_value = u64_annotated(&env, &royalties); + + let mut esdt_attributes = Vec::new(); + let _ = attributes.top_encode(&mut esdt_attributes); + let accounts = &mut self.get_mut_state().accounts; + for (vm_address, account) in accounts.iter_mut() { + if vm_address == &address_value.to_vm_address() { + account.esdt.set_esdt_balance( + token_id.to_vec(), + nonce_value.value, + &balance_value.value, + EsdtInstanceMetadata { + creator: creator + .as_ref() + .map(|c| address_annotated(&env, c).to_vm_address()), + attributes: esdt_attributes.clone(), + royalties: royalties_value.value, + name: name.unwrap_or_default().to_vec(), + hash: hash.map(|h| h.to_vec()), + uri: uris.to_vec(), + }, + ) + } + } + } + + pub fn set_developer_rewards(&mut self, address: A, developer_rewards: V) + where + AddressKey: From, + BigUintValue: From, + { + let accounts = &mut self.get_mut_state().accounts; + for (vm_address, account) in accounts.iter_mut() { + if vm_address == &AddressKey::from(address).to_vm_address() { + account + .developer_rewards + .clone_from(&BigUintValue::from(developer_rewards).value); + } + } + } + + pub fn set_esdt_local_roles(&mut self, address: A, token_id: &[u8], roles: &[EsdtLocalRole]) + where + A: AnnotatedValue>, + { + let env = self.new_env_data(); + let address_value = address_annotated(&env, &address); + let accounts = &mut self.get_mut_state().accounts; + for (vm_address, account) in accounts.iter_mut() { + if vm_address == &address_value.to_vm_address() { + account.esdt.set_roles( + token_id.to_vec(), + roles + .iter() + .map(|role| role.as_role_name().to_vec()) + .collect(), + ); + } + } + } + + pub fn current_block(&mut self) -> SetStateBuilder<'_, BlockItem> { + self.empty_builder().current_block() + } + + pub fn previous_block(&mut self) -> SetStateBuilder<'_, BlockItem> { + self.empty_builder().previous_block() + } +} + +pub trait SetStateBuilderItem { + fn commit_to_step(&mut self, step: &mut SetStateStep); +} + +impl SetStateBuilderItem for () { + fn commit_to_step(&mut self, _step: &mut SetStateStep) {} +} + +struct SetStateBuilderBase<'w> { + world: &'w mut ScenarioWorld, + set_state_step: SetStateStep, +} + +pub struct SetStateBuilder<'w, Current> +where + Current: SetStateBuilderItem, +{ + base: Option>, + item: Current, +} + +impl<'w> SetStateBuilderBase<'w> { + fn new(world: &'w mut ScenarioWorld) -> Self { + SetStateBuilderBase { + world, + set_state_step: SetStateStep::new(), + } + } + + fn start_account(&self, address: AddressKey) -> AccountItem { + assert!( + !self + .world + .get_debugger_backend() + .vm_runner + .blockchain_mock + .state + .account_exists(&address.to_vm_address()), + "updating existing accounts currently not supported" + ); + + AccountItem::new(address) + } +} + +impl<'w> SetStateBuilder<'w, ()> {} + +impl<'w, Item> SetStateBuilder<'w, Item> +where + Item: SetStateBuilderItem, +{ + fn new_env_data(&self) -> ScenarioTxEnvData { + self.base.as_ref().unwrap().world.new_env_data() + } + + /// Starts building of a new account. + pub fn account(mut self, address_expr: A) -> SetStateBuilder<'w, AccountItem> + where + A: AnnotatedValue>, + { + let mut base = core::mem::take(&mut self.base).unwrap(); + let env = base.world.new_env_data(); + let address_value = address_annotated(&env, &address_expr); + self.item.commit_to_step(&mut base.set_state_step); + let item = base.start_account(address_value.into()); + SetStateBuilder { + base: Some(base), + item, + } + } + + pub fn new_address( + mut self, + creator_address_expr: CA, + creator_nonce_expr: CN, + new_address_expr: NA, + ) -> SetStateBuilder<'w, NewAddressItem> + where + CA: AnnotatedValue>, + CN: AnnotatedValue, + NA: AnnotatedValue>, + { + let mut base = core::mem::take(&mut self.base).unwrap(); + self.item.commit_to_step(&mut base.set_state_step); + let env = base.world.new_env_data(); + SetStateBuilder { + base: Some(base), + item: NewAddressItem { + new_address: NewAddress { + creator_address: address_annotated(&env, &creator_address_expr), + creator_nonce: u64_annotated(&env, &creator_nonce_expr), + new_address: address_annotated(&env, &new_address_expr), + }, + }, + } + } + + pub fn current_block(&mut self) -> SetStateBuilder<'w, BlockItem> { + let mut base = core::mem::take(&mut self.base).unwrap(); + self.item.commit_to_step(&mut base.set_state_step); + SetStateBuilder { + base: Some(base), + item: BlockItem::new_current(), + } + } + + pub fn previous_block(&mut self) -> SetStateBuilder<'w, BlockItem> { + let mut base = core::mem::take(&mut self.base).unwrap(); + self.item.commit_to_step(&mut base.set_state_step); + SetStateBuilder { + base: Some(base), + item: BlockItem::new_prev(), + } + } + + /// Forces value drop and commit accounts. + pub fn commit(self) {} +} + +impl<'w, Current> Drop for SetStateBuilder<'w, Current> +where + Current: SetStateBuilderItem, +{ + fn drop(&mut self) { + if let Some(base) = &mut self.base { + self.item.commit_to_step(&mut base.set_state_step); + base.world.run_set_state_step(&base.set_state_step); + } + } +} diff --git a/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_account.rs b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_account.rs new file mode 100644 index 0000000000..f5590894e1 --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_account.rs @@ -0,0 +1,220 @@ +use std::collections::btree_map::Entry; + +use multiversx_sc::types::{ + AnnotatedValue, BigUint, ManagedAddress, ManagedBuffer, TokenIdentifier, +}; + +use crate::{ + imports::StaticApi, + scenario::tx_to_step::{ + address_annotated, big_uint_annotated, bytes_annotated, token_identifier_annotated, + u64_annotated, + }, + scenario_model::{Account, AddressKey, BytesKey, Esdt, EsdtObject, SetStateStep}, + ScenarioTxEnvData, +}; + +use super::{SetStateBuilder, SetStateBuilderItem}; + +pub struct AccountItem { + address: AddressKey, + account: Account, +} + +impl AccountItem { + pub fn new(address: AddressKey) -> Self { + AccountItem { + address, + account: Account::default(), + } + } +} + +impl SetStateBuilderItem for AccountItem { + fn commit_to_step(&mut self, step: &mut SetStateStep) { + if let Entry::Vacant(entry) = step.accounts.entry(core::mem::take(&mut self.address)) { + entry.insert(core::mem::take(&mut self.account)); + }; + } +} + +impl<'w> SetStateBuilder<'w, AccountItem> { + pub fn nonce(mut self, nonce: N) -> Self + where + N: AnnotatedValue, + { + let env = self.new_env_data(); + self.item.account.nonce = Some(u64_annotated(&env, &nonce)); + self + } + + pub fn balance(mut self, balance: V) -> Self + where + V: AnnotatedValue>, + { + let env = self.new_env_data(); + self.item.account.balance = Some(big_uint_annotated(&env, &balance)); + self + } + + pub fn esdt_balance(mut self, token_id: K, balance: V) -> Self + where + K: AnnotatedValue>, + V: AnnotatedValue>, + { + let env = self.new_env_data(); + let token_id_key = token_identifier_annotated(&env, token_id); + let balance_value = big_uint_annotated(&env, &balance); + + let esdt_data_ref = self.get_esdt_data_or_create(&token_id_key); + esdt_data_ref.set_balance(0u64, balance_value); + + self + } + + pub fn esdt_nft_balance( + mut self, + token_id: K, + nonce: N, + balance: V, + attributes: T, + ) -> Self + where + K: AnnotatedValue>, + N: AnnotatedValue, + V: AnnotatedValue>, + T: AnnotatedValue>, + { + let env = self.new_env_data(); + let token_id_key = token_identifier_annotated(&env, token_id); + let nonce_value = u64_annotated(&env, &nonce); + let balance_value = big_uint_annotated(&env, &balance); + let attributes_value = bytes_annotated(&env, attributes); + + let esdt_obj_ref = self + .get_esdt_data_or_create(&token_id_key) + .get_mut_esdt_object(); + esdt_obj_ref.set_balance(nonce_value.clone(), balance_value); + + esdt_obj_ref.set_token_attributes(nonce_value, attributes_value); + + self + } + + #[allow(clippy::too_many_arguments)] + pub fn esdt_nft_all_properties( + mut self, + token_id: K, + nonce: N, + balance: V, + attributes: T, + royalties: R, + creator: Option, + hash: H, + uris: Vec, + ) -> Self + where + K: AnnotatedValue>, + N: AnnotatedValue, + V: AnnotatedValue>, + T: AnnotatedValue>, + C: AnnotatedValue>, + R: AnnotatedValue, + H: AnnotatedValue>, + U: AnnotatedValue>, + { + let env = self.new_env_data(); + let token_id_key = token_identifier_annotated(&env, token_id); + let nonce_value = u64_annotated(&env, &nonce); + let royalties_value = u64_annotated(&env, &royalties); + let balance_value = big_uint_annotated(&env, &balance); + let attributes_value = bytes_annotated(&env, attributes); + let creator_value = creator.as_ref().map(|c| address_annotated(&env, c)); + let hash_value = bytes_annotated(&env, hash); + let mut uris_value = Vec::new(); + for uri in uris { + let uri_value = bytes_annotated(&env, uri); + uris_value.push(uri_value); + } + + let esdt_obj_ref = self + .get_esdt_data_or_create(&token_id_key) + .get_mut_esdt_object(); + + esdt_obj_ref.set_token_all_properties( + nonce_value, + balance_value, + Some(attributes_value), + royalties_value, + creator_value, + Some(hash_value), + uris_value, + ); + + self + } + + pub fn esdt_nft_last_nonce(mut self, token_id: K, last_nonce: N) -> Self + where + K: AnnotatedValue>, + N: AnnotatedValue, + { + let env = self.new_env_data(); + let token_id_key = token_identifier_annotated(&env, token_id); + let nonce_value = u64_annotated(&env, &last_nonce); + + let esdt_obj_ref = self + .get_esdt_data_or_create(&token_id_key) + .get_mut_esdt_object(); + esdt_obj_ref.set_last_nonce(nonce_value); + + self + } + + // TODO: Find a better way to pass roles + pub fn esdt_roles(mut self, token_id: K, roles: Vec) -> Self + where + K: AnnotatedValue>, + { + let env = self.new_env_data(); + let token_id_key = token_identifier_annotated(&env, token_id); + + let esdt_obj_ref = self + .get_esdt_data_or_create(&token_id_key) + .get_mut_esdt_object(); + esdt_obj_ref.set_roles(roles); + + self + } + + fn get_esdt_data_or_create(&mut self, token_id: &BytesKey) -> &mut Esdt { + if !self.item.account.esdt.contains_key(token_id) { + self.item + .account + .esdt + .insert(token_id.clone(), Esdt::Full(EsdtObject::default())); + } + + self.item.account.esdt.get_mut(token_id).unwrap() + } + + pub fn code(mut self, code: C) -> Self + where + C: AnnotatedValue>, + { + let env = self.new_env_data(); + let code_value = bytes_annotated(&env, code); + self.item.account.code = Some(code_value); + self + } + + pub fn owner(mut self, owner: V) -> Self + where + V: AnnotatedValue>, + { + let env = self.new_env_data(); + let owner_value = address_annotated(&env, &owner); + self.item.account.owner = Some(owner_value); + self + } +} diff --git a/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_block.rs b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_block.rs new file mode 100644 index 0000000000..3ef0d06cca --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_block.rs @@ -0,0 +1,107 @@ +use multiversx_sc::types::{AnnotatedValue, ManagedBuffer}; + +use crate::{ + imports::StaticApi, + scenario::tx_to_step::{bytes_annotated, u64_annotated}, + scenario_model::{BlockInfo, SetStateStep}, + ScenarioTxEnvData, +}; + +use super::{SetStateBuilder, SetStateBuilderItem}; + +pub enum BlockItemTarget { + Current, + Previous, +} + +pub struct BlockItem { + target: BlockItemTarget, + block_info: BlockInfo, +} + +impl BlockItem { + pub fn new_current() -> Self { + BlockItem { + target: BlockItemTarget::Current, + block_info: BlockInfo::default(), + } + } + + pub fn new_prev() -> Self { + BlockItem { + target: BlockItemTarget::Previous, + block_info: BlockInfo::default(), + } + } +} + +impl SetStateBuilderItem for BlockItem { + fn commit_to_step(&mut self, step: &mut SetStateStep) { + let block_info = core::mem::take(&mut self.block_info); + match self.target { + BlockItemTarget::Current => { + step.current_block_info = Box::new(Some(block_info)); + }, + BlockItemTarget::Previous => { + step.previous_block_info = Box::new(Some(block_info)); + }, + } + } +} + +impl<'w> SetStateBuilder<'w, BlockItem> { + pub fn block_epoch(mut self, block_epoch: N) -> Self + where + N: AnnotatedValue, + { + let env = self.new_env_data(); + let block_epoch_value = u64_annotated(&env, &block_epoch); + + self.item.block_info.block_epoch = Some(block_epoch_value); + self + } + + pub fn block_nonce(mut self, block_nonce: N) -> Self + where + N: AnnotatedValue, + { + let env = self.new_env_data(); + let block_nonce_value = u64_annotated(&env, &block_nonce); + + self.item.block_info.block_nonce = Some(block_nonce_value); + self + } + + pub fn block_round(mut self, block_round: N) -> Self + where + N: AnnotatedValue, + { + let env = self.new_env_data(); + let block_round_value = u64_annotated(&env, &block_round); + + self.item.block_info.block_round = Some(block_round_value); + self + } + + pub fn block_timestamp(mut self, block_timestamp: N) -> Self + where + N: AnnotatedValue, + { + let env = self.new_env_data(); + let block_timestamp_value = u64_annotated(&env, &block_timestamp); + + self.item.block_info.block_timestamp = Some(block_timestamp_value); + self + } + + pub fn block_random_seed(mut self, block_random_seed: B) -> Self + where + B: AnnotatedValue>, + { + let env = self.new_env_data(); + let block_random_seed_value = bytes_annotated(&env, block_random_seed); + + self.item.block_info.block_random_seed = Some(block_random_seed_value); + self + } +} diff --git a/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_new_address.rs b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_new_address.rs new file mode 100644 index 0000000000..35a8ae392b --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_set_state/scenario_set_new_address.rs @@ -0,0 +1,14 @@ +use crate::scenario_model::{NewAddress, SetStateStep}; + +use super::SetStateBuilderItem; + +pub struct NewAddressItem { + pub(super) new_address: NewAddress, +} + +impl SetStateBuilderItem for NewAddressItem { + fn commit_to_step(&mut self, step: &mut SetStateStep) { + step.new_addresses + .push(core::mem::take(&mut self.new_address)); + } +} diff --git a/framework/scenario/src/facade/world_tx/scenario_tx_env.rs b/framework/scenario/src/facade/world_tx/scenario_tx_env.rs new file mode 100644 index 0000000000..91aa212fc3 --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_tx_env.rs @@ -0,0 +1,66 @@ +use std::path::PathBuf; + +use multiversx_chain_scenario_format::interpret_trait::InterpreterContext; +use multiversx_sc::types::{ManagedAddress, ManagedBuffer, TxEnv, H256}; + +use crate::{api::StaticApi, scenario_model::TxExpect, ScenarioWorld}; + +/// Designates a tx environment suitable for running scenarios locally. +pub trait ScenarioTxEnv: TxEnv { + fn env_data(&self) -> &ScenarioTxEnvData; +} + +/// The actual data required to run a scenario locally. This is the minimal environment needed to run txs. +#[derive(Default, Debug, Clone)] +pub struct ScenarioTxEnvData { + pub context_path: PathBuf, + pub tx_hash: Option, +} + +impl TxEnv for ScenarioTxEnvData { + type Api = StaticApi; + + type RHExpect = TxExpect; + + fn resolve_sender_address(&self) -> ManagedAddress { + panic!("Explicit sender address expected") + } + + fn default_gas_annotation(&self) -> multiversx_sc::types::ManagedBuffer { + ManagedBuffer::from("5,000,000") + } + + fn default_gas_value(&self) -> u64 { + 5_000_000 + } +} + +impl ScenarioTxEnvData { + pub fn interpreter_context(&self) -> InterpreterContext { + InterpreterContext::default() + .with_dir(self.context_path.clone()) + .with_allowed_missing_files() + } +} + +impl ScenarioTxEnv for ScenarioTxEnvData { + fn env_data(&self) -> &ScenarioTxEnvData { + self + } +} + +impl ScenarioWorld { + pub(crate) fn new_env_data(&self) -> ScenarioTxEnvData { + ScenarioTxEnvData { + context_path: self.current_dir.clone(), + tx_hash: None, + } + } +} + +/// Provides a `run` method for transactions and steps. +pub trait ScenarioTxRun { + type Returns; + + fn run(self) -> Self::Returns; +} diff --git a/framework/scenario/src/imports.rs b/framework/scenario/src/imports.rs new file mode 100644 index 0000000000..0da1a2d072 --- /dev/null +++ b/framework/scenario/src/imports.rs @@ -0,0 +1,25 @@ +pub use crate::multiversx_sc::imports::*; + +pub use crate::multiversx_sc::codec::test_util::*; + +pub use crate::{ + api::{DebugApi, StaticApi}, + assert_values_eq, bech32, + facade::{ + expr::*, result_handlers::*, world_tx::*, ContractInfo, ScenarioWorld, WhiteboxContract, + }, + managed_address, managed_biguint, managed_buffer, managed_token_id, num_bigint, + num_bigint::BigUint as RustBigUint, + rust_biguint, + scenario::{ + model::{ + Account, AddressValue, BytesValue, CheckAccount, CheckStateStep, ScCallStep, + ScDeployStep, ScQueryStep, Scenario, SetStateStep, TransferStep, TxESDT, TxExpect, + TypedResponse, TypedScDeploy, + }, + ScenarioRunner, + }, + scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext}, + whitebox_legacy::*, + ScenarioTxRun, +}; diff --git a/framework/scenario/src/lib.rs b/framework/scenario/src/lib.rs index 0110147ed3..cfac7eaa50 100644 --- a/framework/scenario/src/lib.rs +++ b/framework/scenario/src/lib.rs @@ -1,5 +1,4 @@ #![allow(clippy::type_complexity)] -#![feature(exhaustive_patterns)] pub mod api; pub mod bech32; @@ -8,20 +7,13 @@ pub mod display_util; mod facade; pub mod managed_test_util; pub mod scenario; -mod scenario_macros; -pub mod standalone; -pub mod test_wallets; +pub mod scenario_macros; mod vm_go_tool; -#[deprecated( - since = "0.42.0", - note = "Use the blackbox testing framework instead. If needed, it also supports whitebox calls." -)] pub mod whitebox_legacy; /// Keeping this for backwards compatibility. /// Unfortunately, the `deprecated` annotation doesn't function for reexports. -#[allow(deprecated)] pub use whitebox_legacy as testing_framework; pub use api::DebugApi; @@ -32,7 +24,7 @@ pub use num_bigint; pub use multiversx_sc; -pub use multiversx_sc_meta as meta; +pub use multiversx_sc_meta_lib as meta; /// Exposing the scenario model. Might be moved in the future, /// but the export will hopefully remain the same. @@ -44,10 +36,13 @@ pub use crate::scenario as mandos_system; // Re-exporting the whole mandos crate for easier use in tests. pub use multiversx_chain_scenario_format as scenario_format; -pub use facade::{ContractInfo, ScenarioWorld, WhiteboxContract}; +pub use facade::{result_handlers::*, world_tx::*, ContractInfo, ScenarioWorld, WhiteboxContract}; use std::path::Path; +/// Imports normally needed in integration tests, grouped together. +pub mod imports; + /// Legacy function for running a scenario test using the Go VM tool. /// /// Use `sc-meta test-gen` to replace all calls to it automatically. diff --git a/framework/scenario/src/main.rs b/framework/scenario/src/main.rs deleted file mode 100644 index 7de76cd7cf..0000000000 --- a/framework/scenario/src/main.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[tokio::main] -async fn main() { - multiversx_sc_scenario::standalone::cli_main().await; -} diff --git a/framework/scenario/src/scenario/mod.rs b/framework/scenario/src/scenario.rs similarity index 91% rename from framework/scenario/src/scenario/mod.rs rename to framework/scenario/src/scenario.rs index 3ffd41300f..70f8f5f285 100644 --- a/framework/scenario/src/scenario/mod.rs +++ b/framework/scenario/src/scenario.rs @@ -4,6 +4,7 @@ pub mod run_list; pub mod run_trace; pub mod run_vm; mod scenario_runner; +pub mod tx_to_step; pub use parse_util::{parse_scenario, parse_scenario_raw}; pub use scenario_runner::ScenarioRunner; diff --git a/framework/scenario/src/scenario/model/account_data/account.rs b/framework/scenario/src/scenario/model/account_data/account.rs index 8488017c4e..9748fdf7dc 100644 --- a/framework/scenario/src/scenario/model/account_data/account.rs +++ b/framework/scenario/src/scenario/model/account_data/account.rs @@ -86,14 +86,14 @@ impl Account { } #[allow(clippy::too_many_arguments)] - pub fn esdt_nft_all_properties( + pub fn esdt_nft_all_properties( mut self, token_id_expr: K, nonce_expr: N, balance_expr: V, opt_attributes_expr: Option, royalties_expr: N, - creator_expr: Option, + creator_expr: Option, hash_expr: Option, uris_expr: Vec, ) -> Self @@ -102,6 +102,7 @@ impl Account { U64Value: From, BigUintValue: From, BytesValue: From, + AddressValue: From, { let token_id = BytesKey::from(token_id_expr); diff --git a/framework/scenario/src/scenario/model/esdt_data/esdt_instance.rs b/framework/scenario/src/scenario/model/esdt_data/esdt_instance.rs index 8607937c6c..01e57394d2 100644 --- a/framework/scenario/src/scenario/model/esdt_data/esdt_instance.rs +++ b/framework/scenario/src/scenario/model/esdt_data/esdt_instance.rs @@ -4,13 +4,14 @@ use crate::{ interpret_trait::{InterpretableFrom, InterpreterContext, IntoRaw}, serde_raw::EsdtInstanceRaw, }, + scenario_model::AddressValue, }; #[derive(Debug, Default, Clone)] pub struct EsdtInstance { pub nonce: Option, pub balance: Option, - pub creator: Option, + pub creator: Option, pub royalties: Option, pub hash: Option, pub uri: Vec, @@ -41,7 +42,9 @@ impl InterpretableFrom for EsdtInstance { balance: from .balance .map(|b| BigUintValue::interpret_from(b, context)), - creator: from.creator.map(|b| BytesValue::interpret_from(b, context)), + creator: from + .creator + .map(|b| AddressValue::interpret_from(b, context)), royalties: from.royalties.map(|b| U64Value::interpret_from(b, context)), hash: from.hash.map(|b| BytesValue::interpret_from(b, context)), uri: from diff --git a/framework/scenario/src/scenario/model/esdt_data/esdt_object.rs b/framework/scenario/src/scenario/model/esdt_data/esdt_object.rs index f8298e2b8c..f9d65e4df9 100644 --- a/framework/scenario/src/scenario/model/esdt_data/esdt_object.rs +++ b/framework/scenario/src/scenario/model/esdt_data/esdt_object.rs @@ -1,5 +1,8 @@ use super::EsdtInstance; -use crate::scenario::model::{BigUintValue, BytesValue, U64Value}; +use crate::{ + scenario::model::{BigUintValue, BytesValue, U64Value}, + scenario_model::AddressValue, +}; #[derive(Debug, Default, Clone)] pub struct EsdtObject { @@ -53,19 +56,20 @@ impl EsdtObject { } #[allow(clippy::too_many_arguments)] - pub fn set_token_all_properties( + pub fn set_token_all_properties( &mut self, nonce_expr: N, balance_expr: V, opt_attributes_expr: Option, royalties_expr: N, - creator_expr: Option, + creator_expr: Option, hash_expr: Option, uris_expr: Vec, ) where U64Value: From, BigUintValue: From, BytesValue: From, + AddressValue: From, { let inst_for_nonce = self.get_or_insert_instance_for_nonce(nonce_expr); @@ -93,8 +97,8 @@ impl EsdtObject { } if let Some(creator_expr) = creator_expr { - let creator = BytesValue::from(creator_expr); - if !creator.value.is_empty() { + let creator = AddressValue::from(creator_expr); + if !creator.value.is_zero() { inst_for_nonce.creator = Some(creator); } else { inst_for_nonce.creator = None; diff --git a/framework/scenario/src/scenario/model/new_address.rs b/framework/scenario/src/scenario/model/new_address.rs index f4893978d1..3ef0ddba2c 100644 --- a/framework/scenario/src/scenario/model/new_address.rs +++ b/framework/scenario/src/scenario/model/new_address.rs @@ -5,7 +5,7 @@ use crate::scenario_format::{ use super::{AddressValue, U64Value}; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct NewAddress { pub creator_address: AddressValue, pub creator_nonce: U64Value, diff --git a/framework/scenario/src/scenario/model/step/sc_call_step.rs b/framework/scenario/src/scenario/model/step/sc_call_step.rs index f18bf4c2c5..4a68bfa000 100644 --- a/framework/scenario/src/scenario/model/step/sc_call_step.rs +++ b/framework/scenario/src/scenario/model/step/sc_call_step.rs @@ -1,4 +1,5 @@ -use multiversx_sc::types::H256; +use multiversx_sc::{abi::TypeAbiFrom, types::H256}; +use unwrap_infallible::UnwrapInfallible; use crate::{ api::StaticApi, @@ -7,12 +8,10 @@ use crate::{ }; use crate::multiversx_sc::{ - codec::{CodecFrom, PanicErrorHandler, TopEncodeMulti}, + codec::{PanicErrorHandler, TopEncodeMulti}, types::{ContractCall, ManagedArgBuffer}, }; -use super::TypedScCall; - #[derive(Debug, Clone)] pub struct ScCallStep { pub id: String, @@ -136,9 +135,14 @@ impl ScCallStep { /// - "to" /// - "function" /// - "arguments" - pub fn call(mut self, contract_call: CC) -> TypedScCall + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] + #[allow(deprecated)] + pub fn call(mut self, contract_call: CC) -> super::TypedScCall where - CC: ContractCall, + CC: multiversx_sc::types::ContractCallBase, { let (to_str, function, egld_value_expr, scenario_args) = process_contract_call(contract_call); @@ -167,14 +171,15 @@ impl ScCallStep { since = "0.42.0", note = "Please use `call` followed by `expect`, there is no point in having a method that does both." )] + #[allow(deprecated)] pub fn call_expect( self, contract_call: CC, expected_value: ExpectedResult, - ) -> TypedScCall + ) -> super::TypedScCall where CC: ContractCall, - ExpectedResult: CodecFrom + TopEncodeMulti, + ExpectedResult: TypeAbiFrom + TopEncodeMulti, { self.call(contract_call).expect_value(expected_value) } @@ -220,11 +225,12 @@ impl AsMut for ScCallStep { /// - recipient, /// - endpoint name, /// - the arguments. +#[allow(deprecated)] pub(super) fn process_contract_call( contract_call: CC, ) -> (String, String, BigUintValue, Vec) where - CC: ContractCall, + CC: multiversx_sc::types::ContractCallBase, { let normalized_cc = contract_call.into_normalized(); let to_str = format!( @@ -255,7 +261,8 @@ pub fn convert_call_args(arg_buffer: &ManagedArgBuffer) -> Vec(t: T) -> TxExpect { let mut encoded = Vec::>::new(); - let Ok(()) = t.multi_encode_or_handle_err(&mut encoded, PanicErrorHandler); + t.multi_encode_or_handle_err(&mut encoded, PanicErrorHandler) + .unwrap_infallible(); let mut expect = TxExpect::ok().no_result(); for encoded_res in encoded { let encoded_hex_string = format!("0x{}", hex::encode(encoded_res.as_slice())); diff --git a/framework/scenario/src/scenario/model/step/sc_deploy_step.rs b/framework/scenario/src/scenario/model/step/sc_deploy_step.rs index 0ade06fc0f..7e520e1a17 100644 --- a/framework/scenario/src/scenario/model/step/sc_deploy_step.rs +++ b/framework/scenario/src/scenario/model/step/sc_deploy_step.rs @@ -10,7 +10,7 @@ use crate::{ scenario_model::TxResponse, }; -use crate::multiversx_sc::types::{CodeMetadata, ContractDeploy}; +use crate::multiversx_sc::types::CodeMetadata; use super::{convert_call_args, TypedScDeploy}; @@ -98,11 +98,16 @@ impl ScDeployStep { /// Sets following fields based on the smart contract proxy: /// - "function" /// - "arguments" - pub fn call( - mut self, - contract_deploy: ContractDeploy, - ) -> TypedScDeploy { - let (_, mandos_args) = process_contract_deploy(contract_deploy); + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] + #[allow(deprecated)] + pub fn call(mut self, contract_deploy: CD) -> TypedScDeploy + where + CD: Into>, + { + let (_, mandos_args) = process_contract_deploy(contract_deploy.into()); for arg in mandos_args { self = self.argument(arg.as_str()); } @@ -149,8 +154,13 @@ impl AsMut for ScDeployStep { /// Extracts /// - (optional) recipient (needed for contract upgrade, not yet used); /// - the arguments. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] +#[allow(deprecated)] pub(crate) fn process_contract_deploy( - contract_deploy: ContractDeploy, + contract_deploy: multiversx_sc::types::ContractDeploy, ) -> (Option, Vec) { let to_str = contract_deploy .to diff --git a/framework/scenario/src/scenario/model/step/sc_query_step.rs b/framework/scenario/src/scenario/model/step/sc_query_step.rs index a3ada3b83b..8183dcd579 100644 --- a/framework/scenario/src/scenario/model/step/sc_query_step.rs +++ b/framework/scenario/src/scenario/model/step/sc_query_step.rs @@ -1,12 +1,9 @@ -use multiversx_sc::types::H256; +use multiversx_sc::{abi::TypeAbiFrom, types::H256}; use num_traits::Zero; use crate::{ api::StaticApi, - multiversx_sc::{ - codec::{CodecFrom, TopEncodeMulti}, - types::ContractCall, - }, + multiversx_sc::{codec::TopEncodeMulti, types::ContractCall}, scenario::model::{AddressValue, BytesValue, TxExpect, TxQuery}, scenario_model::TxResponse, }; @@ -65,9 +62,14 @@ impl ScQueryStep { /// - "to" /// - "function" /// - "arguments" + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] + #[allow(deprecated)] pub fn call(mut self, contract_call: CC) -> TypedScQuery where - CC: ContractCall, + CC: multiversx_sc::types::ContractCallBase, { let (to_str, function, egld_value_expr, mandos_args) = process_contract_call(contract_call); assert!( @@ -89,6 +91,11 @@ impl ScQueryStep { /// - "expect" /// - "out" /// - "status" set to 0 + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] + #[allow(deprecated)] pub fn call_expect( self, contract_call: CC, @@ -96,7 +103,7 @@ impl ScQueryStep { ) -> TypedScQuery where CC: ContractCall, - ExpectedResult: CodecFrom + TopEncodeMulti, + ExpectedResult: TypeAbiFrom + TopEncodeMulti, { let typed = self.call(contract_call); typed.expect_value(expected_value) diff --git a/framework/scenario/src/scenario/model/step/typed_sc_call.rs b/framework/scenario/src/scenario/model/step/typed_sc_call.rs index bf939ee590..e70e00aa64 100644 --- a/framework/scenario/src/scenario/model/step/typed_sc_call.rs +++ b/framework/scenario/src/scenario/model/step/typed_sc_call.rs @@ -1,8 +1,13 @@ +#![allow(deprecated)] + use std::marker::PhantomData; -use multiversx_sc::codec::PanicErrorHandler; +use multiversx_sc::{ + abi::TypeAbiFrom, + codec::{PanicErrorHandler, TopDecodeMulti}, +}; -use crate::multiversx_sc::codec::{CodecFrom, TopEncodeMulti}; +use crate::multiversx_sc::codec::TopEncodeMulti; use crate::{ scenario::model::{AddressValue, U64Value}, @@ -12,6 +17,10 @@ use crate::{ use super::{format_expect, ScCallStep}; /// `SCCallStep` with explicit return type. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] #[derive(Default, Debug)] pub struct TypedScCall { pub sc_call_step: ScCallStep, @@ -22,7 +31,7 @@ impl TypedScCall { pub fn result(&self) -> Result where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { let mut raw_result = self.response().out.clone(); Ok( @@ -109,7 +118,7 @@ impl TypedScCall { pub fn expect_value(self, expected_value: ExpectedResult) -> Self where OriginalResult: TopEncodeMulti, - ExpectedResult: CodecFrom + TopEncodeMulti, + ExpectedResult: TypeAbiFrom + TopEncodeMulti, { self.expect(format_expect(expected_value)) } @@ -144,14 +153,22 @@ impl From for TypedScCall { /// Helps with syntax. Allows the `TypedScCall` to call the `execute` operation directly. /// /// The trait defines the connection to the executor. +#[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." +)] pub trait TypedScCallExecutor { + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] fn execute_typed_sc_call( &mut self, typed_sc_call: TypedScCall, ) -> RequestedResult where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom; + RequestedResult: TopDecodeMulti + TypeAbiFrom; } impl TypedScCall @@ -164,7 +181,7 @@ where executor: &mut E, ) -> RequestedResult where - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { executor.execute_typed_sc_call(self) } diff --git a/framework/scenario/src/scenario/model/step/typed_sc_deploy.rs b/framework/scenario/src/scenario/model/step/typed_sc_deploy.rs index c440f9bd29..2fa49c188f 100644 --- a/framework/scenario/src/scenario/model/step/typed_sc_deploy.rs +++ b/framework/scenario/src/scenario/model/step/typed_sc_deploy.rs @@ -1,11 +1,14 @@ use std::marker::PhantomData; -use multiversx_sc::{codec::PanicErrorHandler, types::ContractDeploy}; +use multiversx_sc::{ + abi::TypeAbiFrom, + codec::{PanicErrorHandler, TopDecodeMulti}, +}; use crate::{ api::StaticApi, multiversx_sc::{ - codec::{CodecFrom, TopEncodeMulti}, + codec::TopEncodeMulti, types::{Address, CodeMetadata}, }, scenario_format::interpret_trait::InterpreterContext, @@ -14,7 +17,7 @@ use crate::{ use crate::scenario::model::{AddressValue, BigUintValue, TxExpect, U64Value}; -use super::{process_contract_deploy, ScDeployStep}; +use super::ScDeployStep; /// `ScDeployStep` with explicit return type. #[derive(Default, Debug)] @@ -27,7 +30,7 @@ impl TypedScDeploy { pub fn result(&self) -> Result where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { let mut raw_result = self.response().out.clone(); Ok( @@ -100,8 +103,16 @@ impl TypedScDeploy { /// Sets following fields based on the smart contract proxy: /// - "function" /// - "arguments" - pub fn call(mut self, contract_deploy: ContractDeploy) -> Self { - let (_, mandos_args) = process_contract_deploy(contract_deploy); + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] + #[allow(deprecated)] + pub fn call( + mut self, + contract_deploy: multiversx_sc::types::ContractDeploy, + ) -> Self { + let (_, mandos_args) = super::process_contract_deploy(contract_deploy); for arg in mandos_args { self.sc_deploy_step.tx.arguments.push(BytesValue::from(arg)); } @@ -145,7 +156,7 @@ pub trait TypedScDeployExecutor { ) -> (Address, RequestedResult) where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom; + RequestedResult: TopDecodeMulti + TypeAbiFrom; } impl TypedScDeploy @@ -158,7 +169,7 @@ where executor: &mut E, ) -> (Address, RequestedResult) where - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { executor.execute_typed_sc_deploy(self) } diff --git a/framework/scenario/src/scenario/model/step/typed_sc_query.rs b/framework/scenario/src/scenario/model/step/typed_sc_query.rs index 60b3b91818..3e7e819c4e 100644 --- a/framework/scenario/src/scenario/model/step/typed_sc_query.rs +++ b/framework/scenario/src/scenario/model/step/typed_sc_query.rs @@ -1,6 +1,8 @@ use std::marker::PhantomData; -use crate::multiversx_sc::codec::{CodecFrom, TopEncodeMulti}; +use multiversx_sc::{abi::TypeAbiFrom, codec::TopDecodeMulti}; + +use crate::multiversx_sc::codec::TopEncodeMulti; use crate::{ scenario::model::{AddressValue, BytesValue, TxExpect}, @@ -72,7 +74,7 @@ impl TypedScQuery { pub fn expect_value(self, expected_value: ExpectedResult) -> Self where OriginalResult: TopEncodeMulti, - ExpectedResult: CodecFrom + TopEncodeMulti, + ExpectedResult: TypeAbiFrom + TopEncodeMulti, { self.expect(format_expect(expected_value)) } @@ -105,7 +107,7 @@ pub trait TypedScQueryExecutor { ) -> RequestedResult where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom; + RequestedResult: TopDecodeMulti + TypeAbiFrom; } impl TypedScQuery @@ -118,7 +120,7 @@ where executor: &mut E, ) -> RequestedResult where - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { executor.execute_typed_sc_query(self) } diff --git a/framework/scenario/src/scenario/model/transaction.rs b/framework/scenario/src/scenario/model/transaction.rs index c1a6d6a271..3ffa8a542d 100644 --- a/framework/scenario/src/scenario/model/transaction.rs +++ b/framework/scenario/src/scenario/model/transaction.rs @@ -9,7 +9,6 @@ mod tx_interpret_util; mod tx_query; mod tx_response; mod tx_response_status; -mod tx_response_utils; mod tx_transfer; mod tx_validator_reward; mod typed_response; @@ -24,7 +23,6 @@ pub use tx_expect::*; pub use tx_query::*; pub use tx_response::TxResponse; pub use tx_response_status::TxResponseStatus; -pub use tx_response_utils::*; pub use tx_transfer::*; pub use tx_validator_reward::*; pub use typed_response::TypedResponse; diff --git a/framework/scenario/src/scenario/model/transaction/tx_call.rs b/framework/scenario/src/scenario/model/transaction/tx_call.rs index 102ef3ef4e..547466032e 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_call.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_call.rs @@ -1,6 +1,6 @@ use crate::{ api::StaticApi, - multiversx_sc::types::{ContractCall, ContractCallWithEgld, EsdtTokenPayment}, + multiversx_sc::types::{ContractCall, EsdtTokenPayment}, scenario::model::{AddressValue, BigUintValue, BytesValue, U64Value}, scenario_format::{ interpret_trait::{InterpretableFrom, InterpreterContext, IntoRaw}, @@ -87,8 +87,13 @@ impl IntoRaw for TxCall { } impl TxCall { - pub fn to_contract_call(&self) -> ContractCallWithEgld { - let mut contract_call = ContractCallWithEgld::new( + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] + #[allow(deprecated)] + pub fn to_contract_call(&self) -> multiversx_sc::types::ContractCallWithEgld { + let mut contract_call = multiversx_sc::types::ContractCallWithEgld::new( (&self.to.value).into(), self.function.as_bytes(), (&self.egld_value.value).into(), diff --git a/framework/scenario/src/scenario/model/transaction/tx_esdt.rs b/framework/scenario/src/scenario/model/transaction/tx_esdt.rs index cf17a76a19..67ccf99956 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_esdt.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_esdt.rs @@ -1,3 +1,5 @@ +use multiversx_sc::{api::ManagedTypeApi, types::EsdtTokenPayment}; + use crate::{ scenario::model::{BigUintValue, BytesValue, U64Value}, scenario_format::{ @@ -33,6 +35,18 @@ impl IntoRaw for TxESDT { } } +impl From> for TxESDT { + fn from(value: EsdtTokenPayment) -> Self { + TxESDT { + esdt_token_identifier: BytesValue::from( + value.token_identifier.as_managed_buffer().to_vec(), + ), + nonce: U64Value::from(value.token_nonce), + esdt_value: BigUintValue::from(value.amount), + } + } +} + fn interpret_esdt_token_identifier( esdt_token_identifier: Option, context: &InterpreterContext, diff --git a/framework/scenario/src/scenario/model/transaction/tx_expect.rs b/framework/scenario/src/scenario/model/transaction/tx_expect.rs index 6f64a471f0..d487a10db5 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_expect.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_expect.rs @@ -23,6 +23,12 @@ pub struct TxExpect { pub additional_error_message: String, } +impl Default for TxExpect { + fn default() -> Self { + Self::ok() + } +} + impl TxExpect { pub fn ok() -> Self { TxExpect { diff --git a/framework/scenario/src/scenario/model/transaction/tx_response.rs b/framework/scenario/src/scenario/model/transaction/tx_response.rs index 440db8258a..46806b1183 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_response.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_response.rs @@ -1,18 +1,8 @@ -use multiversx_chain_vm::{crypto_functions::keccak256, tx_mock::TxResult}; +use multiversx_chain_vm::tx_mock::TxResult; use multiversx_sc::types::Address; -use multiversx_sdk::{ - data::transaction::{ApiLogs, ApiSmartContractResult, Events, TransactionOnNetwork}, - utils::base64_decode, -}; +use multiversx_sdk::data::transaction::{ApiLogs, ApiSmartContractResult}; -use super::{ - decode_scr_data_or_panic, is_out_scr, process_topics_error, Log, TxExpect, TxResponseStatus, -}; - -const SC_DEPLOY_PROCESSING_TYPE: &str = "SCDeployment"; -const LOG_IDENTIFIER_SIGNAL_ERROR: &str = "signalError"; - -const SYSTEM_SC_BECH32: &str = "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u"; +use super::{Log, TxExpect, TxResponseStatus}; #[derive(Debug, Default, Clone)] /// The response of a transaction. @@ -50,26 +40,6 @@ impl TxResponse { } } - /// Creates a [`TxResponse`] from a [`TransactionOnNetwork`]. - pub fn from_network_tx(tx: TransactionOnNetwork) -> Self { - let mut response = Self { - api_scrs: tx.smart_contract_results.unwrap_or_default(), - api_logs: tx.logs, - ..Default::default() - }; - - response.tx_error = response.process_signal_error(); - if !response.tx_error.is_success() { - return response; - } - - response.process( - tx.sender.to_bytes(), - tx.nonce, - tx.processing_type_on_destination, - ) - } - /// Creates a [`TxResponse`] from raw results. pub fn from_raw_results(raw_results: Vec>) -> Self { TxResponse { @@ -105,2269 +75,4 @@ impl TxResponse { pub fn is_success(&self) -> bool { self.tx_error.is_success() } - - fn process_signal_error(&self) -> TxResponseStatus { - if let Some(event) = self.find_log(LOG_IDENTIFIER_SIGNAL_ERROR) { - let topics = event.topics.as_ref(); - if let Some(error) = process_topics_error(topics) { - return TxResponseStatus::signal_error(&error); - } - - let error_raw = base64_decode(topics.unwrap().get(1).unwrap()); - let error = String::from_utf8(error_raw).unwrap(); - return TxResponseStatus::signal_error(&error); - } - - TxResponseStatus::default() - } - - fn process( - self, - sender_address: [u8; 32], - nonce: u64, - processing_type_on_destination: String, - ) -> Self { - self.process_out() - .process_new_deployed_address(sender_address, nonce, processing_type_on_destination) - .process_new_issued_token_identifier() - } - - fn process_out(mut self) -> Self { - let out_scr = self.api_scrs.iter().find(is_out_scr); - - if let Some(out_scr) = out_scr { - self.out = decode_scr_data_or_panic(&out_scr.data); - } else if let Some(data) = self.process_out_from_log() { - self.out = data - } - - self - } - - fn process_out_from_log(&self) -> Option>> { - if let Some(logs) = &self.api_logs { - logs.events.iter().rev().find_map(|event| { - if event.identifier == "writeLog" { - if let Some(data) = &event.data { - let decoded_data = String::from_utf8(base64_decode(data)).unwrap(); - - if decoded_data.starts_with('@') { - let out = decode_scr_data_or_panic(decoded_data.as_str()); - return Some(out); - } - } - } - - None - }) - } else { - None - } - } - - fn process_new_deployed_address( - mut self, - sender_address_bytes: [u8; 32], - nonce: u64, - processing_type_on_destination: String, - ) -> Self { - if processing_type_on_destination != SC_DEPLOY_PROCESSING_TYPE { - return self; - } - - let sender_nonce_bytes = nonce.to_le_bytes(); - let mut bytes_to_hash: Vec = Vec::new(); - bytes_to_hash.extend_from_slice(&sender_address_bytes); - bytes_to_hash.extend_from_slice(&sender_nonce_bytes); - - let address_keccak = keccak256(&bytes_to_hash); - - let mut address = [0u8; 32]; - - address[0..8].copy_from_slice(&[0u8; 8]); - address[8..10].copy_from_slice(&[5, 0]); - address[10..30].copy_from_slice(&address_keccak[10..30]); - address[30..32].copy_from_slice(&sender_address_bytes[30..32]); - - self.new_deployed_address = Some(Address::from(address)); - - self - } - - fn process_new_issued_token_identifier(mut self) -> Self { - for scr in self.api_scrs.iter() { - if scr.sender.to_string() != SYSTEM_SC_BECH32 { - continue; - } - - let Some(prev_tx) = self.api_scrs.iter().find(|e| e.hash == scr.prev_tx_hash) else { - continue; - }; - - let is_issue_fungible = prev_tx.data.starts_with("issue@"); - let is_issue_semi_fungible = prev_tx.data.starts_with("issueSemiFungible@"); - let is_issue_non_fungible = prev_tx.data.starts_with("issueNonFungible@"); - let is_register_meta_esdt = prev_tx.data.starts_with("registerMetaESDT@"); - - if !is_issue_fungible - && !is_issue_semi_fungible - && !is_issue_non_fungible - && !is_register_meta_esdt - { - continue; - } - - if scr.data.starts_with("ESDTTransfer@") { - let encoded_tid = scr.data.split('@').nth(1); - if encoded_tid.is_none() { - return self; - } - - self.new_issued_token_identifier = - Some(String::from_utf8(hex::decode(encoded_tid.unwrap()).unwrap()).unwrap()); - - break; - } else if scr.data.starts_with("@00@") { - let encoded_tid = scr.data.split('@').nth(2); - if encoded_tid.is_none() { - return self; - } - - self.new_issued_token_identifier = - Some(String::from_utf8(hex::decode(encoded_tid.unwrap()).unwrap()).unwrap()); - - break; - } - } - - self - } - - fn find_log(&self, log_identifier: &str) -> Option<&Events> { - if let Some(logs) = &self.api_logs { - logs.events - .iter() - .find(|event| event.identifier == log_identifier) - } else { - None - } - } -} - -#[cfg(test)] -mod tests { - use crate::scenario_model::TxResponse; - use multiversx_sc::types::Address; - use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; - - #[test] - fn test_deployed_address() { - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCDeployment", - "processingTypeOnDestination": "SCDeployment", - "hash": "07a176d1734d1901d396be344f97e1d80f076269e9559f9b2110f6f11c4f74de", - "nonce": 427, - "round": 2190715, - "epoch": 887, - "value": "0", - "receiver": "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu", - "sender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "gasPrice": 1000000000, - "gasLimit": 600000000, - "data": "MDA2MTczNmQwMTAwMDAwMDAxOTgwMTE5NjAwMjdmN2YwMDYwMDE3ZjAxN2Y2MDAwMDA2MDAwMDE3ZjYwMDI3ZjdmMDE3ZjYwMDM3ZjdmN2YwMDYwMDE3ZjAwNjAwNDdmN2Y3ZjdmMDA2MDA1N2Y3ZjdmN2Y3ZjAwNjAwMzdmN2Y3ZjAxN2Y2MDA0N2Y3ZjdmN2YwMTdmNjAwMjdmN2UwMDYwMDE3ZjAxN2U2MDAyN2Y3ZjAxN2U2MDA1N2Y3ZjdlN2Y3ZjAxN2Y2MDA2N2U3ZjdmN2Y3ZjdmMDE3ZjYwMDE3ZTAwNjAwMDAxN2U2MDAxN2UwMTdmNjAwNDdmN2Y3ZTdmMDA2MDA1N2U3ZjdmN2Y3ZjAxN2Y2MDA0N2Y3ZjdmN2UwMDYwMDE3ZTAxN2U2MDA0N2Y3ZTdmN2YwMDYwMDI3ZTdmMDAwMmMxMDcyOTAzNjU2ZTc2MTI2ZDYxNmU2MTY3NjU2NDUzNjk2NzZlNjE2YzQ1NzI3MjZmNzIwMDA2MDM2NTZlNzYwZTYyNjk2NzQ5NmU3NDUzNjU3NDQ5NmU3NDM2MzQwMDBiMDM2NTZlNzYwOTYyNjk2NzQ5NmU3NDQxNjQ2NDAwMDUwMzY1NmU3NjBiNzM2OTY3NmU2MTZjNDU3MjcyNmY3MjAwMDAwMzY1NmU3NjBhNmQ0Mjc1NjY2NjY1NzI0ZTY1NzcwMDAzMDM2NTZlNzYwZDZkNDI3NTY2NjY2NTcyNDE3MDcwNjU2ZTY0MDAwNDAzNjU2ZTc2MDk2ZDQyNzU2NjY2NjU3MjQ1NzEwMDA0MDM2NTZlNzYwZDZkNDI3NTY2NjY2NTcyNDY2OTZlNjk3MzY4MDAwMTAzNjU2ZTc2MjI2ZDYxNmU2MTY3NjU2NDRkNzU2Yzc0Njk1NDcyNjE2ZTczNjY2NTcyNDU1MzQ0NTQ0ZTQ2NTQ0NTc4NjU2Mzc1NzQ2NTAwMGUwMzY1NmU3NjFiNmQ2MTZlNjE2NzY1NjQ0NTc4NjU2Mzc1NzQ2NTRmNmU0NDY1NzM3NDQzNmY2ZTc0NjU3ODc0MDAwZjAzNjU2ZTc2MGQ2ZDYxNmU2MTY3NjU2NDQzNjE2YzZjNjU3MjAwMDYwMzY1NmU3NjEwNmQ2MTZlNjE2NzY1NjQ1MzQzNDE2NDY0NzI2NTczNzMwMDA2MDM2NTZlNzYxMzZkNjE2ZTYxNjc2NTY0NGY3NzZlNjU3MjQxNjQ2NDcyNjU3MzczMDAwNjAzNjU2ZTc2MWM2ZDYxNmU2MTY3NjU2NDQ3NjU3NDRkNzU2Yzc0Njk0NTUzNDQ1NDQzNjE2YzZjNTY2MTZjNzU2NTAwMDYwMzY1NmU3NjEyNmQ0Mjc1NjY2NjY1NzI0NzY1NzQ0MTcyNjc3NTZkNjU2ZTc0MDAwNDAzNjU2ZTc2MTI2ZDQyNzU2NjY2NjU3MjQxNzA3MDY1NmU2NDQyNzk3NDY1NzMwMDA5MDM2NTZlNzYxOTYyNjk2NzQ5NmU3NDQ3NjU3NDU1NmU3MzY5Njc2ZTY1NjQ0MTcyNjc3NTZkNjU2ZTc0MDAwMDAzNjU2ZTc2MWI3MzZkNjE2YzZjNDk2ZTc0NDc2NTc0NTU2ZTczNjk2NzZlNjU2NDQxNzI2Nzc1NmQ2NTZlNzQwMDBjMDM2NTZlNzYxMDZkNDI3NTY2NjY2NTcyNDc2NTc0NGM2NTZlNjc3NDY4MDAwMTAzNjU2ZTc2MGY2NzY1NzQ0ZTc1NmQ0MTcyNjc3NTZkNjU2ZTc0NzMwMDAzMDM2NTZlNzYxNjczNmQ2MTZjNmM0OTZlNzQ0NjY5NmU2OTczNjg1NTZlNzM2OTY3NmU2NTY0MDAxMDAzNjU2ZTc2MDk2MjY5Njc0OTZlNzQ1Mzc1NjIwMDA1MDM2NTZlNzYwYTY3NjU3NDQ3NjE3MzRjNjU2Njc0MDAxMTAzNjU2ZTc2MGY2MzZjNjU2MTZlNTI2NTc0NzU3MjZlNDQ2MTc0NjEwMDAyMDM2NTZlNzYwZjZkNDI3NTY2NjY2NTcyNTM2NTc0NDI3OTc0NjU3MzAwMDkwMzY1NmU3NjA5NjI2OTY3NDk2ZTc0NDM2ZDcwMDAwNDAzNjU2ZTc2MGE2MjY5Njc0OTZlNzQ1NDQ0Njk3NjAwMDUwMzY1NmU3NjA5NjI2OTY3NDk2ZTc0NGQ3NTZjMDAwNTAzNjU2ZTc2MTk2ZDQyNzU2NjY2NjU3MjQ2NzI2ZjZkNDI2OTY3NDk2ZTc0NTU2ZTczNjk2NzZlNjU2NDAwMDQwMzY1NmU3NjE3NmQ0Mjc1NjY2NjY1NzI1NDZmNDI2OTY3NDk2ZTc0NTU2ZTczNjk2NzZlNjU2NDAwMDQwMzY1NmU3NjA5NjI2OTY3NDk2ZTc0NTA2Zjc3MDAwNTAzNjU2ZTc2MTQ2ZDQyNzU2NjY2NjU3MjQzNmY3MDc5NDI3OTc0NjU1MzZjNjk2MzY1MDAwYTAzNjU2ZTc2MTI2ZDQyNzU2NjY2NjU3MjUzNzQ2ZjcyNjE2NzY1NGM2ZjYxNjQwMDA0MDM2NTZlNzYxMzZkNDI3NTY2NjY2NTcyNTM3NDZmNzI2MTY3NjU1Mzc0NmY3MjY1MDAwNDAzNjU2ZTc2MGU2MzY4NjU2MzZiNGU2ZjUwNjE3OTZkNjU2ZTc0MDAwMjAzNjU2ZTc2MTc2ZDYxNmU2MTY3NjU2NDQ3NjU3NDQyNjE2MzZiNTQ3MjYxNmU3MzY2NjU3MjczMDAwMDAzNjU2ZTc2MGY2ZDYxNmU2MTY3NjU2NDU3NzI2OTc0NjU0YzZmNjcwMDAwMDM2NTZlNzYxNDYyNjk2NzQ5NmU3NDQ2Njk2ZTY5NzM2ODU1NmU3MzY5Njc2ZTY1NjQwMDA2MDM2NTZlNzYwNjY2Njk2ZTY5NzM2ODAwMDAwMzY1NmU3NjBhNjI2OTY3NDk2ZTc0NTM2OTY3NmUwMDAxMDM2NTZlNzYxMzZkNDI3NTY2NjY2NTcyNDc2NTc0NDI3OTc0NjU1MzZjNjk2MzY1MDAwYTAzZDMwMWQxMDEwMTAzMDgwMjAxMTIwMTA0MDAwMTA3MDYwNjA2MDAwNDAxMDkwMTAwMDEwMDAwMDAwMDEzMDMwMDE0MDMwMzAzMDIwMzAxMDcwNDAwMDMwOTAxMDkwOTA5MDAwNzA3MDEwMDA2MDYwMTA2MDYwYzA1MDEwODA1MDAwMTBiMDAwODA3MTUwNzA4MDgwMDBhMDAxNjAxMDEwNjAxMDAwMDAwMDUwMDAwMDEwMzAwMDYwMTAwMTcwNTA1MGEwNzA0MDAwNDBhMDAwNDA0MDQwMDA0MDQwNDA0MDQwMTAxMDAwNDBkMDcwNzA3MDgwYTAwMDUwMTAxMDUwNTA2MDEwMTAwMGIwYjAxMDEwMTAxMDEwNTBkMDEwNTAwMDAwMDA1MDUwMDAwMDAwMDAwMGMwNzA3MDcwNzAwMDAwODE4MDMwMzAzMDAwMzAzMDAwMTA0MDcwMzAzMDMwMzAxMDEwMzAzMDMwMzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwODA4MDUwMzAxMDAwMzA2MTYwMzdmMDE0MTgwODAwODBiN2YwMDQxZTlkYjA4MGI3ZjAwNDFmMGRiMDgwYjA3YzcwNTIwMDY2ZDY1NmQ2ZjcyNzkwMjAwMDQ2OTZlNjk3NDAwZGIwMTA3NzU3MDY3NzI2MTY0NjUwMGRjMDEwNzY0NjU3MDZmNzM2OTc0MDBkZDAxMDg3NzY5NzQ2ODY0NzI2MTc3MDBkZTAxMDg2MzZmNmQ3MDZmNzU2ZTY0MDBkZjAxMGU2NzY1NzQ1NDZmNzQ2MTZjNDE3MzczNjU3NDczMDBlMDAxMGY2NzY1NzQ1NjYxNzU2Yzc0NDE2NDY0NzI2NTczNzMwMGUxMDExNzY3NjU3NDQxNzM3MzY1NzQ1NDZmNmI2NTZlNDk2NDY1NmU3NDY5NjY2OTY1NzIwMGUyMDExZDY3NjU3NDRkNmY2ZTY1Nzk0ZDYxNzI2YjY1NzQ1NDZmNmI2NTZlNDk2NDY1NmU3NDY5NjY2OTY1NzIwMGUzMDEyMjY3NjU3NDRkNmY2ZTY1Nzk0ZDYxNzI2YjY1NzQ1NTZlNjQ2NTcyNmM3OTY5NmU2NzQ5NjQ2NTZlNzQ2OTY2Njk2NTcyMDBlNDAxMWY2NzY1NzQ0MjZmNmY3Mzc0NjU3MjUzNzQ2MTZiNjU2NDU0NmY2YjY1NmU0OTY0NjU2ZTc0Njk2NjY5NjU3MjAwZTUwMTE0Njc2NTc0NDM2ZjZlNzQ3MjZmNmM2YzY1NzI0MTY0NjQ3MjY1NzM3MzAwZTYwMTE1Njc2NTc0NGQ2ZjZlNjU3OTRkNjE3MjZiNjU3NDQxNjQ2NDcyNjU3MzczMDBlNzAxMWQ2NzY1NzQ1NzcyNjE3MDcwNjU2NDQ1Njc2YzY0NDM2ZjZlNzQ3MjYxNjM3NDQxNjQ2NDcyNjU3MzczMDBlODAxMWQ2NzY1NzQ1NzcyNjE3MDcwNjU2NDQ1Njc2YzY0NTQ2ZjZiNjU2ZTQ5NjQ2NTZlNzQ2OTY2Njk2NTcyMDBlOTAxMTE2NzY1NzQ0MjZmNmY3Mzc0NjU3MjQxNjQ2NDcyNjU3MzczMDBlYTAxMTk2NzY1NzQ0MzZmNmQ3MDZmNzU2ZTY0NTg0NTc4NjM2ODYxNmU2NzY1NTM3NzYxNzA3MzAwZWIwMTE3Njc2NTc0NDM2ZjZkNzA2Zjc1NmU2NDQxNzM2ODczNzc2MTcwNTM3NzYxNzA3MzAwZWMwMTE2Njc2NTc0NDM2ZjZkNzA2Zjc1NmU2NDQ2NjU2NTczNTA2NTcyNjM2NTZlNzQwMGVkMDExOTY3NjU3NDUwNjU3MjY2NmY3MjZkNjE2ZTYzNjU0NjY1NjU3MzUwNjU3MjYzNjU2ZTc0MDBlZTAxMGU3Mzc0NjE2YjY1NDk2ZTQyNmY2ZjczNzQ2NTcyMDBlZjAxMWI3MjY1NjI2MTZjNjE2ZTYzNjU1MDZmNzI3NDY2NmY2YzY5NmY0OTZlNDI2ZjZmNzM3NDY1NzIwMGYwMDExMjc1NmU3Mzc0NjE2YjY1NDY3MjZmNmQ0MjZmNmY3Mzc0NjU3MjAwZjEwMTE4NjM2YzYxNjk2ZDRkNzU2Yzc0Njk3MDZjNjU0NjcyNmY2ZDQyNmY2ZjczNzQ2NTcyMDBmMjAxMTk3MzY1NzQ1MDY1NzI2NjZmNzI2ZDYxNmU2MzY1NDY2NTY1NzM1MDY1NzI2MzY1NmU3NDAwZjMwMTE2NzM2NTc0NDM2ZjZkNzA2Zjc1NmU2NDQ2NjU2NTczNTA2NTcyNjM2NTZlNzQwMGY0MDExMDczNjU3NDQzNmY2ZDcwNmY3NTZlNjQ1Mzc3NjE3MDczMDBmNTAxMGQ2NzY1NzQ0ZTYxNzQ3NTcyNjE2YzQxNTA1OTAwZjYwMTA4NjM2MTZjNmM0MjYxNjM2YjAwZjcwMTBhNWY1ZjY0NjE3NDYxNWY2NTZlNjQwMzAxMGI1ZjVmNjg2NTYxNzA1ZjYyNjE3MzY1MDMwMjBhOWFhOTAxZDEwMTE2MDEwMTdmMTAyYTIyMDE0MjAwMTAwMTIwMDEyMDAxMjAwMDEwMDIyMDAxMGIxOTAxMDE3ZjQxYzg4ZDA4NDFjODhkMDgyODAyMDA0MTAxNmIyMjAwMzYwMjAwMjAwMDBiMmUwMDAyNDAyMDAxMjAwMjRkMDQ0MDIwMDIyMDA0NGQwZDAxMTAyYzAwMGIxMDJjMDAwYjIwMDAyMDAyMjAwMTZiMzYwMjA0MjAwMDIwMDEyMDAzNmEzNjAyMDAwYjBiMDA0MWI4OGQwODQxMGUxMDAzMDAwYjEzMDEwMTdmMTAyYTIyMDEyMDAwYWQ0MmZmMDE4MzEwMDEyMDAxMGIyMTAxMDE3ZjEwMmEyMTAxMjAwMDQyMDA1MzA0NDA0MWIyODUwODQxMTExMDAzMDAwYjIwMDEyMDAwMTAwMTIwMDEwYjBmMDEwMTdmMTAwNDIyMDEyMDAwMTAwNTFhMjAwMTBiMGIwMDIwMDAyMDAxMTAwNjQxMDA0YTBiMmQwMTAxN2YyMzAwNDEyMDZiMjIwMjI0MDAyMDAyMjAwMDEwMzI0MWMwODAwODQxMDgxMDMzMjAwMjIwMDEzNjAyMTgyMDAyMTAzNDIwMDI0MTIwNmEyNDAwMGIxOTAwMjAwMDQxZmVmZmZmZmYwNzQ2MDQ0MDQxYzg4MDA4NDExOTEwMDMwMDBiMjAwMDBiMmEwMDIwMDIyMDAzMTA0ZDIxMDIxMDQzMjEwMzIwMDA0MjdmMzcwMzA4MjAwMDIwMDMzNjAyMDQyMDAwMjAwMjM2MDIwMDIwMDAyMDAxMzYwMjEwMGI3ZDAxMDM3ZjIzMDA0MTEwNmIyMjAxMjQwMDIwMDAyOTAzMDgxMDcxMjAwMDI4MDIxMDIwMDAyODAyMTgyMDAwMjgwMjAwMjAwMDI4MDIwNDEwNDUyMTAyMTAxNzQxMDAyMTAwMjAwMjEwMTIyMTAzMjAwMTQxMDAzNjAyMGMyMDAxMjAwMjM2MDIwNDIwMDEyMDAzNDEwMjc2MjIwMjM2MDIwODAzNDAyMDAwMjAwMjRmNDUwNDQwMjAwMTQxMDQ2YTEwNzUxYTIwMDEyODAyMDgyMTAyMjAwMTI4MDIwYzIxMDAwYzAxMGIwYjIwMDE0MTEwNmEyNDAwMGIzNjAxMDI3ZjIzMDA0MTEwNmIyMjAxMjQwMDIwMDE0MTA4NmExMDM2MjAwMTI4MDIwODIxMDIyMDAwMjAwMTJkMDAwYzQxMDE3MTNhMDAwNDIwMDAyMDAyMzYwMjAwMjAwMTQxMTA2YTI0MDAwYjZkMDEwMjdmMjMwMDQxMTA2YjIyMDEyNDAwMjAwMDAyN2Y0MWUwZGIwODJkMDAwMDIyMDI0NTA0NDA0MWUwZGIwODQxMDEzYTAwMDA0MWRjZGIwODQxMDAzNjAyMDAyMDAxNDEwODZhNDEwMDEwOWYwMTIwMDEyODAyMDgyMDAxMjgwMjBjNDFiODhkMDg0MTAwMTA1NzEwNDMwYzAxMGI0MWI4OGQwODQxMDAxMDRkMGIzNjAyMDAyMDAwMjAwMjQxMDE3MzNhMDAwNDIwMDE0MTEwNmEyNDAwMGIwYjAwMjAwMDIwMDExMDM4MTAwNzFhMGI0OTAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDIyMDAxM2EwMDBjMjAwMjIwMDAzNjAyMDgyMDAyNDEwODZhMTBhNTAxMjAwMjI4MDIwODIwMDIyZDAwMGMwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAyNDExMDZhMjQwMDBiMGUwMDIwMDA0MThhODUwODQxMGIxMDNhMTAzYjBiMTMwMDIwMDAyMDAwMjAwMTIwMDIxMDUyMjAwMTIwMDIxMDg1MDEwYjBkMDAyMDAwMTAyYTIyMDAxMDFkMWEyMDAwMGIwYTAwMjAwMDEwM2QyMDAxMTAzZTBiMGYwMTAxN2YxMDJhMjIwMTIwMDAxMDFjMWEyMDAxMGI1MTAxMDI3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDIyMDAwMTAxMjIyMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIwYzIwMDEyMDAyNDEwYzZhNDEwNDEwYTMwMTIwMDEyMDAwMTBiZDAxMjAwMjQxMTA2YTI0MDAwYjBhMDAyMDAwMTAzZDIwMDExMDQwMGI1MTAxMDI3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDIyMDAwMTAxMjIyMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIwYzIwMDEyMDAyNDEwYzZhNDEwNDEwMGYxYTIwMDEyMDAwMTA4YjAxMjAwMjQxMTA2YTI0MDAwYjA5MDAyMDAwMjAwMTEwMDMwMDBiNTAwMTA0N2YxMDQzMjEwNjEwNDMyMTA3MjMwMDQxMTA2YjIyMDQyNDAwMTA0MzIxMDUyMDAxMTAyZjIxMDEyMDA0MjAwMzEwMjkzNjAyMGMyMDA0MjAwMjM3MDMwMDIwMDQyMDAxMzYwMjA4MjAwNTIwMDQxMDQ0MjAwMDIwMDU0MjAwMjAwNjIwMDcxMDA4MWEyMDA0NDExMDZhMjQwMDBiMTMwMTAxN2YxMDJhMjIwMDQxYjg4ZDA4NDEwMDEwMTgxYTIwMDAwYmQyMDEwMjAyN2YwMTdlMjMwMDQxMTA2YjIyMDMyNDAwMjAwMzIwMDEyODAyMDgyMjAyNDExODc0MjAwMjQxODBmZTAzNzE0MTA4NzQ3MjIwMDI0MTA4NzY0MTgwZmUwMzcxMjAwMjQxMTg3NjcyNzIzNjAyMDAyMDAzMjAwMTI4MDIwYzIyMDI0MTE4NzQyMDAyNDE4MGZlMDM3MTQxMDg3NDcyMjAwMjQxMDg3NjQxODBmZTAzNzEyMDAyNDExODc2NzI3MjM2MDIwYzIwMDMyMDAxMjkwMzAwMjIwNDQyMzg4NjIwMDQ0MjgwZmUwMzgzNDIyODg2ODQyMDA0NDI4MDgwZmMwNzgzNDIxODg2MjAwNDQyODA4MDgwZjgwZjgzNDIwODg2ODQ4NDIwMDQ0MjA4ODg0MjgwODA4MGY4MGY4MzIwMDQ0MjE4ODg0MjgwODBmYzA3ODM4NDIwMDQ0MjI4ODg0MjgwZmUwMzgzMjAwNDQyMzg4ODg0ODQ4NDM3MDIwNDIwMDAyMDAzNDExMDEwMGYxYTIwMDM0MTEwNmEyNDAwMGIxNTAwMjAwMDIwMDEyMDAyMjAwMzIwMDQxMDJhMjIwMTEwMDkxYTIwMDEwYjBjMDEwMTdmMTAyYTIyMDAxMDBhMjAwMDBiMGMwMTAxN2YxMDJhMjIwMDEwMGIyMDAwMGIwYzAxMDE3ZjEwMmEyMjAwMTAwYzIwMDAwYjE1MDAxMDQ4MTA0NjEwMzAwNDQwMGYwYjQxOTI4ZDA4NDEyNDEwMDMwMDBiMmIwMTAxN2Y0MWU4ZGIwODJkMDAwMDIyMDAwNDQwNDE2YjQxZmZmZmZmZmYwNzIwMDAxYjBmMGI0MWU4ZGIwODQxMDEzYTAwMDA0MTZiMTAwZDQxNmIwYjBkMDAyMDAwMTAyYTIyMDAxMDBlMWEyMDAwMGIyZTAxMDE3ZjQxZDU4MzA4NDExNzEwNGQyMjA0MjAwMDIwMDExMDBmMWEyMDA0NDFlYzgzMDg0MTAzMTAwZjFhMjAwNDIwMDIyMDAzMTAwZjFhMjAwNDEwMDAwMDBiMTEwMTAxN2YxMDJhMjIwMjIwMDAyMDAxMTAxODFhMjAwMjBiNDYwMTAxN2YyMzAwNDExMDZiMjIwMjI0MDAyMDAyMjAwMTQxMTg3NDIwMDE0MTgwZmUwMzcxNDEwODc0NzIyMDAxNDEwODc2NDE4MGZlMDM3MTIwMDE0MTE4NzY3MjcyMzYwMjBjMjAwMDIwMDI0MTBjNmE0MTA0MTAwZjFhMjAwMjQxMTA2YTI0MDAwYjBlMDEwMTdmNDEwMDEwMmEyMjAwMTAxMDIwMDAwYjFmMDAyMDAwMTA0YjIyMDAxMDEyNDEyMDQ3MDQ0MDIwMDEyMDAyNDFiMDg2MDg0MTEwMTA0YzAwMGIyMDAwMGJkOTAzMDEwOTdmMjMwMDQxNDA2YTIyMDEyNDAwMjAwMDEwNGIyMTAyMTA0MzIxMDYyMDAyMTAxMjIxMDAyMDAxNDEyNDZhNDEwMDNhMDAwMDIwMDE0MTIwNmEyMDAwMzYwMjAwMjAwMTIwMDIzNjAyMWMyMDAxMjAwMDM2MDIxODIwMDE0MTAwMzYwMjE0NDEwMDIxMDIwMzdmMjAwMDIwMDI0NjA0N2YyMDAxMmQwMDI0MDQ0MDQxZGNkYjA4NDEwMDM2MDIwMDQxZTBkYjA4NDEwMDNhMDAwMDBiMjAwMTQxNDA2YjI0MDAyMDA2MDUyMDAxNDExNDZhMjIwMDQxOTc4NzA4NDExNjEwM2EyMTA0MjAwMDQxOTc4NzA4NDExNjEwNTIyMTAwMTA0MzIxMDMwMzQwMjAwMDA0NDAyMDAxNDExNDZhMjIwNTQxOTc4NzA4NDExNjEwNTIyMTA3MjAwNTQxOTc4NzA4NDExNjEwNTMyMTA4MjAwNTQxOTc4NzA4NDExNjEwM2EyMTA5NDEwMDIxMDIwMjQwMDI0MDAyNDAyMDA1NDE5Nzg3MDg0MTE2MTA1NDQxZmYwMTcxMGUwMjAyMDEwMDBiNDE5Nzg3MDg0MTE2NDFlZDg2MDg0MTBkMTA0YzAwMGI0MTAxMjEwMjBiMjAwMTIwMDIzYTAwMzQyMDAxMjAwOTM2MDIzMDIwMDEyMDA4MzYwMjJjMjAwMTIwMDczNjAyMjgyMDAzMjAwMTQxMjg2YTEwNTUyMDAwNDEwMTZiMjEwMDBjMDEwYjBiMjAwMTQyMDAzNzAzMjgyMDAxMjAwNDQxMTg3NDIwMDQ0MTgwZmUwMzcxNDEwODc0NzIyMDA0NDEwODc2NDE4MGZlMDM3MTIwMDQ0MTE4NzY3MjcyMzYwMjNjMjAwMTQxMDg2YTIwMDE0MTI4NmEyMjAwNDEwMDQxMDQxMDU2MjAwMTI4MDIwODIwMDEyODAyMGMyMDAxNDEzYzZhMjIwMjQxMDQxMDU3MjAwMTIwMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIzYzIwMDEyMDAwNDEwNDQxMDgxMDU2MjAwMTI4MDIwMDIwMDEyODAyMDQyMDAyNDEwNDEwNTcyMDA2MjAwMDQxMDgxMDBmMWEyMDAxMjgwMjE0MjEwMjIwMDEyODAyMTgyMTAwMGMwMTBiMGIwYjM3MDIwMTdmMDE3ZTIzMDA0MTEwNmIyMjAzMjQwMDIwMDM0MTAwMzYwMjBjMjAwMDIwMDM0MTBjNmEyMjAwNDEwNDIwMDEyMDAyMTBjNTAxMjAwMDQxMDQxMGIxMDEyMDAzNDExMDZhMjQwMGE3MGIwZDAwMjAwMDQxMjAyMDAxMjAwMjEwODUwMTBiMzAwMTAxN2YyMzAwNDExMDZiMjIwMzI0MDAyMDAzNDEwMDNhMDAwZjIwMDAyMDAzNDEwZjZhNDEwMTIwMDEyMDAyMTBjNTAxMjAwMzJkMDAwZjIwMDM0MTEwNmEyNDAwMGJmNjAyMDEwNTdmMjMwMDQxZDAwMDZiMjIwMjI0MDAyMDAyNDIwMDM3MDAzNTIwMDI0MjAwMzcwMzMwMjAwMjIwMDEyODAyMDAyMjAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyNDAyMDAyNDEyODZhMjAwMjQxMzA2YTIyMDU0MTAwNDEwNDEwOWIwMTIwMDIyODAyMjgyMDAyMjgwMjJjMjAwMjQxNDA2YjIyMDQ0MTA0MTA1NzIwMDI0MWM4MDA2YTQxMDAzYTAwMDAyMDAyNDIwMDM3MDM0MDIwMDIyMDAxMjgwMjA0MjIwMzQxMTg3NDIwMDM0MTgwZmUwMzcxNDEwODc0NzIyMDAzNDEwODc2NDE4MGZlMDM3MTIwMDM0MTE4NzY3MjcyMzYwMjRjMjAwMjQxMjA2YTIwMDQ0MTAwNDEwNDEwOWMwMTIwMDIyODAyMjAyMDAyMjgwMjI0MjAwMjQxY2MwMDZhMjIwNjQxMDQxMDU3MjAwMjIwMDE0MTA4NmEyODAyMDAyMjAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyNGMyMDAyNDExODZhMjAwNDQxMDQ0MTA4MTA5YzAxMjAwMjI4MDIxODIwMDIyODAyMWMyMDA2NDEwNDEwNTcyMDAyMjAwMTQxMGM2YTJkMDAwMDNhMDA0YzIwMDI0MTEwNmEyMDA0NDEwODQxMDkxMDljMDEyMDAyMjgwMjEwMjAwMjI4MDIxNDIwMDY0MTAxMTA1NzIwMDI0MTA4NmEyMDA1NDEwNDQxMGQxMDliMDEyMDAyMjgwMjA4MjAwMjI4MDIwYzIwMDQ0MTA5MTA1NzIwMDAyMDA1NDEwZDEwMGYxYTIwMDI0MWQwMDA2YTI0MDAwYjBmMDAyMDAwMjAwMTIwMDIyMDAzNDEwODEwZjkwMTBiYjUwMjAxMDY3ZjIwMDEyMDAzNDYwNDQwMjAwMTIyMDM0MTEwNGYwNDQwMjAwMDQxMDAyMDAwNmI0MTAzNzEyMjA0NmEyMTA1MjAwNDA0NDAyMDAyMjEwMTAzNDAyMDAwMjAwMTJkMDAwMDNhMDAwMDIwMDE0MTAxNmEyMTAxMjAwMDQxMDE2YTIyMDAyMDA1NDkwZDAwMGIwYjIwMDUyMDAzMjAwNDZiMjIwMzQxN2M3MTIyMDY2YTIxMDAwMjQwMjAwMjIwMDQ2YTIyMDQ0MTAzNzEwNDQwMjAwNjQxMDA0YzBkMDEyMDA0NDEwMzc0MjIwMTQxMTg3MTIxMDcyMDA0NDE3YzcxMjIwODQxMDQ2YTIxMDI0MTAwMjAwMTZiNDExODcxMjEwOTIwMDgyODAyMDAyMTAxMDM0MDIwMDUyMDAxMjAwNzc2MjAwMjI4MDIwMDIyMDEyMDA5NzQ3MjM2MDIwMDIwMDI0MTA0NmEyMTAyMjAwNTQxMDQ2YTIyMDUyMDAwNDkwZDAwMGIwYzAxMGIyMDA2NDEwMDRjMGQwMDIwMDQyMTAyMDM0MDIwMDUyMDAyMjgwMjAwMzYwMjAwMjAwMjQxMDQ2YTIxMDIyMDA1NDEwNDZhMjIwNTIwMDA0OTBkMDAwYjBiMjAwMzQxMDM3MTIxMDMyMDA0MjAwNjZhMjEwMjBiMjAwMzA0NDAyMDAwMjAwMzZhMjEwMTAzNDAyMDAwMjAwMjJkMDAwMDNhMDAwMDIwMDI0MTAxNmEyMTAyMjAwMDQxMDE2YTIyMDAyMDAxNDkwZDAwMGIwYjBmMGIxMDJjMDAwYmEyMDMwMTA3N2YyMzAwNDE0MDZhMjIwMTI0MDAyMDAwMTA0YjIxMDIxMDQzMjEwNTIwMDIxMDEyMjEwMDIwMDE0MTJjNmE0MTAwM2EwMDAwMjAwMTQxMjg2YTIwMDAzNjAyMDAyMDAxMjAwMjM2MDIyNDIwMDEyMDAwMzYwMjIwMjAwMTQxMDAzNjAyMWM0MTAwMjEwMjAzN2YyMDAwMjAwMjQ2MDQ3ZjIwMDEyZDAwMmMwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAxNDE0MDZiMjQwMDIwMDUwNTIwMDE0MTFjNmEyMjAwNDFhZDg3MDg0MTE4MTAzYTIxMDMyMDAwNDFhZDg3MDg0MTE4MTA1MjIxMDAxMDQzMjEwMjAzNDAyMDAwMDQ0MDIwMDE0MTFjNmEyMjA0NDFhZDg3MDg0MTE4MTA1MjIxMDYyMDA0NDFhZDg3MDg0MTE4MTA1MzIxMDcyMDA0NDFhZDg3MDg0MTE4MTAzYTIxMDQyMDAxMjAwNjM2MDIzODIwMDEyMDA0MzYwMjM0MjAwMTIwMDczNjAyMzAyMDAyMjAwMTQxMzA2YTEwNTkyMDAwNDEwMTZiMjEwMDBjMDEwYjBiMjAwMTQyMDAzNzAzMzAyMDAxMjAwMzQxMTg3NDIwMDM0MTgwZmUwMzcxNDEwODc0NzIyMDAzNDEwODc2NDE4MGZlMDM3MTIwMDM0MTE4NzY3MjcyMzYwMjNjMjAwMTQxMTA2YTIwMDE0MTMwNmEyMjAwNDEwMDQxMDQxMDU2MjAwMTI4MDIxMDIwMDEyODAyMTQyMDAxNDEzYzZhMjIwMzQxMDQxMDU3MjAwMTIwMDI0MTE4NzQyMDAyNDE4MGZlMDM3MTQxMDg3NDcyMjAwMjQxMDg3NjQxODBmZTAzNzEyMDAyNDExODc2NzI3MjM2MDIzYzIwMDE0MTA4NmEyMDAwNDEwNDQxMDgxMDU2MjAwMTI4MDIwODIwMDEyODAyMGMyMDAzNDEwNDEwNTcyMDA1MjAwMDQxMDgxMDBmMWEyMDAxMjgwMjFjMjEwMjIwMDEyODAyMjAyMTAwMGMwMTBiMGIwYmI4MDIwMTA0N2YyMzAwNDE0MDZhMjIwMjI0MDAyMDAyNDEyODZhNDEwMDM2MDIwMDIwMDI0MjAwMzcwMzIwMjAwMjIwMDEyODAyMDgyMjAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyMzAyMDAyNDExODZhMjAwMjQxMjA2YTIyMDU0MTAwNDEwNDEwOWEwMTIwMDIyODAyMTgyMDAyMjgwMjFjMjAwMjQxMzA2YTIyMDQ0MTA0MTA1NzIwMDI0MjAwMzcwMzMwMjAwMjIwMDEyODAyMDAyMjAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyM2MyMDAyNDExMDZhMjAwNDQxMDA0MTA0MTA1NjIwMDIyODAyMTAyMDAyMjgwMjE0MjAwMjQxM2M2YTIyMDM0MTA0MTA1NzIwMDIyMDAxMjgwMjA0MjIwMTQxMTg3NDIwMDE0MTgwZmUwMzcxNDEwODc0NzIyMDAxNDEwODc2NDE4MGZlMDM3MTIwMDE0MTE4NzY3MjcyMzYwMjNjMjAwMjQxMDg2YTIwMDQ0MTA0NDEwODEwNTYyMDAyMjgwMjA4MjAwMjI4MDIwYzIwMDM0MTA0MTA1NzIwMDIyMDA1NDEwNDQxMGMxMDlhMDEyMDAyMjgwMjAwMjAwMjI4MDIwNDIwMDQ0MTA4MTA1NzIwMDAyMDA1NDEwYzEwMGYxYTIwMDI0MTQwNmIyNDAwMGIxNDAwMTAxMzIwMDA0NjA0NDAwZjBiNDE5Mjg0MDg0MTE5MTAwMzAwMGIwOTAwMjAwMDEwNWMxMDA3MWEwYjFkMDAyMDAwMTBhNzAxMjIwMDEwMTI0MTIwNDcwNDQwNDFiMDg2MDg0MTEwMTA4ODAxMDAwYjIwMDAwYjBhMDAyMDAwMTBhNzAxMTAwNzFhMGIwODAwMjAwMDEwNWYxMDE0MGI2MTAyMDI3ZjAxN2UyMzAwNDExMDZiMjIwMTI0MDAyMDAxNDIwMDM3MDMwODIwMDAxMGE3MDEyMjAwMTAxMjIyMDI0MTA5NGYwNDQwNDE5NTg1MDg0MTBlMTA4ODAxMDAwYjIwMDEyMDAxNDEwODZhMjAwMjEwYjAwMTIwMDA0MTAwMjAwMTI4MDIwMDIyMDAyMDAxMjgwMjA0MjIwMjEwOGEwMTFhMjAwMDIwMDIxMGIxMDEyMDAxNDExMDZhMjQwMDBiMWYwMDIwMDAyMDAxMjAwMjEwMTUyMDAwMTA2MTQxZmYwMTcxMDQ0MDBmMGI0MWFiODQwODQxMzAxMDAzMDAwYjE1MDA0MTAyNDEwMTIwMDAxMDI3MjIwMDFiNDEwMDIwMDA0MTAwNGUxYjBiZjgwMTAxMDQ3ZjIzMDA0MWQwMDA2YjIyMDUyNDAwMjAwNTIwMDQzNjAyMjgyMDA1NDEyMDZhNDFkYjg0MDg0MTE0MTA2MzIwMDUyODAyMjAyMTA3MjAwNTI4MDIyNDIyMDYyMDAzMTA2NDIwMDQxMDY1MjEwMzEwNDMyMjA4MjAwM2FkMTA2NjIwMDYyMDA4MTA0ZTIwMDUyMDA0MTAxMjM2MDIzNDIwMDU0MTAwMzYwMjMwMjAwNTIwMDU0MTI4NmEzNjAyMmMwMzQwMjAwNTQxMzg2YTIwMDU0MTJjNmExMDY3MjAwNTI5MDMzODUwMDQ0MDIwMDUyMDA3MjAwNjIwMDEyMDAyMTA2ODIwMDUyODAyMDQyMTAxMjAwMDIwMDUyODAyMDAzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MWQwMDA2YTI0MDAwNTIwMDUyODAyNGMyMTAzMjAwNTQxMTg2YTIwMDcyMDA2MjAwNTI4MDI0ODEwNjkyMDA1NDExMDZhMjAwNTI4MDIxODIwMDUyODAyMWMyMDA1MjkwMzQwMTA2YTIwMDU0MTA4NmEyMDA1MjgwMjEwMjAwNTI4MDIxNDIwMDMxMDZiMjAwNTI4MDIwYzIxMDYyMDA1MjgwMjA4MjEwNzBjMDEwYjBiMGIxODAwMjAwMTIwMDIxMDRkMjEwMTIwMDAxMDQzMzYwMjA0MjAwMDIwMDEzNjAyMDAwYjEwMDAxMDQzMWEyMDAwMjAwMTI4MDIwMDEwMmYxMDRlMGIwOTAwMjAwMDEwMTI0MTA0NzYwYjM4MDEwMTdmMjMwMDQxMTA2YjIyMDIyNDAwMjAwMjQyMDAzNzAzMDgyMDAyMjAwMTQxMDAyMDAyNDEwODZhMTA4MjAxMjAwMDIwMDIyODAyMDAyMDAyMjgwMjA0MTAxODFhMjAwMjQxMTA2YTI0MDAwYmE3MDEwMjA1N2YwMTdlMjMwMDQxMjA2YjIyMDIyNDAwMjAwMDIwMDEyODAyMDQyMjA0NDExMDZhMjIwNTIwMDEyODAyMDg0ZDA0N2UyMDAxMjgwMjAwMjAwMjQxMTA2YTQyMDAzNzAzMDAyMDAyNDIwMDM3MDMwODI4MDIwMDIwMDQyMDAyNDEwODZhMjIwMzQxMTAxMDZmMWEyMDAyNDEwMDM2MDIxYzIwMDMyMDAyNDExYzZhMjIwNjEwOTgwMTIxMDQyMDAzMjAwNjEwOTkwMTIxMDcyMDAwNDExNDZhMjAwMjQxMDg2YTIwMDI0MTFjNmExMDk4MDEzNjAyMDAyMDAwNDExMDZhMjAwNDM2MDIwMDIwMDAyMDA3MzcwMzA4MjAwMTIwMDUzNjAyMDQ0MjAxMDU0MjAwMGIzNzAzMDAyMDAyNDEyMDZhMjQwMDBiOTEwMTAxMDM3ZjIzMDA0MTEwNmIyMjA1MjQwMDAyNDAyMDAzMTAxMjQ1MGQwMDIwMDIyMDAzMTA2ZTIwMDQxMDEyMjEwNjQxMDAyMTAzMDM0MDIwMDM0MTA0NmEyMjA3MjAwNjRiMGQwMTIwMDU0MTAwMzYwMjBjMjAwNDIwMDMyMDA1NDEwYzZhNDEwNDEwNmYxYTIwMDIyMDA1MjgwMjBjMjIwMzQxMTg3NDIwMDM0MTgwZmUwMzcxNDEwODc0NzIyMDAzNDEwODc2NDE4MGZlMDM3MTIwMDM0MTE4NzY3MjcyMTA2ZTIwMDcyMTAzMGMwMDBiMDAwYjIwMDAyMDAyMzYwMjA0MjAwMDIwMDEzNjAyMDAyMDA1NDExMDZhMjQwMDBiMTYwMDIwMDIyMDAzMTA2ZTIwMDAyMDAyMzYwMjA0MjAwMDIwMDEzNjAyMDAwYjIwMDEwMTdmMTA0MzIyMDQyMDAzMTA2NjIwMDIyMDA0MTA0ZTIwMDAyMDAyMzYwMjA0MjAwMDIwMDEzNjAyMDAwYjE2MDAyMDAzMjAwMjEwNzAyMDAwMjAwMjM2MDIwNDIwMDAyMDAxMzYwMjAwMGJhMzAxMDEwMjdmMjMwMDQxMzA2YjIyMDUyNDAwMjAwNTQxMjg2YTQxZWY4NDA4NDEwZjEwNjMyMDA1NDEyMDZhMjAwNTI4MDIyODIwMDUyODAyMmMyMDA0MjgwMjA4MTA2OTIwMDU0MTE4NmEyMDA1MjgwMjIwMjAwNTI4MDIyNDIwMDQyOTAzMDAxMDZhMjAwNTQxMTA2YTIwMDUyODAyMTgyMDA1MjgwMjFjMjAwNDI4MDIwYzEwNmIyMDA1MjgwMjEwMjEwNDIwMDUyODAyMTQyMTA2MTA0MzFhMjAwNjIwMDMxMDJmMTA0ZTIwMDU0MTA4NmEyMDA0MjAwNjIwMDEyMDAyMTA2ODIwMDUyODAyMGMyMTAxMjAwMDIwMDUyODAyMDgzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MTMwNmEyNDAwMGI3MTAxMDE3ZjIzMDA0MTIwNmIyMjA1MjQwMDIwMDU0MTE4NmE0MWZlODQwODQxMGMxMDYzMjAwNTQxMTA2YTIwMDUyODAyMTgyMDA1MjgwMjFjMjAwMzEwNjkyMDA1NDEwODZhMjAwNTI4MDIxMDIwMDUyODAyMTQyMDA0MTA2YjIwMDUyMDA1MjgwMjA4MjAwNTI4MDIwYzIwMDEyMDAyMTA2ODIwMDUyODAyMDQyMTAxMjAwMDIwMDUyODAyMDAzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MTIwNmEyNDAwMGIwZDAwMTA0MzFhMjAwMDIwMDExMDJmMTA0ZTBiMGQwMDIwMDAyMDAxMjAwMjIwMDMxMDhhMDEwYjBkMDAxMDQzMWEyMDAxMjAwMDEwM2QxMDRlMGIwZjAwMjAwMDQyN2Y1MTA0N2UxMDE2MDUyMDAwMGIwYjMwMDEwMTdlMjAwMDI5MDMwODIyMDE0MjdmNTEwNDdlMTAxNjA1MjAwMTBiMjAwMDI4MDIxMDIwMDAyODAyMTgyMDAwMjgwMjAwMjAwMDI4MDIwNDEwNDUxMDE3MTA3MzBiM2IwMTAyN2YyMzAwNDExMDZiMjIwMTI0MDAyMDAwMTAxMjIxMDIyMDAxNDEwMDM2MDIwYzIwMDEyMDAwMzYwMjA0MjAwMTIwMDI0MTAyNzYzNjAyMDgyMDAxNDEwNDZhMTA3NTEwM2IyMDAxNDExMDZhMjQwMDBiMjQwMDIwMDAyOTAzMDgxMDcxMjAwMDI4MDIxMDIwMDAyODAyMTgyMDAwMjgwMjAwMjAwMDI4MDIwNDEwNDUxMDE3MTAxMjFhMGI3ZDAxMDM3ZjIzMDA0MTEwNmIyMjAxMjQwMDIwMDAyODAyMDgyMTAzMjAwMTQxMDAzNjAyMGMyMDAwMjgwMjAwMjAwMzQxMDI3NDIwMDE0MTBjNmE0MTA0MTA2ZjQ1MDQ0MDIwMDEyODAyMGMyMTAyMjAwMDIwMDM0MTAxNmEzNjAyMDgyMDAyNDExODc0MjAwMjQxODBmZTAzNzE0MTA4NzQ3MjIwMDI0MTA4NzY0MTgwZmUwMzcxMjAwMjQxMTg3NjcyNzIxMDJmMjAwMTQxMTA2YTI0MDAwZjBiNDE4YTg1MDg0MTBiNDFlZjgzMDg0MTExMTA0YzAwMGI5MDAyMDIwMjdmMDE3ZTIzMDA0MWQwMDA2YjIyMDIyNDAwMjAwMTI5MDMwODIyMDQ0MjdmNTEwNDdlMTAxNjA1MjAwNDBiMjAwMTI4MDIxMDIwMDEyODAyMTgyMDAxMjgwMjAwMjAwMTI4MDIwNDEwNDUyMTAxMTAxNzIwMDExMDEyMjEwMzIwMDI0MTAwMzYwMjE0MjAwMjIwMDEzNjAyMGMyMDAyMjAwMzQxMDI3NjM2MDIxMDIwMDI0MTBjNmExMDc1MjIwMzEwMTIyMTAxMjAwMjQxM2M2YTQxMDAzYTAwMDAyMDAyNDEzODZhMjAwMTM2MDIwMDIwMDIyMDAzMzYwMjM0MjAwMjIwMDEzNjAyMzAyMDAyNDEwMDM2MDIyYzIwMDI0MTQwNmIyMDAyNDEyYzZhMTA3NzIwMDIyODAyMzAyMDAyMjgwMjJjNDYwNDQwMjAwMjQxMjA2YTIyMDEyMDAyNDFjODAwNmEyOTAzMDAzNzAzMDAyMDAyMjAwMjI5MDM0MDM3MDMxODIwMDIyZDAwM2MwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAwMjAwMjI5MDMxODM3MDMwMDIwMDA0MTA4NmEyMDAxMjkwMzAwMzcwMzAwMjAwMjQxZDAwMDZhMjQwMDBmMGI0MThhODUwODQxMGI0MTk1ODUwODQxMGUxMDRjMDAwYjMwMDIwMTdmMDE3ZTIwMDE0MThhODUwODQxMGIxMDNhMjEwMjIwMDExMGJlMDEyMTAzMjAwMDIwMDExMDM5MzYwMjBjMjAwMDIwMDIzNjAyMDgyMDAwMjAwMzM3MDMwMDBiMTAwMDEwNDMxYTIwMDAyMDAxMjgwMjAwMTAzZDEwNGUwYjBlMDAyMDAxNDUwNDQwMjAwMjIwMDAxMDcwMGIwYjgxMDEwMTA1N2YyMzAwNDExMDZiMjIwMzI0MDAxMDQzMTAyZjIxMDQyMDAxMjgwMjAwMTAxMjIxMDUwMzQwMjAwNTIwMDI0MTA0NmEyMjA2NGYwNDQwMjAwMzQxMDAzNjAyMGMyMDAxMjgwMjAwMjAwMjIwMDM0MTBjNmE0MTA0MTA2ZjFhMjAwMzI4MDIwYzIyMDI0MTE4NzQyMDAyNDE4MGZlMDM3MTQxMDg3NDcyMjAwMjQxMDg3NjQxODBmZTAzNzEyMDAyNDExODc2NzI3MjIwMDQxMDNmMjAwNjIxMDIwYzAxMGIwYjIwMDAyMDA0MTA0ZTIwMDM0MTEwNmEyNDAwMGI4MjAxMDEwNTdmMjMwMDQxMTA2YjIyMDMyNDAwMTA0MzEwMmYyMTA0MjAwMTI4MDIwMDEwMTIyMTA1MDM0MDIwMDUyMDAyNDEwNDZhMjIwNjRmMDQ0MDIwMDM0MTAwMzYwMjBjMjAwMTI4MDIwMDIwMDIyMDAzNDEwYzZhNDEwNDEwNmYxYTIwMDQyMDAzMjgwMjBjMjIwMjQxMTg3NDIwMDI0MTgwZmUwMzcxNDEwODc0NzIyMDAyNDEwODc2NDE4MGZlMDM3MTIwMDI0MTE4NzY3MjcyMTAwNTFhMjAwNjIxMDIwYzAxMGIwYjIwMDAyMDA0MTA0ZTIwMDM0MTEwNmEyNDAwMGI0ZDAxMDI3ZjIzMDA0MTIwNmIyMjAxMjQwMDEwN2QyMTAyMjAwMTQxMTA2YTIwMDA0MTEwNmEyOTAzMDAzNzAzMDAyMDAxNDEwODZhMjAwMDQxMDg2YTI5MDMwMDM3MDMwMDIwMDEyMDAyMzYwMjE4MjAwMTIwMDAyOTAzMDAzNzAzMDAyMDAxMTA3MjIwMDE0MTIwNmEyNDAwMGIwZTAxMDE3ZjEwMmEyMjAwNDIwMDEwMDEyMDAwMGI0ZjAxMDI3ZjIzMDA0MTIwNmIyMjAyMjQwMDEwN2QyMTAzMjAwMjQxMTA2YTIwMDE0MTEwNmEyOTAzMDAzNzAzMDAyMDAyNDEwODZhMjAwMTQxMDg2YTI5MDMwMDM3MDMwMDIwMDIyMDAzMzYwMjE4MjAwMjIwMDEyOTAzMDAzNzAzMDAyMDAwMjAwMjEwNzYyMDAyNDEyMDZhMjQwMDBiNGQwMTAyN2YyMzAwNDEyMDZiMjIwMTI0MDAxMDdkMjEwMjIwMDE0MTEwNmEyMDAwNDExMDZhMjkwMzAwMzcwMzAwMjAwMTQxMDg2YTIwMDA0MTA4NmEyOTAzMDAzNzAzMDAyMDAxMjAwMjM2MDIxODIwMDEyMDAwMjkwMzAwMzcwMzAwMjAwMTEwMzQyMDAxNDEyMDZhMjQwMDBiNzYwMjA1N2YwMTdlMjMwMDQxMTA2YjIyMDEyNDAwMTA3ZDIxMDIyMDAwMjgwMjEwMjEwMzIwMDAyODAyMDQyMTA0MjAwMDI4MDIwMDIxMDUyMDAwMjkwMzA4MjIwNjQyN2Y1MTA0N2UxMDE2MDUyMDA2MGIyMDAzMjAwMjIwMDUyMDA0MTA0NTIxMDAxMDE3MjAwMDEwMTIyMTAyMjAwMTQxMDAzNjAyMGMyMDAxMjAwMDM2MDIwNDIwMDEyMDAyNDEwMjc2MzYwMjA4MjAwMTQxMDQ2YTEwNzUxMDJmMjAwMTQxMTA2YTI0MDAwYjQ3MDEwMjdmMjMwMDQxMTA2YjIyMDIyNDAwMTA0MzIxMDMyMDAyNDIwMDM3MDMwODIwMDIyMDAxYWQ0MmZmMDE4MzQxMDEyMDAyNDEwODZhMTA4MjAxMjAwMzIwMDIyODAyMDAyMDAyMjgwMjA0MTAxODFhMjAwMDIwMDMxMDRlMjAwMjQxMTA2YTI0MDAwYjhmMDIwMjA0N2YwMTdlMjAwMzIwMDE0MjM4ODYyMDAxNDI4MGZlMDM4MzQyMjg4Njg0MjAwMTQyODA4MGZjMDc4MzQyMTg4NjIwMDE0MjgwODA4MGY4MGY4MzQyMDg4Njg0ODQyMDAxNDIwODg4NDI4MDgwODBmODBmODMyMDAxNDIxODg4NDI4MDgwZmMwNzgzODQyMDAxNDIzODg4MjIwODIwMDE0MjI4ODg0MjgwZmUwMzgzODQ4NDg0MzcwMDAwMDI0MDIwMDE1MDA0NDA0MWI4OGQwODIxMDMwYzAxMGIyMDAyMDQ0MDIwMDE0MjdmNTEwNDQwMjAwMzQxMDc2YTIxMDM0MTAxMjEwNDBjMDIwYjIwMDhhN2MwMjIwNTQxMDc3NTIxMDYyMDA1NDEwMDQ4MjEwNTBiMjAwNjQxZmYwMTcxMjEwNjAzNDAwMjQwMDI0MDIwMDQ0MTA4NDcwNDQwMjAwMzIwMDQ2YTJkMDAwMDIyMDcyMDA2NDYwZDAyMjAwMjQ1MjAwNzQxMDc3NjIwMDU0NjcyNDUwNDQwMjAwNDQxMDE2YjIyMDQ0MTA5NGYwZDAyMGIyMDAzMjAwNDZhMjEwMzQxMDgyMDA0NmIyMTA0MGMwNDBiMTAyYzAwMGIxMDJjMDAwYjIwMDQ0MTAxNmEyMTA0MGMwMDBiMDAwYjIwMDAyMDA0MzYwMjA0MjAwMDIwMDMzNjAyMDAwYmEzMDEwMjAzN2YwMTdlMjMwMDQxMTA2YjIyMDMyNDAwMDI3ZjIwMDIyOTAzMDA1MDA0NDAyMDAxMjgwMjEwMjEwNDIwMDMyMDAxMjgwMjAwMjAwMTI4MDIwNDIwMDIyODAyMDgyMDAyMjgwMjBjMTA2ZDIwMDMyODAyMDAyMTA1MjAwMzI4MDIwNDBjMDEwYjEwNDcyMTA0MjAwMzQxMDg2YTIwMDEyODAyMDAyMDAxMjgwMjA0MjAwMTI4MDIxMDIwMDIxMDZjMjAwMzI4MDIwODIxMDUyMDAzMjgwMjBjMGIyMTAyMjAwMTI5MDMwODIxMDYyMDAwMTA3ZDM2MDIxODIwMDAyMDA0MzYwMjEwMjAwMDIwMDYzNzAzMDgyMDAwMjAwMjM2MDIwNDIwMDAyMDA1MzYwMjAwMjAwMzQxMTA2YTI0MDAwYjNmMDEwMTdmMTA0MzIxMDMyMDAwMjAwMTI5MDMwMDM3MDMwMDIwMDA0MTEwNmEyMDAxNDExMDZhMjkwMzAwMzcwMzAwMjAwMDQxMDg2YTIwMDE0MTA4NmEyOTAzMDAzNzAzMDAyMDAzMjAwMjEwNDQyMDAwMjAwMzM2MDIxODBiNTIwMTAyN2YyMzAwNDExMDZiMjIwNDI0MDAyMDA0NDEwODZhMjAwMDI4MDIwODIwMDAyODAyMDAyMjA1MjAwMTEwODYwMTIwMDQyODAyMDg0MTAxNDYwNDQwMjAwNDI4MDIwYzIwMDAyMDAxMjAwNTZhMzYwMjAwMjAwNDQxMTA2YTI0MDAwZjBiMjAwMjIwMDM0MWEzODUwODQxMGYxMDRjMDAwYjFmMDAyMDAxMjAwMjIwMDMxMDA0MjIwMTEwMWYyMTAyMjAwMDIwMDEzNjAyMDQyMDAwMjAwMjQ1MzYwMjAwMGI0ZjAxMDM3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDI0MTA4NmEyMDAwMjgwMjA4MjAwMDI4MDIwMDIyMDMyMDAxMTA4NjAxMjAwMjI4MDIwODQxMDE0NjA0NDAyMDAyMjgwMjBjMjAwMDIwMDEyMDAzNmEzNjAyMDAyMDAyNDExMDZhMjQwMDBmMGI0MWEzODUwODQxMGYxMDg4MDEwMDBiMWEwMTAxN2Y0MWYxODUwODQxMTYxMDRkMjIwMjIwMDAyMDAxMTAwZjFhMjAwMjEwMDAwMDBiMTUwMDQxN2YyMDAwMjAwMTEwMTkyMjAwNDEwMDQ3MjAwMDQxMDA0ODFiMGIwZjAwMjAwMDIwMDEyMDAzMjAwMjEwMjg0MTAwNDcwYjA5MDAyMDAwMjAwMTEwMDUxYTBiMGMwMDIwMDAyMDAwMjAwMTEwMDIyMDAwMGIwYzAwMjAwMDIwMDAyMDAxMTAxYTIwMDAwYjBjMDAyMDAwMjAwMDIwMDExMDFiMjAwMDBiMGEwMDIwMDAyMDAwMjAwMTEwMDIwYjBjMDAyMDAwMjAwMDIwMDExMDYwMjAwMDBiMTAwMTAxN2YxMDJhMjIwMjIwMDAyMDAxMTAwMjIwMDIwYjEwMDEwMTdmMTAyYTIyMDIyMDAwMjAwMTEwMWIyMDAyMGIxMDAxMDE3ZjEwMmEyMjAyMjAwMDIwMDExMDYwMjAwMjBiMTkwMTAxN2YxMDJhMjEwMjQxNzIyMDAxYWQxMDAxMjAwMjIwMDA0MTcyMTAxZTIwMDIwYjBlMDEwMTdmMTA0MzIyMDEyMDAwMTA0NDIwMDEwYjRjMDEwMjdmMjMwMDQxMTA2YjIyMDEyNDAwMTA0MzIxMDIyMDAxMjAwMDQxMTg3NDIwMDA0MTgwZmUwMzcxNDEwODc0NzIyMDAwNDEwODc2NDE4MGZlMDM3MTIwMDA0MTE4NzY3MjcyMzYwMjBjMjAwMjIwMDE0MTBjNmE0MTA0MTAwZjFhMjAwMTQxMTA2YTI0MDAyMDAyMGI4NDAxMDIwNDdmMDE3ZTIzMDA0MTIwNmIyMjAyMjQwMDIwMDI0MTEwNmE0MjAwMzcwMzAwMjAwMjQyMDAzNzAzMDgyMDAxNDEwMDIwMDI0MTA4NmEyMjAzNDExMDEwNmYyMDAyNDEwMDM2MDIxYzIwMDMyMDAyNDExYzZhMjIwNDEwOTgwMTIxMDUyMDAzMjAwNDEwOTkwMTIxMDYyMDAyNDEwODZhMjAwMjQxMWM2YTEwOTgwMTIxMDMwNDQwNDFjMzg1MDg0MTFkMTAwMzAwMGIyMDAwMjAwMzM2MDIwYzIwMDAyMDA1MzYwMjA4MjAwMDIwMDYzNzAzMDAyMDAyNDEyMDZhMjQwMDBiNzQwMTAxN2YyMzAwNDExMDZiMjIwMjI0MDAyMDAyNDEwMDM2MDIwYzIwMDIyMDAwNDExMDIwMDEyODAyMDAyMjAwMjAwMDQxMDQ2YTIyMDAxMDlkMDEyMDAyNDEwYzZhNDEwNDIwMDIyODAyMDAyMDAyMjgwMjA0MTA1NzIwMDEyMDAwMzYwMjAwMjAwMjI4MDIwYzIxMDAyMDAyNDExMDZhMjQwMDIwMDA0MTE4NzQyMDAwNDE4MGZlMDM3MTQxMDg3NDcyMjAwMDQxMDg3NjQxODBmZTAzNzEyMDAwNDExODc2NzI3MjBiYTgwMTAyMDE3ZTAxN2YyMzAwNDExMDZiMjIwMzI0MDAyMDAzNDIwMDM3MDMwODIwMDMyMDAwNDExMDIwMDEyODAyMDAyMjAwMjAwMDQxMDg2YTIyMDAxMDlkMDEyMDAzNDEwODZhNDEwODIwMDMyODAyMDAyMDAzMjgwMjA0MTA1NzIwMDEyMDAwMzYwMjAwMjAwMzI5MDMwODIxMDIyMDAzNDExMDZhMjQwMDIwMDI0MjM4ODYyMDAyNDI4MGZlMDM4MzQyMjg4Njg0MjAwMjQyODA4MGZjMDc4MzQyMTg4NjIwMDI0MjgwODA4MGY4MGY4MzQyMDg4Njg0ODQyMDAyNDIwODg4NDI4MDgwODBmODBmODMyMDAyNDIxODg4NDI4MDgwZmMwNzgzODQyMDAyNDIyODg4NDI4MGZlMDM4MzIwMDI0MjM4ODg4NDg0ODQwYjBmMDAyMDAwMjAwMTIwMDIyMDAzNDEwYzEwZjkwMTBiMGYwMDIwMDAyMDAxMjAwMjIwMDM0MTBkMTBmOTAxMGIwZjAwMjAwMDIwMDEyMDAyMjAwMzQxMDkxMGY5MDEwYjJmMDAwMjQwMjAwMzIwMDQ0ZDA0NDAyMDAyMjAwNDQ5MGQwMTIwMDAyMDA0MjAwMzZiMzYwMjA0MjAwMDIwMDEyMDAzNmEzNjAyMDAwZjBiMTAyYzAwMGIxMDJjMDAwYmI0MDEwMTAzN2YyMzAwNDExMDZiMjIwNDI0MDAwMjdmMDI0MDIwMDAyZDAwMDg0NTA0NDAyMDAwMjgwMjAwMjIwNTEwMTIyMjA2NDE5MGNlMDA0YjBkMDE0MWUwZGIwODJkMDAwMDBkMDE0MWRjZGIwODIwMDYzNjAyMDA0MWUwZGIwODQxMDEzYTAwMDAyMDA0NDEwODZhMjAwNjEwOWYwMTIwMDU0MTAwMjAwNDI4MDIwODIwMDQyODAyMGMxMDZmMWEyMDAwNDEwMTNhMDAwODBiNDEwMTIwMDEyMDAzNmEyMjAwNDFkY2RiMDgyODAyMDA0YjBkMDExYTIwMDQyMDAxMjAwMDEwYTAwMTIwMDIyMDAzMjAwNDI4MDIwMDIwMDQyODAyMDQxMDU3NDEwMDBjMDEwYjIwMDA0MTAwM2EwMDA4MjAwNTIwMDEyMDAyMjAwMzEwNmYwYjIwMDQ0MTEwNmEyNDAwMGIzZTAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDI0MTA4NmE0MWNjOGQwODQxOTBjZTAwMjAwMTEwZDAwMTIwMDIyODAyMGMyMTAxMjAwMDIwMDIyODAyMDgzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDI0MTEwNmEyNDAwMGIzMjAwMDI0MDIwMDEyMDAyNGQwNDQwMjAwMjQxOTBjZTAwNGQwZDAxMTAyYzAwMGIxMDJjMDAwYjIwMDAyMDAyMjAwMTZiMzYwMjA0MjAwMDIwMDE0MWNjOGQwODZhMzYwMjAwMGIxOTAwMjAwMDQxZmVmZmZmZmYwNzQ2MDQ0MDQxZTA4NTA4NDEwZDEwMDMwMDBiMjAwMDBiNGQwMTAxN2YyMzAwNDExMDZiMjIwMTI0MDAyMDAwMTAxMjQxMDQ0NjA0NDAyMDAxNDEwMDM2MDIwYzIwMDA0MTAwMjAwMTQxMGM2YTQxMDQxMDhhMDExYTQxZmVmZmZmZmYwNzIwMDAyMDAxMjgwMjBjNDFjNThlYjFhMjA0NDYxYjIxMDAwYjIwMDE0MTEwNmEyNDAwMjAwMDBiODAwMTAxMDI3ZjIzMDA0MTEwNmIyMjAzMjQwMDAyNDAwMjQwMjAwMDJkMDAwNDA0NDA0MTkwY2UwMDQxZGNkYjA4MjgwMjAwMjIwNDZiMjAwMjQ5MGQwMTIwMDM0MTA4NmEyMDA0MjAwMjIwMDQ2YTIyMDAxMGE0MDEyMDAzMjgwMjA4MjAwMzI4MDIwYzIwMDEyMDAyMTA1NzQxZGNkYjA4MjAwMDM2MDIwMDBjMDIwYjIwMDAyODAyMDAyMDAxMjAwMjEwMGYxYTBjMDEwYjIwMDAxMGE1MDEyMDAwMjgwMjAwMjAwMTIwMDIxMDBmMWEwYjIwMDM0MTEwNmEyNDAwMGIzZjAxMDE3ZjIzMDA0MTEwNmIyMjAzMjQwMDIwMDM0MTA4NmEyMDAxMjAwMjQxY2M4ZDA4NDE5MGNlMDAxMDJiMjAwMzI4MDIwYzIxMDEyMDAwMjAwMzI4MDIwODM2MDIwMDIwMDAyMDAxMzYwMjA0MjAwMzQxMTA2YTI0MDAwYjU4MDEwMjdmMjMwMDQxMTA2YjIyMDEyNDAwMjAwMDJkMDAwNDIwMDA0MTAwM2EwMDA0MDQ0MDIwMDE0MTA4NmE0MTAwNDFkY2RiMDgyODAyMDAxMGEwMDEyMDAwMjgwMjAwMjAwMTI4MDIwODIwMDEyODAyMGMxMDBmMWE0MWRjZGIwODQxMDAzNjAyMDA0MWUwZGIwODQxMDAzYTAwMDAwYjIwMDE0MTEwNmEyNDAwMGIwZDAwMjAwMDQxNjcxMDIwMWE0MTY3MTAxMjBiMGQwMDIwMDAxMDJhMjIwMDEwMjAxYTIwMDAwYjEyMDAyMDAwMTBhNjAxNDUwNDQwMjAwMDIwMDExMDIxMWEwYjBiMTIwMDIwMDAxMGE2MDE0NTA0NDAyMDAwMjAwMTEwYWEwMTBiMGIzODAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDI0MjAwMzcwMzA4MjAwMjIwMDE0MTAwMjAwMjQxMDg2YTEwODIwMTIwMDAyMDAyMjgwMjAwMjAwMjI4MDIwNDEwYjgwMTIwMDI0MTEwNmEyNDAwMGIwYTAwMjAwMDEwYTcwMTEwYTIwMTBiYjkwMTAxMDQ3ZjIzMDA0MTIwNmIyMjAxMjQwMDIwMDAxMGE3MDEyMTAyMTA0MzIxMDQyMDAyMTAxMjIxMDAyMDAxNDExMDZhNDEwMDNhMDAwMDIwMDE0MTBjNmEyMDAwMzYwMjAwMjAwMTIwMDIzNjAyMDgyMDAxMjAwMDM2MDIwNDIwMDE0MTAwMzYwMjAwMDM3ZjIwMDAyMDAzNDYwNDdmMjAwMTJkMDAxMDA0NDA0MWRjZGIwODQxMDAzNjAyMDA0MWUwZGIwODQxMDAzYTAwMDAwYjIwMDE0MTIwNmEyNDAwMjAwNDA1MjAwMTEwYWQwMTIxMDAyMDAxMTBhZTAxMjEwMjIwMDExMGFmMDEyMTAzMjAwMTIwMDAzNjAyMWMyMDAxMjAwMzM2MDIxODIwMDEyMDAyMzYwMjE0MjAwNDIwMDE0MTE0NmExMDU5MjAwMTI4MDIwMDIxMDMyMDAxMjgwMjA0MjEwMDBjMDEwYjBiMGIzMzAyMDE3ZjAxN2UyMzAwNDExMDZiMjIwMTI0MDAyMDAxNDEwMDM2MDIwYzIwMDAyMDAxNDEwYzZhMjIwMDQxMDQxMGIzMDEyMDAwNDEwNDEwYjEwMTIwMDE0MTEwNmEyNDAwYTcwYjA5MDAyMDAwNDEyMDEwODcwMTBiMGMwMDIwMDAyMDAwMTBhZDAxMTA4NzAxMGIzYTAxMDE3ZjIzMDA0MTEwNmIyMjAzMjQwMDIwMDM0MTA4NmEyMDAxNDEwODIwMDIxMGQwMDEyMDAzMjgwMjBjMjEwMTIwMDAyMDAzMjgwMjA4MzYwMjAwMjAwMDIwMDEzNjAyMDQyMDAzNDExMDZhMjQwMDBiMzQwMTAxN2UwMjQwMjAwMTQ1MGQwMDAzNDAyMDAxNDUwZDAxMjAwMTQxMDE2YjIxMDEyMDAwMzEwMDAwMjAwMjQyMDg4Njg0MjEwMjIwMDA0MTAxNmEyMTAwMGMwMDBiMDAwYjIwMDIwYmZkMDEwMTA2N2YyMzAwNDEzMDZiMjIwMTI0MDAyMDAwMTBhNzAxMjEwMjEwNDMyMTA0MjAwMjEwMTIyMTAwMjAwMTQxMTg2YTQxMDAzYTAwMDAyMDAxNDExNDZhMjAwMDM2MDIwMDIwMDEyMDAyMzYwMjEwMjAwMTIwMDAzNjAyMGMyMDAxNDEwMDM2MDIwODAzN2YyMDAwMjAwMzQ2MDQ3ZjIwMDEyZDAwMTgwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAxNDEzMDZhMjQwMDIwMDQwNTIwMDE0MTA4NmEyMjAyMTBhZDAxMjEwMzIwMDIxMGFlMDEyMTA1MjAwMjEwYWYwMTIxMDY0MTAwMjEwMDIwMDE0MTAwM2EwMDJmMjAwMjIwMDE0MTJmNmE0MTAxMTBiMzAxMDI0MDAyNDAwMjQwMjAwMTJkMDAyZjBlMDIwMjAxMDAwYjQxZWQ4NjA4NDEwZDEwODgwMTAwMGI0MTAxMjEwMDBiMjAwMTIwMDAzYTAwMjgyMDAxMjAwNjM2MDIyNDIwMDEyMDA1MzYwMjIwMjAwMTIwMDMzNjAyMWMyMDA0MjAwMTQxMWM2YTEwNTUyMDAxMjgwMjA4MjEwMzIwMDEyODAyMGMyMTAwMGMwMTBiMGIwYjJkMDAyMDAwNDEwODZhMjAwMDI4MDIwMDIwMDEyMDAyMTA5ZTAxMDQ0MDQxYTM4NTA4NDEwZjEwODgwMTAwMGIyMDAwMjAwMDI4MDIwMDIwMDI2YTM2MDIwMDBiODcwMTAxMDE3ZjIzMDA0MTMwNmIyMjAyMjQwMDIwMDIyMDAxMzYwMjA4MjAwMjEwMzUyMDAyMjAwMjJkMDAwNDNhMDAxMDIwMDIyMDAyMjgwMjAwMzYwMjBjMjAwMjIwMDExMDEyMzYwMjFjMjAwMjQxMDAzNjAyMTgyMDAyMjAwMjQxMDg2YTM2MDIxNDAzNDAyMDAyNDEyMDZhMjAwMjQxMTQ2YTEwYjUwMTIwMDIyZDAwMmM0MTAyNDY0NTA0NDAyMDAyNDEyMDZhMjAwMjQxMGM2YTEwYjYwMTBjMDEwYjBiMjAwMDIwMDIyODAyMGMyMDAyMmQwMDEwMTBiNzAxMjAwMjQxMzA2YTI0MDAwYmM1MDMwMTA3N2YyMzAwNDFkMDAwNmIyMjAyMjQwMDAyNDAyMDAxMjgwMjA0MjIwNDQxMGQ2YTIyMDgyMDAxMjgwMjA4NGQwNDQwMjAwMTI4MDIwMDIwMDI0MjAwMzcwMDM1MjAwMjQyMDAzNzAzMzAyODAyMDAyMDA0MjAwMjQxMzA2YTIyMDM0MTBkMTA2ZjFhMjAwMjQxMDAzNjAyNDAyMDAyNDEyODZhMjAwMzQxMDA0MTA0MTBiZjAxMjAwMjQxNDA2YjIyMDU0MTA0MjAwMjI4MDIyODIwMDIyODAyMmMxMDU3MjAwMjI4MDI0MDIxMDQyMDAyNDFjODAwNmE0MTAwM2EwMDAwMjAwMjQyMDAzNzAzNDAyMDAyNDEyMDZhMjAwMzQxMDQ0MTBkMTBiZjAxMjAwNTQxMDkyMDAyMjgwMjIwMjAwMjI4MDIyNDEwNTcyMDAyNDEwMDM2MDI0YzIwMDI0MTE4NmEyMDA1NDEwMDQxMDQxMGMwMDEyMDAyNDFjYzAwNmEyMjA3NDEwNDIwMDIyODAyMTgyMDAyMjgwMjFjMTA1NzIwMDIyODAyNGMyMTAzMjAwMjQxMDAzNjAyNGMyMDAyNDExMDZhMjAwNTQxMDQ0MTA4MTBjMDAxMjAwNzQxMDQyMDAyMjgwMjEwMjAwMjI4MDIxNDEwNTcyMDAyMjgwMjRjMjEwNjIwMDI0MTAwM2EwMDRjMjAwMjQxMDg2YTIwMDU0MTA4NDEwOTEwYzAwMTIwMDc0MTAxMjAwMjI4MDIwODIwMDIyODAyMGMxMDU3MjAwMDIwMDIyZDAwNGM0MTAwNDczYTAwMGMyMDAwMjAwNjQxMTg3NDIwMDY0MTgwZmUwMzcxNDEwODc0NzIyMDA2NDEwODc2NDE4MGZlMDM3MTIwMDY0MTE4NzY3MjcyMzYwMjA4MjAwMDIwMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIwNDIwMDAyMDA0NDExODc0MjAwNDQxODBmZTAzNzE0MTA4NzQ3MjIwMDQ0MTA4NzY0MTgwZmUwMzcxMjAwNDQxMTg3NjcyNzIzNjAyMDAyMDAxMjAwODM2MDIwNDBjMDEwYjIwMDA0MTAyM2EwMDBjMGIyMDAyNDFkMDAwNmEyNDAwMGI0ZDAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDAyODAyMDAyMDAxMTBiYzAxMjAwMTIwMDAyODAyMDQxMGJkMDEyMDAwNDEwODZhMjgwMjAwMjAwMTEwM2UyMDAyMjAwMDQxMGM2YTJkMDAwMDNhMDAwZjIwMDEyMDAyNDEwZjZhNDEwMTEwYTMwMTIwMDI0MTEwNmEyNDAwMGIwZDAwMjAwMDIwMDEyMDAyMTAzODEwMjExYTBiMGQwMDIwMDAyMDAxMjAwMjEwNGQxMDIxMWEwYjg3MDEwMTAxN2YyMzAwNDEzMDZiMjIwMjI0MDAyMDAyMjAwMTM2MDIwODIwMDIxMDM1MjAwMjIwMDIyZDAwMDQzYTAwMTAyMDAyMjAwMjI4MDIwMDM2MDIwYzIwMDIyMDAxMTAxMjM2MDIxYzIwMDI0MTAwMzYwMjE4MjAwMjIwMDI0MTA4NmEzNjAyMTQyMDAyNDEyNDZhMjEwMTAzNDAyMDAyNDEyMDZhMjAwMjQxMTQ2YTEwYmEwMTIwMDIyODAyMjAwNDQwMjAwMTIwMDI0MTBjNmExMGJiMDEwYzAxMGIwYjIwMDAyMDAyMjgwMjBjMjAwMjJkMDAxMDEwYjcwMTIwMDI0MTMwNmEyNDAwMGI4OTAzMDEwNjdmMjMwMDQxNDA2YTIyMDIyNDAwMjAwMDIwMDEyODAyMDQyMjAzNDEwYzZhMjIwNjIwMDEyODAyMDg0ZDA0N2YyMDAxMjgwMjAwMjAwMjQxMjg2YTQxMDAzNjAyMDAyMDAyNDIwMDM3MDMyMDI4MDIwMDIwMDMyMDAyNDEyMDZhMjIwMzQxMGMxMDZmMWEyMDAyNDEwMDM2MDIzMDIwMDI0MTE4NmEyMDAzNDEwMDQxMDQxMGMxMDEyMDAyNDEzMDZhMjIwNTQxMDQyMDAyMjgwMjE4MjAwMjI4MDIxYzEwNTcyMDAyMjgwMjMwMjEwNDIwMDI0MjAwMzcwMzMwMjAwMjQxMTA2YTIwMDM0MTA0NDEwYzEwYzEwMTIwMDU0MTA4MjAwMjI4MDIxMDIwMDIyODAyMTQxMDU3MjAwMjQxMDAzNjAyM2MyMDAyNDEwODZhMjAwNTQxMDA0MTA0MTBjMjAxMjAwMjQxM2M2YTIyMDc0MTA0MjAwMjI4MDIwODIwMDIyODAyMGMxMDU3MjAwMjI4MDIzYzIxMDMyMDAyNDEwMDM2MDIzYzIwMDIyMDA1NDEwNDQxMDgxMGMyMDEyMDA3NDEwNDIwMDIyODAyMDAyMDAyMjgwMjA0MTA1NzIwMDIyODAyM2MyMTA1MjAwMDQxMGM2YTIwMDQ0MTE4NzQyMDA0NDE4MGZlMDM3MTQxMDg3NDcyMjAwNDQxMDg3NjQxODBmZTAzNzEyMDA0NDExODc2NzI3MjM2MDIwMDIwMDAyMDAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyMDQyMDAxMjAwNjM2MDIwNDIwMDA0MTA4NmEyMDA1NDExODc0MjAwNTQxODBmZTAzNzE0MTA4NzQ3MjIwMDU0MTA4NzY0MTgwZmUwMzcxMjAwNTQxMTg3NjcyNzIzNjAyMDA0MTAxMDU0MTAwMGIzNjAyMDAyMDAyNDE0MDZiMjQwMDBiMWYwMDIwMDAyODAyMDgyMDAxMTBiYzAxMjAwMTIwMDAyODAyMDAxMGJkMDEyMDAwMjgwMjA0MjAwMTEwM2UwYjQ2MDEwMTdmMjMwMDQxMTA2YjIyMDIyNDAwMjAwMjIwMDA0MTE4NzQyMDAwNDE4MGZlMDM3MTQxMDg3NDcyMjAwMDQxMDg3NjQxODBmZTAzNzEyMDAwNDExODc2NzI3MjM2MDIwYzIwMDEyMDAyNDEwYzZhNDEwNDEwYTMwMTIwMDI0MTEwNmEyNDAwMGI4MTAxMDEwMzdmMjMwMDQxMTA2YjIyMDIyNDAwMDI0MDAyNDAyMDAwMmQwMDA0MDQ0MDIwMDExMDEyMjIwNDQxOTBjZTAwNDFkY2RiMDgyODAyMDAyMjAzNmI0YjBkMDEyMDAyNDEwODZhMjAwMzIwMDMyMDA0NmEyMjAwMTBhNDAxMjAwMTQxMDAyMDAyMjgwMjA4MjAwMjI4MDIwYzEwNmYxYTQxZGNkYjA4MjAwMDM2MDIwMDBjMDIwYjIwMDAyODAyMDAyMDAxMTA4YjAxMGMwMTBiMjAwMDEwYTUwMTIwMDAyODAyMDAyMDAxMTA4YjAxMGIyMDAyNDExMDZhMjQwMDBiMzgwMjAxN2YwMTdlMjMwMDQxMTA2YjIyMDEyNDAwMjAwMTQyMDAzNzAzMDgyMDAwMjAwMTQxMDg2YTIyMDA0MTA4NDE4YTg1MDg0MTBiMTBjNTAxMjAwMDQxMDgxMGIxMDEyMDAxNDExMDZhMjQwMDBiMGYwMDIwMDAyMDAxMjAwMjIwMDM0MTBkMTBmODAxMGIwZjAwMjAwMDIwMDEyMDAyMjAwMzQxMDkxMGY4MDEwYjBmMDAyMDAwMjAwMTIwMDIyMDAzNDEwYzEwZjgwMTBiMGYwMDIwMDAyMDAxMjAwMjIwMDM0MTA4MTBmODAxMGI4MDAyMDEwNTdmMjMwMDQxMjA2YjIyMDIyNDAwMjAwMDIwMDEyODAyMDQyMjAzNDEwODZhMjIwNTIwMDEyODAyMDg0ZDA0N2YyMDAxMjgwMjAwMjAwMjQyMDAzNzAzMTAyODAyMDAyMDAzMjAwMjQxMTA2YTIyMDM0MTA4MTA2ZjFhMjAwMjQxMDAzNjAyMWMyMDAyNDEwODZhMjAwMzQxMDA0MTA0MTBjMjAxMjAwMjQxMWM2YTIyMDY0MTA0MjAwMjI4MDIwODIwMDIyODAyMGMxMDU3MjAwMjI4MDIxYzIxMDQyMDAyNDEwMDM2MDIxYzIwMDIyMDAzNDEwNDQxMDgxMGMyMDEyMDA2NDEwNDIwMDIyODAyMDAyMDAyMjgwMjA0MTA1NzIwMDIyODAyMWMyMTAzMjAwMDIwMDQ0MTE4NzQyMDA0NDE4MGZlMDM3MTQxMDg3NDcyMjAwNDQxMDg3NjQxODBmZTAzNzEyMDA0NDExODc2NzI3MjM2MDIwNDIwMDEyMDA1MzYwMjA0MjAwMDQxMDg2YTIwMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIwMDQxMDEwNTQxMDAwYjM2MDIwMDIwMDI0MTIwNmEyNDAwMGI4YTAxMDEwNDdmMjMwMDQxMTA2YjIyMDMyNDAwMjAwMTI4MDIwNDIyMDI0MTA0NmEyMjA0MjAwMTI4MDIwODRiMDQ3ZjQxMDAwNTIwMDEyODAyMDAyMDAzNDEwMDM2MDIwYzI4MDIwMDIwMDIyMDAzNDEwYzZhNDEwNDEwNmYxYTIwMDMyODAyMGMyMTAyMjAwMTIwMDQzNjAyMDQyMDAyNDExODc0MjAwMjQxODBmZTAzNzE0MTA4NzQ3MjIwMDI0MTA4NzY0MTgwZmUwMzcxMjAwMjQxMTg3NjcyNzIyMTAyNDEwMTBiMjEwMTIwMDAyMDAyMzYwMjA0MjAwMDIwMDEzNjAyMDAyMDAzNDExMDZhMjQwMDBiMzAwMDIwMDA0MTA4NmEyMDAwMjgwMjAwMjAwMTIwMDIxMDllMDEwNDQwMjAwMzIwMDQ0MWEzODUwODQxMGYxMDRjMDAwYjIwMDAyMDAwMjgwMjAwMjAwMjZhMzYwMjAwMGI3ODAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDIyMDAwNDIzODg2MjAwMDQyODBmZTAzODM0MjI4ODY4NDIwMDA0MjgwODBmYzA3ODM0MjE4ODYyMDAwNDI4MDgwODBmODBmODM0MjA4ODY4NDg0MjAwMDQyMDg4ODQyODA4MDgwZjgwZjgzMjAwMDQyMTg4ODQyODA4MGZjMDc4Mzg0MjAwMDQyMjg4ODQyODBmZTAzODMyMDAwNDIzODg4ODQ4NDg0MzcwMzA4MjAwMTIwMDI0MTA4NmE0MTA4MTBhMzAxMjAwMjQxMTA2YTI0MDAwYmQ2MDEwMTA2N2YyMzAwNDE0MDZhMjIwMDI0MDAxMGM4MDExMDVjMjEwMTIwMDAxMGM5MDExMDVjMzYwMjA4MjAwMDEwNDczNjAyMGMyMDAwNDEyODZhMjIwMjIwMDExMDMyNDFmNzgwMDg0MTEwMTAzMzIwMDAyODAyMmMyMjAxMjAwMDQxMDg2YTEwNjQyMDAxMjAwMDQxMGM2YTEwNjQyMDAwNDEyMDZhMjIwMTIwMDA0MTM4NmEyMjAzMjkwMzAwMzcwMzAwMjAwMDQxMTg2YTIyMDQyMDAwNDEzMDZhMjIwNTI5MDMwMDM3MDMwMDIwMDAyMDAwMjkwMzI4MzcwMzEwMjAwMDIwMDA0MTEwNmExMDdjMzYwMjA0MjAwMjEwYzkwMTEwNWMxMDMyNDFmNTgxMDg0MTE4MTAzMzIwMDAyODAyMmMyMDAwNDEwNDZhMTA3ODIwMDEyMDAzMjkwMzAwMzcwMzAwMjAwNDIwMDUyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDMyODM3MDMxMDIwMDA0MTEwNmExMDdjMjAwMDQxNDA2YjI0MDAwYjBhMDA0MTk1ODgwODQxMTIxMDRkMGIwYTAwNDE4MTg4MDg0MTE0MTA0ZDBiYTkwMzAyMDU3ZjAxN2UyMzAwNDE4MDAxNmIyMjAyMjQwMDEwY2IwMTEwYWIwMTIxMDMyMDAxMjgwMjBjMjEwNDIwMDEyOTAzMDAyMTA3MjAwMTI4MDIwODIxMDEwMjQwMjAwMzQxZmVmZmZmZmYwNzQ2MDQ0MDIwMDE0MWZlZmZmZmZmMDc0NjBkMDEyMDAxMTBhMTAxMjEwMTIwMDIyMDA0MzYwMjE0MjAwMjIwMDczNzAzMDgyMDAyMjAwMTM2MDIxMDEwY2MwMTEwNWMyMTAzMjAwNDEwMjkyMTA0MjAwMjQxZTAwMDZhMjIwMTIwMDMxMDMyNDFhMTgwMDg0MTBhMTAzMzIwMDI0MTQwNmIyMjAzMjAwMTIwMDI0MTA4NmExMDg0MDEyMDAxMjAwMzEwY2QwMTIwMDExMDM0NDIwMDIxMDc0MWZlZmZmZmZmMDcyMTAxMGIyMDAyNDFlMDAwNmEyMDAwMTAzMjQxYzA4MTA4NDExMjEwMzMyMDAyMjgwMjY0MWEyMDAyNDEyODZhMjIwMDIwMDI0MWYwMDA2YTIyMDUyOTAzMDAzNzAzMDAyMDAyNDEyMDZhMjIwMzIwMDI0MWU4MDA2YTIyMDYyOTAzMDAzNzAzMDAyMDAyMjAwMjI5MDM2MDM3MDMxODAyNDAyMDAxNDFmZWZmZmZmZjA3NDcwNDQwMjAwNTIwMDAyOTAzMDAzNzAzMDAyMDA2MjAwMzI5MDMwMDM3MDMwMDIwMDIyMDAyMjkwMzE4MzcwMzYwMjAwMjEwN2QzNjAyNzgyMDAxMTBhMTAxMjEwMDIwMDIyMDA0MzYwMjNjMjAwMjIwMDczNzAzMzAyMDAyMjAwMDM2MDIzODIwMDI0MTQwNmIyMDAyNDFlMDAwNmEyMDAyNDEzMDZhMTA4MzAxMGMwMTBiMjAwMjQxZDAwMDZhMjAwMDI5MDMwMDM3MDMwMDIwMDI0MWM4MDA2YTIwMDMyOTAzMDAzNzAzMDAyMDAyMjAwMjI5MDMxODM3MDM0MDIwMDIyMDA0MzYwMjU4MGIyMDAyNDFlMDAwNmEyMDAyNDE0MDZiMTA3NjIwMDI0MTgwMDE2YTI0MDAwZjBiNDFjYTg4MDg0MTFmMTA0MTAwMGIwYTAwNDFlODhjMDg0MTIyMTA0ZDBiMGEwMDQxZmE4NjA4NDExZDEwNGQwYmZmMDIwMjAzN2YwMjdlMjMwMDQxZDAwMDZiMjIwMjI0MDAyMDAyNDEzMDZhMjIwNDIwMDE0MTEwNmEyOTAzMDAzNzAzMDAyMDAyNDEyODZhMjIwMzIwMDE0MTA4NmEyOTAzMDAzNzAzMDAyMDAyMjAwMTI5MDMwMDM3MDMyMDIwMDIxMDdkMzYwMjM4MDI0MDAyNDAwMjQwMDI0MDIwMDEyODAyMTgyMjAxMTA2NTBlMDIwMTAyMDAwYjEwNDcyMTAzMjAwMjQxMDg2YTIwMDIyODAyMjAyMDAyMjgwMjI0MjAwNDIwMDExMDYyMjAwMjI5MDMwODIxMDUyMDAyMjkwMzI4MjEwNjIwMDAxMDdkMzYwMjE4MjAwMDIwMDMzNjAyMTAyMDAwMjAwNjM3MDMwODIwMDAyMDA1MzcwMzAwMGMwMjBiMjAwMDIwMDIyOTAzMjAzNzAzMDAyMDAwNDExODZhMjAwMjQxMzg2YTI5MDMwMDM3MDMwMDIwMDA0MTEwNmEyMDA0MjkwMzAwMzcwMzAwMjAwMDQxMDg2YTIwMDMyOTAzMDAzNzAzMDAwYzAxMGIyMDAyNDE0MDZiMjAwMTEwOTcwMTAyN2YyMDAyMjkwMzQwNTAwNDQwMjAwMjI4MDIzMDIxMDEyMDAyNDExMDZhMjAwMjI4MDIyMDIwMDIyODAyMjQyMDAyMjgwMjQ4MjAwMjI4MDI0YzEwNmQyMDAyMjgwMjEwMjEwMzIwMDIyODAyMTQwYzAxMGIxMDQ3MjEwMTIwMDI0MTE4NmEyMDAyMjgwMjIwMjAwMjI4MDIyNDIwMDIyODAyMzAyMDAyNDE0MDZiMTA2YzIwMDIyODAyMTgyMTAzMjAwMjI4MDIxYzBiMjEwNDIwMDIyOTAzMjgyMTA1MjAwMDEwN2QzNjAyMTgyMDAwMjAwMTM2MDIxMDIwMDAyMDA1MzcwMzA4MjAwMDIwMDQzNjAyMDQyMDAwMjAwMzM2MDIwMDBiMjAwMjQxZDAwMDZhMjQwMDBiMGQwMDIwMDAxMDYxNDFmZjAxNzE0MTAxNGIwYjE3MDAyMDAwMjgwMjAwMjAwMTI4MDIwMDEwODkwMTQxZmYwMTcxNDFmZjAxNDYwYjNiMDEwMTdmMjMwMDQxMTA2YjIyMDQyNDAwMjAwNDQxMDg2YTQxMDAyMDAzMjAwMTIwMDIxMDJiMjAwNDI4MDIwYzIxMDEyMDAwMjAwNDI4MDIwODM2MDIwMDIwMDAyMDAxMzYwMjA0MjAwNDQxMTA2YTI0MDAwYjBhMDA0MWJkODgwODQxMGQxMDRkMGIwYTAwNDFmMjg3MDg0MTBmMTA0ZDBiMGEwMDQxZGQ4NzA4NDExNTEwNGQwYjBhMDA0MWE3ODgwODQxMTYxMDRkMGIxOTAxMDE3ZjQxOTc4NzA4NDExNjEwNGQyMTAxMjAwMDI4MDIwMDIwMDExMDQwMjAwMTBiMTkwMTAxN2Y0MWFkODcwODQxMTgxMDRkMjEwMTIwMDAyODAyMDAyMDAxMTA0MDIwMDEwYjBhMDA0MWM1ODcwODQxMTgxMDRkMGIwYTAwNDE4ZjhjMDg0MTFkMTA0ZDBiMGEwMDQxYWM4YzA4NDExZDEwNGQwYjBhMDA0MWM5OGMwODQxMWYxMDRkMGJhNzA1MDIwZDdmMDI3ZTIzMDA0MTQwNmEyMjAwMjQwMDEwMjI0MTBhMTA1YTQxMDA0MWJkODgwODQxMGQxMDUwMjEwOTQxMDExMDRiMjEwMjQxMDI0MTk1ODgwODQxMTIxMDUwMjEwYTQxMDM0MTgxODgwODQxMTQxMDUwMjEwNTQxMDQ0MWYyODcwODQxMGYxMDUwMjEwNjQxMDUxMDExMjEwZDQxMDYxMDExMjEwZTQxMDcxMDU4MjEwNzQxMDgxMDUxMjEwODQxMDk0MWZhODYwODQxMWQxMDUwMjEwNDIwMDAyMDA4MzYwMjEwMjAwMDIwMDczNjAyMGMyMDA1MTAyZjEwMzIyMTAxNDFlNjgxMDg0MTBmMTA0ZDIxMDMxMDQzMjEwYjEwN2QyMTBjMTAxNjIwMDEyMDBjMjAwMzIwMGIxMDQ1MjEwMTEwMTcyMDAxMTAxMjIxMDMyMDAwNDEwMDM2MDIzMDIwMDAyMDAxMzYwMjI4MjAwMDIwMDM0MTAyNzYzNjAyMmMyMDAwNDEyODZhMjIwMzEwNzUxMDJmMTBhMjAxMjEwMTIwMDMyMDA0MTAyZjEwMmYxMDMyNDFhYjgwMDg0MTE1MTAzMzIwMDMxMDgwMDEyMTAzMDI0MDAyNDAyMDAxNDFmZWZmZmZmZjA3NDcwNDQwMjAwMTEwMmYxMGExMDEyMDAyMTAzMDBkMDE0MWU5ODgwODQxZDEwMDEwNDEwMDBiMjAwMjIwMDMxMDMwNDUwZDAxMGIxMGNjMDEyMDA0MTBhODAxMTBkOTAxMjAwMzEwYTgwMTAyNDAxMGNiMDEyMjA0MTBhNjAxMGQwMDIwMDE0MWZlZmZmZmZmMDc0NzA0NDAyMDA0MjAwMTEwMjExYTBjMDEwYjIwMDQ0MWVkODUwODQxMDQxMGI4MDEwYjEwZDEwMTIwMDkxMGE4MDExMGQ0MDEyMDAyMTBhODAxMTBjODAxMjAwYTEwYTgwMTEwYzkwMTIwMDUxMDJmMTBhODAxMTBkODAxMjAwMDQxMjg2YTIyMDEyMDA1MTAzMjQxYjY4MTA4NDEwYTEwMzMyMDAxMTA4MDAxMTBhODAxMTBkMjAxMjAwNjEwMmYxMGE4MDExMGRhMDEyMDAxMjAwNjEwMzI0MTg2ODMwODQxMGYxMDMzMjAwMTEwODAwMTEwYTgwMTIwMDAyMDA3MTAxMjM2MDIxYzIwMDA0MTAwMzYwMjE4MjAwMDIwMDA0MTBjNmEzNjAyMTQwMzQwMDI0MDIwMDA0MTI4NmEyMDAwNDExNDZhMTBjMzAxMjAwMDI4MDIyODQ1MDQ0MDIwMDAyMDA4MTAxMjM2MDIxYzIwMDA0MTAwMzYwMjE4MjAwMDIwMDA0MTEwNmEzNjAyMTQwMzQwMjAwMDQxMjg2YTIwMDA0MTE0NmExMGMzMDEyMDAwMjgwMjI4NDUwZDAyMjAwMDIwMDAyODAyMzAyMjAxMzYwMjI0MjAwMDIwMDAyODAyMmMzNjAyMjAyMDAwNDEyMDZhMTBkNTAxMjIwMjEwYTYwMTBkMDAyMDAyMjAwMTEwYjQwMTBjMDAwYjAwMGIyMDAwMjAwMDI4MDIzMDIyMDEzNjAyMjQyMDAwMjAwMDI4MDIyYzM2MDIyMDIwMDA0MTIwNmExMGQ2MDEyMjAyMTBhNjAxMGQwMTIwMDIyMDAxMTBiOTAxMGMwMTBiMGIxMGQzMDEyMDBkMTBhOTAxMTBkNzAxMjAwZTEwYTkwMTIwMDA0MTQwNmIyNDAwMGYwYjQxYmE4OTA4NDFjODAwMTA0MTAwMGIwODAwMTAyMjQxMDAxMDVhMGJjNzAxMDEwNTdmMjMwMDQxMzA2YjIyMDAyNDAwNDEwMDEwNWEwMjQwMDI0MDEwNDYxMGQxMDExMDVjMTAzMDA0NDAxMDQ2MTBkMTAxMTA1YzEwMzA0NTBkMDEyMDAwMTA0YTIyMDEzNjAyMDgxMGQ0MDExMGE3MDEyMTAyMTBjOTAxMTA1YzIxMDMyMDAwMjAwMTEwMTIzNjAyMTQyMDAwNDEwMDM2MDIxMDIwMDAyMDAwNDEwODZhMzYwMjBjMjAwMDQxMjA2YTIxMDEwMzQwMDI0MDIwMDA0MTE4NmEyMDAwNDEwYzZhMTA2NzIwMDAyOTAzMTg1MDBkMDAyMDAwMjgwMjJjMjAwMDI4MDIyODIwMDIxMDMwNDUwZDA0MTBjZTAxNDUwZDA0MjAwMzEwMmYyMDAxMTBjYTAxMGMwMTBiMGIyMDAwNDEzMDZhMjQwMDBmMGI0MTgyOGEwODQxMTYxMDQxMDAwYjQxODI4YTA4NDExNjEwNDEwMDBiNDE5ODhhMDg0MTBkMTA0MTAwMGJjNzA3MDIwOTdmMDE3ZTIzMDA0MTgwMDE2YjIyMDAyNDAwMTAyMjQxMDExMDVhMjAwMDEwNGYzNjAyMmMxMGQxMDExMDVjMjEwMTAyNDAwMjQwMDI0MDEwNDYyMjA3MjAwMTEwMzAwNDQwMjAwMDEwYzkwMTEwNWMyMjAxMzYwMjM0MjAwMDQxZTAwMDZhMjIwMjIwMDExMDJmMTAzMjQxOGQ4MjA4NDExODEwMzMyMDAwMjgwMjY0MjAwMDQxMmM2YTEwNzgyMDAwNDFkODAwNmEyMjAxMjAwMDQxZjAwMDZhMjIwNjI5MDMwMDM3MDMwMDIwMDA0MWQwMDA2YTIyMDMyMDAwNDFlODAwNmEyMjA0MjkwMzAwMzcwMzAwMjAwMDIwMDAyOTAzNjAzNzAzNDgyMDAwNDFjODAwNmEyMjA1MTA3YzIxMDgyMDAyMTBjODAxMTA1YzEwMzI0MWUxODAwODQxMGExMDMzMjAwMDI4MDI2NDIyMDIyMDAwNDEzNDZhMTA2NDIwMDI0MTAwMjAwODEwNzkyMDAxMjAwNjI5MDMwMDM3MDMwMDIwMDMyMDA0MjkwMzAwMzcwMzAwMjAwMDIwMDAyOTAzNjAzNzAzNDgyMDAwNDEzODZhMjAwNTEwN2UyMDAwMjgwMjQ0MTBjZTAxNDUwZDAxMjAwMDI4MDIzNDEwMzIyMTAxNDFhNTgyMDg0MTA2MTA0ZDIxMDQxMDQzMjIwMzQxMDEyMDAwMTA3OTEwNDMyMjAyMjAwMDQxMzg2YTEwNDQyMDAwMjAwMTM2MDI3MDIwMDA0MjdmMzcwMzY4MjAwMDIwMDMzNjAyNjQyMDAwMjAwNDM2MDI2MDIwMDAxMDdkMjIwNTM2MDI3ODAyNDAwMjQwMDI0MDAyNDAyMDAyMTA2NTBlMDIwMjAwMDEwYjIwMDA0MWM4MDA2YTIwMDIxMDk3MDEwMjdmMjAwMDI5MDM0ODUwMDQ0MDIwMDA0MTE4NmEyMDA0MjAwMzIwMDAyODAyNTAyMDAwMjgwMjU0MTA2ZDIwMDAyODAyMTgyMTA0MjAwMDI4MDIxYzBjMDEwYjEwNDcyMDAwNDEyMDZhMjAwNDIwMDMyMDAxMjAwMDQxYzgwMDZhMTA2YzIwMDAyODAyMjAyMTA0MjEwMTIwMDAyODAyMjQwYjIxMDMxMDdkMjEwNTBjMDEwYjEwNDcyMTAxMjAwMDQxMTA2YTIwMDQyMDAzMjAwNjIwMDIxMDYyMjAwMDI5MDM2ODIxMDkyMDAwMjgwMjE0MjEwMzIwMDAyODAyMTAyMTA0MTA3ZDIxMDUyMDA5NDI3ZjUyMGQwMTBiMTAxNjIxMDkwYjIwMDkyMDAxMjAwNTIwMDQyMDAzMTA0NTIxMDExMDE3MjAwMTEwMTIyMTAyMjAwMDQxMDAzNjAyNTAyMDAwMjAwMTM2MDI0ODIwMDAyMDAyNDEwMjc2MzYwMjRjMjAwMDQxYzgwMDZhMTA3NTIyMDIxMDEyMjEwMTIwMDA0MWYwMDA2YTQxMDAzYTAwMDAyMDAwNDFlYzAwNmEyMDAxMzYwMjAwMjAwMDIwMDIzNjAyNjgyMDAwMjAwMTM2MDI2NDIwMDA0MTAwMzYwMjYwMjAwMDQxZTAwMDZhMjIwMTQxOGE4NTA4NDEwYjEwM2ExMGEyMDEyMTAyMjAwMTEwYmUwMTIxMDkyMDAxMTAzOTIxMDEyMDAwMjgwMjY0MjAwMDI4MDI2MDQ3MGQwMjIwMDAyZDAwNzAwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIwMjQwMjAwMjQxZmVmZmZmZmYwNzQ3MDQ0MDIwMDIxMGExMDEyMTAzMGMwMTBiMTBkOTAxMTBhNzAxMjEwMzEwY2MwMTEwNWMyMDAxMTAyOTEwMzE0MjAwMjEwOTBiMjAwMTEwY2UwMTQ1MGQwMzIwMDcyMDAzMjAwOTIwMDExMDQyMjAwMDIwMDEzNjAyNmMyMDAwMjAwMzM2MDI2ODIwMDAyMDA5MzcwMzYwMjAwMDIwMDA0MWUwMDA2YTEwOTUwMTIyMDEzNjAyMzAyMDAwNDEwODZhMTAzNTIwMDAyMDAwMmQwMDBjM2EwMDNjMjAwMDIwMDAyODAyMDgzNjAyMzgyMDAwMjAwMTEwMTIzNjAyNTAyMDAwNDEwMDM2MDI0YzIwMDAyMDAwNDEzMDZhMzYwMjQ4MDM0MDIwMDA0MWUwMDA2YTIwMDA0MWM4MDA2YTEwNjcyMDAwMjkwMzYwNTA0NTA0NDAyMDAwMjgwMjc0MjAwMDI4MDI3MDIwMDA0MTM4NmEyMjAxMTAzZTIwMDAyOTAzNjgyMDAxMTBjNjAxMjAwMTEwM2MwYzAxMGIwYjIwMDAyODAyMzgyMDAwMmQwMDNjMTAzNzIwMDA0MTgwMDE2YTI0MDAwZjBiNDE4MjhhMDg0MTE2MTA0MTAwMGI0MWU3OGEwODQxMWYxMDQxMDAwYjQxOGE4NTA4NDEwYjQxOTU4NTA4NDEwZTEwNGMwMDBiNDE4NjhiMDg0MTFhMTA0MTAwMGJmMzFkMDIxNjdmMDI3ZTIzMDA0MWEwMDI2YjIyMDAyNDAwMTAyMjQxMDAxMDVhMTBjODAxMTA1YzIxMDEyMDAwMTBjOTAxMTA1YzIyMTQxMDJmMTA5NjAxMzYwMmYwMDEyMDAwMTA0MzM2MDJhMDAxMjAwMDQxODAwMjZhMjIwOTIwMDExMDMyNDFlYjgwMDg0MTBjMTAzMzIwMDAyODAyODQwMjIyMDE0MTAwMTA4MTAxMjAwMTQxMDExMDgxMDEyMDAxNDEwMDEwODEwMTIwMDEyMDAwNDFmMDAxNmEyMjExMTA3YjIwMDEyMDAwNDFhMDAxNmEyMjA3MTA3YjIwMDA0MWUwMDE2YTIyMDUyMDAwNDE5MDAyNmEyMjA0MjkwMzAwMzcwMzAwMjAwMDQxZDgwMTZhMjIwMjIwMDA0MTg4MDI2YTIyMDMyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDEyMDAwNDFkMDAxNmEyMjA2MTA3ZjEwZDIwMTEwNWMyMTAxMjAwMDIwMTQxMDJmMTA5NjAxMzYwMmYwMDEyMDAwMTA0MzM2MDJhMDAxMjAwOTIwMDExMDMyNDFlYjgwMDg0MTBjMTAzMzIwMDAyODAyODQwMjIyMDE0MTAwMTA4MTAxMjAwMTIwMTExMDdiMjAwMTIwMDcxMDdiMjAwMTQxMDEyMDAwMTA3OTIwMDUyMDA0MjkwMzAwMzcwMzAwMjAwMjIwMDMyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDEyMDA2MTA3ZjEwMmEyMjAzMTAyYTIyMDYxMDIzMjAwNjEwY2UwMTA0NDAxMGNjMDExMDVjMjAwNjEwMjkxMDMxMTBkOTAxMTBhNzAxMjEwMTIwMDAyMDA2MzYwMjhjMDIyMDAwNDIwMDM3MDM4MDAyMjAwMDIwMDEzNjAyODgwMjIwMDMyMDAwNDE4MDAyNmExMDQ0MGIyMDAwMjAwMzM2MDI5MDAxMDI0MDAyNDAwMjQwMjAwMzEwNjUwNDQwMTBkNDAxMTBhNzAxMjEwZTEwN2QyMTBkMjAwMDIwMDAyODAyOTAwMTEwMTIzNjAyOWMwMTIwMDA0MTAwMzYwMjk4MDEyMDAwMjAwMDQxOTAwMTZhMzYwMjk0MDEyMDAwNDE5MDAyNmEyMTBhMjAwMDQxYzAwMTZhMjEwZjIwMDA0MWE4MDE2YTIxMTUwMzQwMjAwMDQxYTAwMTZhMjAwMDQxOTQwMTZhMTA2NzIwMDAyOTAzYTAwMTUwMDQ0MDQyODA4MDkwYmJiYWQ2YWRmMDBkMTAyZTIxMDEyMDBkMTBkMzAxMTA1ZjEwMmUxMDkyMDEyMDAxMTA4ZDAxMjIwNTIwMGQxMGQ3MDExMDVmMTAyZTEwOTIwMTIwMDExMDhkMDEyMjA2MTA5MTAxMjAwZDEwODkwMTQxZmYwMTcxNDEwMjQ5MGQwNTIwMGQyMDA1MTA5MzAxMjAwNjEwOTAwMTIxMDIyMDBlMTAyZjIxMDEyMDAwMjAwMjEwMjkzNjAyOGMwMjIwMDA0MjAwMzcwMzgwMDIyMDAwMjAwMTM2MDI4ODAyMjAxNDIwMDA0MTgwMDI2YTEwY2EwMTIwMGUxMDJmMjEwMTIwMDUxMGNlMDEwNDQwMTA0NjIwMDE0MjAwMjAwNTEwNDIwYjIwMDYxMGNlMDEwNDQwMTA0ODIwMGU0MjAwMjAwNjEwNDIwYjEwNDMyMTA0MTA0MzEwMmYyMTA2MjAwMTQxZmVmZmZmZmYwNzQ2MGQwMzIwMDEyMDA2MTA0MDBjMDQwYjIwMGYyMDE1NDEwODZhMjkwMzAwMzcwMzAwMjAwMDIwMTUyOTAzMDAzNzAzYjgwMTIwMGYxMGQ2MDExMGFjMDEyMTEyMjAwZjEwZDUwMTEwYjIwMTIxMTMyMDBmMjgwMjAwMjEwYzIwMDAyODAyYzQwMTIxMDQyMDAwMjkwM2I4MDEyMTE2MjAxMjEwMTIyMTAxMjAxMzEwMTI0MTBkNmUyMDAxNDEwYzZlNmEyMTExNDEwMDIxMDEwMzQwMDI0MDAyNDAyMDAxMjAxMTQ3MDQ0MDIwMDE0MTAxNmEyMTA2NDEwMDIxMDIyMDEyMTAxMjIxMDUwMjQwMDI0MDAzNDAyMDAyNDEwYzZhMjIwMzIwMDU0YjBkMDEyMDAwNDE4ODAyNmEyMjA5NDEwMDM2MDIwMDIwMDA0MjAwMzcwMzgwMDIyMDEyMjAwMjIwMDA0MTgwMDI2YTIyMDI0MTBjMTA4YTAxMWEyMDAwNDEwMDM2MDJkMDAxMjAwMDQxODgwMTZhMjAwMjQxMDA0MTA0MTBjMTAxMjAwMDQxZDAwMTZhMjIwNzQxMDQyMDAwMjgwMjg4MDEyMDAwMjgwMjhjMDExMDU3MjAwMDI4MDJkMDAxMjEwODIwMDA0MjAwMzcwM2QwMDEyMDAwNDE4MDAxNmEyMDAyNDEwNDQxMGMxMGMxMDEyMDA3NDEwODIwMDAyODAyODAwMTIwMDAyODAyODQwMTEwNTcyMDAwNDEwMDM2MDJmMDAxMjAwMDQxZjgwMDZhMjAwNzQxMDA0MTA0MTBjMjAxMjAwMDQxZjAwMTZhMjIwMjQxMDQyMDAwMjgwMjc4MjAwMDI4MDI3YzEwNTcyMDAwMjgwMmYwMDEyMTBiMjAwMDQxMDAzNjAyZjAwMTIwMDA0MWYwMDA2YTIwMDc0MTA0NDEwODEwYzIwMTIwMDI0MTA0MjAwMDI4MDI3MDIwMDAyODAyNzQxMDU3MjAwMzIxMDIyMDA4NDExODc0MjAwODQxODBmZTAzNzE0MTA4NzQ3MjIwMDg0MTA4NzY0MTgwZmUwMzcxMjAwODQxMTg3NjcyNzIyMDAxNDcwZDAwMGIyMDAwMjgwMmYwMDEyMTAzMjAwYjQxMTg3NDIwMGI0MTgwZmUwMzcxNDEwODc0NzIyMDBiNDEwODc2NDE4MGZlMDM3MTIwMGI0MTE4NzY3MjcyMTAyZjIxMDEyMDAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIyMjA3MTAyZjIxMDU0MTAxMTAyZDIwMDA0MTgwMDI2YTIyMDMyMDAxMTAzMjQxZDk4NjA4NDExNDEwMzMyMDAwMjgwMjg0MDIyMjAxMjAwNTEwNmUyMDAxMTA3MDIwMDA0MWUwMDE2YTIyMDIyMDBhMjkwMzAwMzcwMzAwMjAwMDQxZDgwMTZhMjIwMTIwMDkyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDExMDQzMjEwNTIwMDAyMDA0MzYwMjhjMDIyMDAwMjAwYzM2MDI4ODAyMjAwMDIwMTYzNzAzODAwMjIwMDUyMDAzMTA0NDIwMGEyMDAyMjkwMzAwMzcwMzAwMjAwOTIwMDEyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDNkMDAxMzcwMzgwMDIyMDAwMTA3ZDM2MDI5ODAyMDI0MDAyNDAwMjQwMDI0MDIwMDUxMDY1MGUwMjAxMDIwMDBiMTA0NzIxMDEyMDAwNDFlODAwNmEyMDAwMjgwMjgwMDIyMDAwMjgwMjg0MDIyMDBhMjAwNTEwNjIyMDAwMjkwMzY4MjExNzIwMDAyOTAzODgwMjIxMTYyMDAwMTA3ZDM2MDJlODAxMjAwMDIwMDEzNjAyZTAwMTIwMDAyMDE2MzcwM2Q4MDEyMDAwMjAxNzM3MDNkMDAxMGMwMjBiMjAwMDQxZTgwMTZhMjAwMDQxOTgwMjZhMjkwMzAwMzcwMzAwMjAwMjIwMGEyOTAzMDAzNzAzMDAyMDAxMjAwOTI5MDMwMDM3MDMwMDIwMDAyMDAwMjkwMzgwMDIzNzAzZDAwMTBjMDEwYjIwMDA0MWYwMDE2YTIyMDEyMDA1MTA5NzAxMjAwMDQxZDAwMTZhMjAwMDQxODAwMjZhMjAwMTEwODMwMTBiMjAwMDQxODAwMjZhMjAwMDQxZDAwMTZhMTA3NjIwMDAyODAyODgwMjIyMGMyMDA3MTAzMDQ1MGQwMTIwMDAyODAyOGMwMjIxMDQyMDAwMjkwMzgwMDIyMTE2MjAwNjIxMDEwYzA1MGI0MTAwMjEwMjIwMTMxMDEyMjEwNTAzNDAyMDAyNDEwZDZhMjIwMzIwMDU0YjBkMDMyMDAwNDIwMDM3MDA4NTAyMjAwMDQyMDAzNzAzODAwMjIwMTMyMDAyMjAwMDQxODAwMjZhMjIwMjQxMGQxMDhhMDExYTIwMDA0MTAwMzYwMmQwMDEyMDAwNDFlMDAwNmEyMDAyNDEwMDQxMDQxMGJmMDEyMDAwNDFkMDAxNmEyMjA4NDEwNDIwMDAyODAyNjAyMDAwMjgwMjY0MTA1NzIwMDAyODAyZDAwMTIxMDkyMDAwNDFkODAxNmEyMjBiNDEwMDNhMDAwMDIwMDA0MjAwMzcwM2QwMDEyMDAwNDFkODAwNmEyMDAyNDEwNDQxMGQxMGJmMDEyMDA4NDEwOTIwMDAyODAyNTgyMDAwMjgwMjVjMTA1NzIwMDA0MTAwMzYwMmYwMDEyMDAwNDFkMDAwNmEyMDA4NDEwMDQxMDQxMGMwMDEyMDAwNDFmMDAxNmEyMjAyNDEwNDIwMDAyODAyNTAyMDAwMjgwMjU0MTA1NzIwMDAyODAyZjAwMTIxMTAyMDAwNDEwMDM2MDJmMDAxMjAwMDQxYzgwMDZhMjAwODQxMDQ0MTA4MTBjMDAxMjAwMjQxMDQyMDAwMjgwMjQ4MjAwMDI4MDI0YzEwNTcyMDAwMjgwMmYwMDEyMTA3MjAwMDQxMDAzYTAwZjAwMTIwMDA0MTQwNmIyMDA4NDEwODQxMDkxMGMwMDEyMDAyNDEwMTIwMDAyODAyNDAyMDAwMjgwMjQ0MTA1NzIwMDMyMTAyMjAwOTQxMTg3NDIwMDk0MTgwZmUwMzcxNDEwODc0NzIyMDA5NDEwODc2NDE4MGZlMDM3MTIwMDk0MTE4NzY3MjcyMjAwMTQ3MGQwMDBiMjAwMDJkMDBmMDAxMjAwNzQxMTg3NDIwMDc0MTgwZmUwMzcxNDEwODc0NzIyMDA3NDEwODc2NDE4MGZlMDM3MTIwMDc0MTE4NzY3MjcyMjEwODIwMGMxMDJmMjEwOTIwMDQxMDI5MjEwNzIwMTA0MTE4NzQyMDEwNDE4MGZlMDM3MTQxMDg3NDcyMjAxMDQxMDg3NjQxODBmZTAzNzEyMDEwNDExODc2NzI3MjEwMmYyMTA1NDUwNDQwNDEwMTEwMmQyMDAwNDE4MDAyNmEyMjAxMjAwNTEwMzI0MWE4ODYwODQxMDgxMDMzMjAwMDI4MDI4NDAyMTA3MDIwMDA0MWUwMDE2YTIyMDIyMDBhMjkwMzAwMzcwMzAwMjAwYjIwMDA0MTg4MDI2YTIyMDMyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDExMDQzMjEwNDIwMDAyMDA3MzYwMjhjMDIyMDAwMjAwOTM2MDI4ODAyMjAwMDIwMTYzNzAzODAwMjIwMDQyMDAxMTA0NDIwMGEyMDAyMjkwMzAwMzcwMzAwMjAwMzIwMGIyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDNkMDAxMzcwMzgwMDIyMDAwMTA3ZDM2MDI5ODAyMDI0MDAyNDAwMjQwMDI0MDIwMDQxMDY1MGUwMjAxMDIwMDBiMTA0NzIxMDEyMDAwNDExMDZhMjAwMDI4MDI4MDAyMjAwMDI4MDI4NDAyMjAwYTIwMDQxMDYyMjAwMDI5MDMxMDIxMTcyMDAwMjkwMzg4MDIyMTE2MjAwMDEwN2QzNjAyZTgwMTIwMDAyMDAxMzYwMmUwMDEyMDAwMjAxNjM3MDNkODAxMjAwMDIwMTczNzAzZDAwMTBjMDIwYjIwMDA0MWU4MDE2YTIwMDA0MTk4MDI2YTI5MDMwMDM3MDMwMDIwMDIyMDBhMjkwMzAwMzcwMzAwMjAwYjIwMDMyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDEwYzAxMGIyMDAwNDFmMDAxNmEyMDA0MTA5NzAxMDI3ZjIwMDAyOTAzZjAwMTUwMDQ0MDIwMDAyODAyOTAwMjIxMDMyMDAwNDExODZhMjAwMDI4MDI4MDAyMjAwMDI4MDI4NDAyMjAwMDI4MDJmODAxMjAwMDI4MDJmYzAxMTA2ZDIwMDAyODAyMWMyMTAyMjAwMDI4MDIxODBjMDEwYjEwNDcyMTAzMjAwMDQxMjA2YTIwMDAyODAyODAwMjIwMDAyODAyODQwMjIwMDAyODAyOTAwMjIwMDA0MWYwMDE2YTEwNmMyMDAwMjgwMjI0MjEwMjIwMDAyODAyMjAwYjIxMDEyMDAwMjkwMzg4MDIyMTE2MjAwMDEwN2QzNjAyZTgwMTIwMDAyMDAzMzYwMmUwMDEyMDAwMjAxNjM3MDNkODAxMjAwMDIwMDIzNjAyZDQwMTIwMDAyMDAxMzYwMmQwMDEwYjIwMDA0MWQwMDE2YTEwNzIyMTAzMjAwODEwMmYyMTAxMjAwMDIwMDMzNjAyOGMwMjIwMDA0MjAwMzcwMzgwMDIyMDAwMjAwMTM2MDI4ODAyMjAwMDQxODAwMjZhMTA5NTAxMjEwMTBjMDQwYjIwMDgxMDJmMjEwNDQxMDExMDJkMjAwNTEwMzIyMTAzNDFhODg2MDg0MTA4MTA0ZDIxMDExMDQzMjIwNTIwMDQxMDZlMjAwNTEwNzAxMDQzMjEwNDIwMDAyMDA3MzYwMjhjMDIyMDAwMjAwOTM2MDI4ODAyMjAwMDIwMTYzNzAzODAwMjIwMDQyMDAwNDE4MDAyNmExMDQ0MjAwMDIwMDMzNjAyOTAwMjIwMDA0MjdmMzcwMzg4MDIyMDAwMjAwNTM2MDI4NDAyMjAwMDIwMDEzNjAyODAwMjIwMDAxMDdkMzYwMjk4MDIwMjdmMDI3ZTAyNDAwMjQwMDI0MDIwMDQxMDY1MGUwMjAxMDIwMDBiMTA0NzIxMDIyMDAwNDEyODZhMjAwMDI4MDI4MDAyMjAwMDI4MDI4NDAyMjAwYTIwMDQxMDYyMjAwMDI4MDIyYzIxMDMyMDAwMjgwMjI4MjEwMTIwMDAyOTAzODgwMjBjMDIwYjIwMDAyODAyOTAwMjIxMDIyMDAwMjkwMzg4MDIyMTE2MjAwMDI4MDI4NDAyMjEwMzIwMDAyODAyODAwMjIxMDEyMDAwMjgwMjk4MDIwYzAyMGIyMDAwNDFkMDAxNmEyMDA0MTA5NzAxMDI3ZjIwMDAyOTAzZDAwMTUwMDQ0MDIwMDAyODAyOTAwMjIxMDIyMDAwNDEzMDZhMjAwMDI4MDI4MDAyMjAwMDI4MDI4NDAyMjAwMDI4MDJkODAxMjAwMDI4MDJkYzAxMTA2ZDIwMDAyODAyMzQyMTAzMjAwMDI4MDIzMDBjMDEwYjEwNDcyMTAyMjAwMDQxMzg2YTIwMDAyODAyODAwMjIwMDAyODAyODQwMjIwMDAyODAyOTAwMjIwMDA0MWQwMDE2YTEwNmMyMDAwMjgwMjNjMjEwMzIwMDAyODAyMzgwYjIxMDEyMDAwMjkwMzg4MDIwYjIxMTYxMDdkMGIyMTA0MjAxNjQyN2Y1MTA0N2UxMDE2MDUyMDE2MGIyMDAyMjAwNDIwMDEyMDAzMTA0NTIxMDMxMDE3NDEwMDIxMDIyMDAzMTAxMjIxMDEyMDAwNDEwMDM2MDJmODAxMjAwMDIwMDMzNjAyZjAwMTIwMDAyMDAxNDEwMjc2MzYwMmY0MDEyMDAwNDFmMDAxNmExMDc1MTAyZjIxMDQxMDQzMjEwMTIwMDQxMDEyMjEwMzIwMDA0MTAwM2EwMDkwMDIyMDAwMjAwMzM2MDI4YzAyMjAwMDIwMDQzNjAyODgwMjIwMDAyMDAzMzYwMjg0MDIyMDAwNDEwMDM2MDI4MDAyMDM0MDIwMDIyMDAzNDYwNDQwMjAwMDJkMDA5MDAyNDUwZDA1NDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGMwNTA1MjAwMDQxZDAwMTZhMjIwMzIwMDA0MTgwMDI2YTEwNzcyMDAxMjAwMzEwNDQyMDAwMjgwMjgwMDIyMTAyMjAwMDI4MDI4NDAyMjEwMzBjMDEwYjAwMGIwMDBiNDFjMDg2MDg0MTE5MTA0MTAwMGIyMDBjMjAwZTEwMzAwNDQwMjAwZDIwMDQxMDhmMDEwYzA0MGI0MWQ0OGEwODQxMTMxMDQxMDAwYjIwMDA0MTA4NmExMDM2MjAwMDIwMDAyZDAwMGMzYTAwODQwMjIwMDAyMDAwMjgwMjA4MzYwMjgwMDIyMDAwNDE4MDAyNmEyMjA2NDE4MDgwMDg0MTIxMTBhMzAxMjMwMDQxNDA2YTIyMDMyNDAwMjAwMzQxMDAyMDAzNmI0MTAzNzEyMjA0NmEyMTA3MjAwNDA0NDAyMDAzMjEwMjAzNDAyMDAyNDEwMDNhMDAwMDIwMDI0MTAxNmEyMjAyMjAwNzQ5MGQwMDBiMGIyMDA3NDFjMDAwMjAwNDZiMjIwNTQxN2M3MTIyMDQ2YTIxMDIyMDA0NDEwMDRhMDQ0MDAzNDAyMDA3NDEwMDM2MDIwMDIwMDc0MTA0NmEyMjA3MjAwMjQ5MGQwMDBiMGIyMDA1NDEwMzcxMjIwNDA0NDAyMDAyMjAwNDZhMjEwNDAzNDAyMDAyNDEwMDNhMDAwMDIwMDI0MTAxNmEyMjAyMjAwNDQ5MGQwMDBiMGIyMDA2MjAwMzAyN2YyMDAxMDQ0MDIwMDFhZDIxMTY0MTNmMjEwMTAyNDAwMzQwMjAxNjUwMGQwMTIwMDE0MTNmNGQwNDQwMjAwMTIwMDM2YTIwMTYyMDE2NDIwYTgwMjIxNjQyMGE3ZTdkYTc0MTMwNzIzYTAwMDAyMDAxNDEwMTZiMjEwMTBjMDEwYjBiMTAyYzAwMGIyMDAxNDEwMTZhMGMwMTBiMjAwMzQxMzAzYTAwM2Y0MTNmMGIyMjAxNmE0MWMwMDAyMDAxNmIxMGEzMDEyMDAzNDE0MDZiMjQwMDIwMDAyODAyODAwMjIwMDAyZDAwODQwMjEwMzgxMDAwMDAwYjIwMDAyMDAxMzYwMmNjMDExMDdkMjEwMjEwN2QyMTA0MjAwMDIwMDExMDEyMzYwMmQ4MDEyMDAwNDEwMDM2MDJkNDAxMjAwMDIwMDA0MWNjMDE2YTM2MDJkMDAxMDI0MDAzNDAwMjQwMjAwMDQxODAwMjZhMjAwMDQxZDAwMTZhMTA2NzIwMDAyOTAzODAwMjUwMGQwMDIwMDAyODAyOTQwMjIxMDUyMDAyMjEwMzIwMDAyODAyOTAwMjIyMDEyMDBjMTAzMDQ1MDQ0MDIwMDQyMTAzMjAwMTIwMDgxMDMwNDUwZDAzMGIyMDAzMjAwNTEwOGYwMTBjMDEwYjBiMjAwODEwMmYyMTBjNDIwMDIxMTYyMDA2MjEwMTBjMDEwYjBiMGI0MTg3ODYwODQxMjExMDQxMDAwYjQxYTU4YTA4NDExNTEwNDEwMDBiMjAwMDQxODA4MDgwMjAzNjAyZDAwMTIwMDYyMDAwNDFkMDAxNmE0MTA0MTAwZjFhMjAwNjQxZWQ4NTA4NDEwNDEwMGYxYTBiMjAwMDQyMDAzNzAzZDAwMTIwMDYyMDAwNDFkMDAxNmEyMjAzNDEwODEwMGYxYTIwMDUyMDA2MTAzZjIwMDQyMDA2MTA0ZTEwYzcwMTEwNDMyMjAxNDE4YThkMDg0MTA4MTA0ZDEwNGUyMDAyMTA0MzEwMmYyMjAyMTAzZjIwMDIxMDNmMjAwMTIwMDIxMDI0MjAwMDIwMDQzNjAyZDAwMTIwMDAyMDA0MTAxMjM2MDI4ODAyMjAwMDQxMDAzNjAyODQwMjIwMDAyMDAzMzYwMjgwMDIwMzQwMjAwMDIwMDA0MTgwMDI2YTEwYzQwMTIwMDAyODAyMDAwNDQwMjAwMDI4MDIwNDEwMDcxYTBjMDEwYjBiMjAwMDQxYTAwMjZhMjQwMDBmMGI0MWJhOGEwODQxMWExMDQxMDAwYjBkMDAxMDIyNDEwMDEwNWExMGM3MDExMDI1MGIwZDAwMTAyMjQxMDAxMDVhMTBkMTAxMTA1YjBiMGQwMDEwMjI0MTAwMTA1YTEwZDQwMTEwNWQwYjBkMDAxMDIyNDEwMDEwNWExMGQ4MDExMDVkMGIyYTAxMDE3ZjEwMjI0MTAwMTA1YTEwY2IwMTEwYWIwMTIyMDA0MWZlZmZmZmZmMDc0NzA0NDAyMDAwMTAwNzFhMGYwYjQxZWQ4NTA4NDEwNDEwMjYwYjBkMDAxMDIyNDEwMDEwNWExMGRhMDExMDVkMGIwZDAwMTAyMjQxMDAxMDVhMTBjODAxMTA1YjBiMGQwMDEwMjI0MTAwMTA1YTEwYzkwMTEwNWIwYjBkMDAxMDIyNDEwMDEwNWExMGNjMDExMDViMGIwZDAwMTAyMjQxMDAxMDVhMTBkOTAxMTA1ZDBiMGQwMDEwMjI0MTAwMTA1YTEwZDIwMTEwNWIwYmExMDEwMTAyN2YyMzAwNDE0MDZhMjIwMDI0MDAxMDIyNDEwMTEwNWEyMDAwNDEwMDEwNGIzNjAyMTQyMDAwMjAwMDQxMTQ2YTEwZDYwMTEwYWMwMTIyMDEzNjAyMTgyMDAwNDEwODZhMTAzNTIwMDAyMDAwMmQwMDBjM2EwMDIwMjAwMDIwMDAyODAyMDgzNjAyMWMyMDAwMjAwMTEwMTIzNjAyMmMyMDAwNDEwMDM2MDIyODIwMDAyMDAwNDExODZhMzYwMjI0MjAwMDQxMzQ2YTIxMDEwMzQwMjAwMDQxMzA2YTIwMDA0MTI0NmExMGJhMDEyMDAwMjgwMjMwMDQ0MDIwMDEyMDAwNDExYzZhMTBiYjAxMGMwMTBiMGIyMDAwMjgwMjFjMjAwMDJkMDAyMDEwMzcyMDAwNDE0MDZiMjQwMDBiYTAwMTAxMDI3ZjIzMDA0MTQwNmEyMjAwMjQwMDEwMjI0MTAxMTA1YTIwMDA0MTAwMTA0YjM2MDIxNDIwMDAyMDAwNDExNDZhMTBkNTAxMTBiMjAxMjIwMTM2MDIxODIwMDA0MTA4NmExMDM1MjAwMDIwMDAyZDAwMGMzYTAwMjAyMDAwMjAwMDI4MDIwODM2MDIxYzIwMDAyMDAxMTAxMjM2MDIyYzIwMDA0MTAwMzYwMjI4MjAwMDIwMDA0MTE4NmEzNjAyMjQwMzQwMjAwMDQxMzA2YTIwMDA0MTI0NmExMGI1MDEyMDAwMmQwMDNjNDEwMjQ3MDQ0MDIwMDA0MTMwNmEyMDAwNDExYzZhMTBiNjAxMGMwMTBiMGIyMDAwMjgwMjFjMjAwMDJkMDAyMDEwMzcyMDAwNDE0MDZiMjQwMDBiMGQwMDEwMjI0MTAwMTA1YTEwZDMwMTEwNWUwYjBkMDAxMDIyNDEwMDEwNWExMGQ3MDExMDVlMGJlMzAzMDIwNTdmMDI3ZTIzMDA0MTkwMDE2YjIyMDAyNDAwMTA0OTQxMDAxMDVhMjAwMDEwNGEyMjAxMzYwMjE0MDI0MDIwMDExMDY1NDEwMTQ2MDQ0MDIwMDExMDEyMjEwMTIwMDA0MTAwMzYwMjM0MjAwMDIwMDEzNjAyMzAyMDAwNDEwMDM2MDIyYzIwMDAyMDAwNDExNDZhMzYwMjI4MjAwMDQxM2M2YTIxMDIyMDAwNDFmNDAwNmEyMTAzMjAwMDQxZjgwMDZhMjEwMTAzNDAyMDAwNDFmMDAwNmEyMDAwNDEyODZhMTA2NzIwMDAyOTAzNzA1MDBkMDIyMDAwNDFlMDAwNmEyMDAxNDEwODZhMjkwMzAwMjIwNTM3MDMwMDIwMDAyMDAxMjkwMzAwMjIwNjM3MDM1ODIwMDAyMDAwMjgwMjM0MjIwNDQxMDE2YTM2MDIzNDIwMDM0MTA4NmEyMDA1MzcwMjAwMjAwMzIwMDYzNzAyMDAyMDAwNDE0MDZiMjAwMTI5MDIwMDM3MDMwMDIwMDA0MWM4MDA2YTIwMDA0MTgwMDE2YTI4MDIwMDM2MDIwMDIwMDAyMDAwMjkwMjcwMzcwMzM4MjAwNDQ1MDQ0MDIwMDA0MTIwNmEyMDAyNDEwODZhMjkwMjAwMzcwMzAwMjAwMDIwMDIyOTAyMDAzNzAzMTgwYzAxMGIwYjEwMmMwMDBiNDFiMzgzMDg0MTIyMTAwMzAwMGIyMDAwNDEwODZhMjIwMTIwMDA0MTIwNmEyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDMxODM3MDMwMDEwZGEwMTEwYTcwMTIxMDIyMDAxMjgwMjAwMjAwMjEwMzA0NTA0NDA0MTk4OGEwODQxMGQxMDQxMDAwYjEwZDIwMTEwNWMyMTAyMjAwMDEwNDMzNjAyMTgyMDAwMTA0MzM2MDIyODIwMDA0MWYwMDA2YTIyMDEyMDAyMTAzMjQxYTc4MzA4NDEwNTEwMzMyMDAwMjgwMjc0MjIwMjIwMDA0MTE4NmExMDdiMjAwMjIwMDA0MTI4NmExMDdhMjAwMDQxZTgwMDZhMjAwMDQxODAwMTZhMjkwMzAwMzcwMzAwMjAwMDQxZTAwMDZhMjAwMDQxZjgwMDZhMjkwMzAwMzcwMzAwMjAwMDIwMDAyOTAzNzAzNzAzNTgyMDAwNDEzODZhMjIwMjIwMDA0MWQ4MDA2YTIwMDAxMDg0MDEyMDAxMjAwMjEwY2QwMTIwMDExMDc0MjAwMDQxOTAwMTZhMjQwMDBiOGMwMTAxMDI3ZjIzMDA0MTQwNmEyMjAwMjQwMDEwNDk0MTAwMTA1YTEwZDIwMTEwNWMyMTAxMjAwMDEwNDMzNjAyMDAyMDAwMTA0MzM2MDIwNDIwMDA0MTA4NmEyMDAxMTAzMjQxOTU4MzA4NDExMjEwMzMyMDAwMjgwMjBjMjIwMTIwMDAxMDdiMjAwMTIwMDA0MTA0NmExMDdhMjAwMDQxMzA2YTIwMDA0MTE4NmEyOTAzMDAzNzAzMDAyMDAwNDEyODZhMjAwMDQxMTA2YTI5MDMwMDM3MDMwMDIwMDAyMDAwMjkwMzA4MzcwMzIwMjAwMDEwN2QzNjAyMzgyMDAwNDEyMDZhMTA3NDIwMDA0MTQwNmIyNDAwMGJmZjAxMDIwNTdmMDE3ZTIzMDA0MTMwNmIyMjAwMjQwMDEwMjIxMDQ5NDEwMTEwNWEyMDAwMTA0ZjM2MDIxMDEwZDIwMTEwNWMyMDAwMTA0MzM2MDIxNDIwMDAxMDQzMzYwMjE4MTAzMjIxMDI0MWFjODMwODQxMDcxMDRkMjEwMzEwNDMyMjAxMjAwMDQxMTA2YTEwNzgyMDAxMjAwMDQxMTQ2YTEwN2IyMDAxMjAwMDQxMTg2YTEwN2ExMDdkMjEwNDEwMTYyMDAyMjAwNDIwMDMyMDAxMTA0NTIxMDExMDE3MjAwMTEwMTIyMTAyMjAwMDQxMDAzNjAyMjQyMDAwMjAwMTM2MDIxYzIwMDAyMDAyNDEwMjc2MzYwMjIwMjAwMDQxMWM2YTEwNzUyMTAxMjAwMDQyMDAzNzAzMjgyMDAxMTAxMjIyMDI0MTA5NDkwNDQwMDI0MDIwMDA0MTA4NmEyMDAwNDEyODZhMjAwMjEwYjAwMTIwMDE0MTAwMjAwMDI4MDIwODIyMDEyMDAwMjgwMjBjMjIwMjEwOGEwMTFhMjAwMTIwMDIxMGIxMDEyMjA1NDI4MDgwODA4MDEwNWEwZDAwMjAwNTEwMTQyMDAwNDEzMDZhMjQwMDBmMGIwYjQxOGE4NTA4NDEwYjQxOTU4NTA4NDEwZTEwNGMwMDBiOTgwMzAyMDU3ZjAxN2UyMzAwNDFlMDAwNmIyMjAwMjQwMDEwMjIxMDQ5NDFlNGRiMDgxMDEzMzYwMjAwNDFlNGRiMDgyODAyMDA0MTAwNDgwNDQwNDFlZjgzMDg0MTExMTAwMzAwMGIyMDAwNDEwMDM2MDIzODEwNDMyMTAzMjAwMDQxMzg2YTIyMDQyODAyMDAyMTAxMDM0MDQxZTRkYjA4MjgwMjAwMjAwMTRhMDQ0MDIwMDQyMDAxNDEwMTZhMjIwMjM2MDIwMDIwMDMyMDAxMTA0YjEwNGUyMDAyMjEwMTBjMDEwYjBiMjAwMzIxMDE0MWU0ZGIwODI4MDIwMDIwMDAyODAyMzg0YTA0NDA0MTgwODQwODQxMTIxMDAzMDAwYjIwMDAyMDAxMzYwMjFjMjAwNDEwZDIwMTEwNWMxMDMyNDFmOTgyMDg0MTBkMTAzMzIwMDAyMDAxMTAxMjM2MDI1YzIwMDA0MTAwMzYwMjU4MjAwMDIwMDA0MTFjNmEzNjAyNTQyMDAwMjgwMjNjMjEwMTAzNDAyMDAwNDExMDZhMjAwMDQxZDQwMDZhMTBjNDAxMjAwMDI4MDIxMDA0NDAyMDAxMjAwMDI4MDIxNDEwNmUwYzAxMGIwYjIwMDA0MTI4NmEyMDAwNDE0MDZiMjkwMzAwMzcwMzAwMjAwMDQxMzA2YTIwMDA0MWM4MDA2YTI5MDMwMDM3MDMwMDIwMDAyMDAwMjkwMzM4MzcwMzIwMjAwMDQxMzg2YTIwMDA0MTIwNmExMDdlMDI0MDIwMDAyODAyNDQyMjAxMTBjZTAxNDUwNDQwMjAwMDI4MDI0MDIxMDIwYzAxMGIxMDQ2MjAwMDI4MDI0MDIyMDI0MjAwMjAwMTEwNDIwYjIwMDAyOTAzMzgyMDAwNDEwODZhMTAzNTIwMDAyMDAwMmQwMDBjM2EwMDNjMjAwMDIwMDAyODAyMDgzNjAyMzgyMDAyMjAwMDQxMzg2YTIyMDIxMDNlMjAwMjEwYzYwMTIwMDEyMDAyMTAzYzIwMDAyODAyMzgyMDAwMmQwMDNjMTAzNzIwMDA0MWUwMDA2YTI0MDAwYjMxMDEwMTdlMTAyMjEwNDk0MTAxMTA1YTQxMDAxMDExMjIwMDQyODE4MDkwYmJiYWQ2YWRmMDBkNWEwNDQwNDFlZjhiMDg0MTIwMTA0MTAwMGIxMGQ3MDEyMDAwMTBhYTAxMGIzMTAxMDE3ZTEwMjIxMDQ5NDEwMTEwNWE0MTAwMTAxMTIyMDA0MjgxODA5MGJiYmFkNmFkZjAwZDVhMDQ0MDQxZDI4YjA4NDExZDEwNDEwMDBiMTBkMzAxMjAwMDEwYWEwMTBiZTMwMTAxMDM3ZjIzMDA0MTMwNmIyMjAwMjQwMDEwMjIxMDQ5NDEwMjEwNWE0MTAwMTA1ODIxMDEyMDAwNDEwMTEwNTEyMjAyMzYwMjBjMjAwMDIwMDEzNjAyMDgyMDAwMjAwMTEwMTIzNjAyMTgyMDAwNDEwMDM2MDIxNDIwMDAyMDAwNDEwODZhMzYwMjEwMDM0MDIwMDA0MTFjNmEyMDAwNDExMDZhMTBjMzAxMjAwMDI4MDIxYzA0NDAyMDAwMjAwMDI4MDIyNDIyMDEzNjAyMmMyMDAwMjAwMDI4MDIyMDM2MDIyODIwMDA0MTI4NmExMGQ2MDEyMDAxMTBiOTAxMGMwMTA1MjAwMDIwMDIxMDEyMzYwMjE4MjAwMDQxMDAzNjAyMTQyMDAwMjAwMDQxMGM2YTM2MDIxMDAzNDAyMDAwNDExYzZhMjAwMDQxMTA2YTEwYzMwMTIwMDAyODAyMWMwNDQwMjAwMDIwMDAyODAyMjQyMjAxMzYwMjJjMjAwMDIwMDAyODAyMjAzNjAyMjgyMDAwNDEyODZhMTBkNTAxMjAwMTEwYjQwMTBjMDEwYjBiMjAwMDQxMzA2YTI0MDAwYjBiMGJhYTA3MDIwYjdmMDE3ZTIzMDA0MTMwNmIyMjAwMjQwMDEwMjI0MTAwMTA1YTEwYzkwMTEwNWMyMjA5MTAyZjEwMzIyMTAxNDFkMjgxMDg0MTE0MTA0ZDIxMDIxMDQzMjEwNjEwN2QyMTA3MTAxNjIwMDEyMDA3MjAwMjIwMDYxMDQ1MjEwMTEwMTcyMDAxMTAxMjIxMDIyMDAwNDEwMDM2MDIxMDIwMDAyMDAxMzYwMjA4MjAwMDIwMDI0MTAyNzYzNjAyMGMyMDAwNDEwODZhMTA3NTIyMDIxMDEyMjEwMTIwMDA0MTI4NmE0MTAwM2EwMDAwMjAwMDQxMjQ2YTIwMDEzNjAyMDAyMDAwMjAwMjM2MDIyMDIwMDAyMDAxMzYwMjFjMjAwMDQxMDAzNjAyMTgwMjQwMDI3ZjAyNDAwMjQwMjAwMTQ1MGQwMDAyNDAwMjQwMDI0MDIwMDA0MTE4NmE0MThhODUwODQxMGIxMDU0NDFmZjAxNzEwZTAyMDIwMTAwMGI0MThhODUwODQxMGI0MWVkODYwODQxMGQxMDRjMDAwYjQxMDEyMTAzMjAwMDQxMTg2YTQxOGE4NTA4NDEwYjEwNTMyMTAxMGIyMDAwMjgwMjFjMjAwMDI4MDIxODQ3MGQwMzIwMDAyZDAwMjgwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAzNDUwZDAwMjAwMDQxMTg2YTIyMDQyMDAxMTAyZjEwMzI0MWU0ODIwODQxMTUxMDMzMjAwMDIwMDQxMDdjMjIwMzM2MDIwMDIwMDQyMDAxMTAyZjEwMzI0MWIyODIwODQxMGIxMDMzMjAwMDQxMTg2YTEwN2M0MmJlOGE4NjBmMTAyZTEwOGUwMTIxMDYyMDA0MjAwMTEwMmYxMDMyNDFjOTgyMDg0MTBkMTAzMzIwMDA0MTE4NmExMDdjMjAwMzEwOTIwMTQyYmU4YTg2MGYxMDJlMTA4ZTAxNDEwYTEwMmQ0MTEyMTA5NDAxMTA4ZDAxMjEwNzIwMDQyMDAxMTAyZjEwMzI0MWJkODIwODQxMGMxMDMzMjAwMDQxMTg2YTEwN2M0MTBhMTAyZDQxMTIxMDk0MDEyMDAzMTA5MDAxMTA4ZTAxNDJiZThhODYwZjEwMmUxMDhlMDE0MTBhMTAyZDQxMTIxMDk0MDExMDhkMDEyMTBhMjAwNDIwMDkxMDJmMjIwMjEwMmYxMDMyNDE4NzgxMDg0MTBmMTAzMzIwMDAyMDAwNDExODZhMTA3YzIyMDUzNjAyMTQyMDA0MjAwMjEwMmYxMDMyNDFhYjgyMDg0MTA3MTAzMzIwMDA0MTE4NmExMDdjMjEwODIwMDQyMDAyMTAzMjQxYTY4MTA4NDExMDEwMzMyMDAwNDExODZhMTA3YzIxMDIyMDAwMjAwODIwMDUxMDkxMDEyMDAyMTA5MDAxMzYwMjA4MjAwNDIwMDExMDMyNDFkNjgyMDg0MTBlMTAzMzIwMDAyODAyMWMyMjAxMjAwMDQxMTQ2YTEwNzgyMDAxMjAwMDQxMDg2YTEwNzgyMDAwMjgwMjI4MjEwMjIwMDAyODAyMTgyMTA1MjAwMDI5MDMyMDEwN2QyMTA4MTA3MTIwMDIyMDA4MjAwNTIwMDExMDQ1MjEwMTEwMTcyMDAwMjAwMTEwNzMzNjAyMDQ0MjgwODA5MGJiYmFkNmFkZjAwZDEwMmUyMTAyMjAwMDEwN2QzNjAyMTgyMDAwNDEwNDZhMjAwNDEwY2YwMTIxMDUxMDdkMjIwMTIwMDUwZDAyMWEyMDAxMjAwMDI4MDIwNDEwODkwMTQxMDE2YTQxZmYwMTcxNDEwMTRkMDQ0MDIwMDA0MTA0NmEyMDAwMTBjZjAxMGQwMjIwMDAyODAyMDAyMTAzMGIyMDAwMjgwMjA0MjAwMzEwOTMwMTIwMGExMDhlMDEyMTAxNDEwYTEwMmQ0MTEyMTA5NDAxMjAwMDI4MDIwMDEwOTAwMTIxMDMyMDA2MjAwMjEwOTIwMTIwMDcyMDAyMTA5MjAxMTA4YzAxMjAwMTIwMDIxMDhlMDEyMDAzMTA4ZDAxMTA4YzAxMGMwMjBiNDFhMDhiMDg0MTMyMTA0MTAwMGIyMDAwMjgwMjA0MjAwNzEwOTIwMTIxMDEyMDA2MjAwMjEwOTIwMTIwMDEyMDAyMTA4ZTAxMjAwMDI4MDIwMDEwOGQwMTEwOGMwMTBiMjEwMTIwMDA0MTE4NmEyMjAzMjAwOTEwMzI0MTk2ODEwODQxMTAxMDMzMjAwMzEwN2MyMTAyNDEwYTEwMmQ0MTEyMTA5NDAxMjEwMzIwMDAyODAyMDQyMDAxMTA5MjAxMjAwMzIwMDIxMDkzMDExMDhlMDEyMDAzNDEwMzEwOTQwMTEwOGQwMTEwMjUyMDAwNDEzMDZhMjQwMDBmMGI0MThhODUwODQxMGI0MTk1ODUwODQxMGUxMDRjMDAwYjAzMDAwMTBiM2MwMTAxN2YyMzAwNDExMDZiMjIwNTI0MDAyMDA1NDEwODZhMjAwMTIwMDQyMDAyMjAwMzEwOWQwMTIwMDUyODAyMGMyMTAxMjAwMDIwMDUyODAyMDgzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MTEwNmEyNDAwMGIzYjAxMDE3ZjIzMDA0MTEwNmIyMjA1MjQwMDIwMDU0MTA4NmEyMDAyMjAwMzIwMDEyMDA0MTAyYjIwMDUyODAyMGMyMTAxMjAwMDIwMDUyODAyMDgzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MTEwNmEyNDAwMGIwYmRhMGQwMjAwNDE4MDgwMDgwYmM2MGQ0ZTZmMjA3Mzc3NjE3MDIwNmY3MDY1NzI2MTc0Njk2ZjZlMjA2NjZmNzU2ZTY0MjA2MTc0MjA2OTZlNjQ2NTc4MjA3NTZlNzc3MjYxNzA0NTY3NmM2NDY3NjU3NDU3NzI2MTcwNzA2NTY0NDU2NzZjNjQ1NDZmNmI2NTZlNDk2NDc3NzI2MTcwNDU2NzZjNjQ3MjY1NjM2OTcwNjk2NTZlNzQyMDYxNjQ2NDcyNjU3MzczMjA2ZTZmNzQyMDczNjU3NDY1Nzg2OTc0NGQ2MTcyNmI2NTc0NjM2YzYxNjk2ZDUyNjU3NzYxNzI2NDczNjc2NTc0NDE2MzYzNmY3NTZlNzQ1NDZmNmI2NTZlNzM2NzY1NzQ1NDZmNzQ2MTZjNDI2ZjcyNzI2Zjc3NzM2NzY1NzQ1MjY1NzM2NTcyNzY2NTQ2NjE2Mzc0NmY3MjY3NjU3NDU0NmY3NDYxNmM1MjY1NzM2NTcyNzY2NTczNjc2NTc0NTQ2ZjZiNjU2ZTQ5NjQ2ZDY5NmU3NDQxNmU2NDQ1NmU3NDY1NzI0ZDYxNzI2YjY1NzQ2NzY1NzQ0OTZlNzQ2NTcyNjU3Mzc0NTI2MTc0NjU0ZDZmNjQ2NTZjNjc2NTc0NTU2ZTY0NjU3MjZjNzk2OTZlNjc0OTY0NzQ2ZjZiNjU2ZTczNTQ2ZjU1NmU2NDY1NzI2Yzc5Njk2ZTY3NDE2ZDZmNzU2ZTc0NzU2ZTY0NjU3MjZjNzk2OTZlNjc0MTZkNmY3NTZlNzQ1NDZmNTQ2ZjZiNjU2ZTczNzI2NTY0NjU2NTZkNjc2NTc0NDM2MTczNjg2NzY1NzQ0MjYxNzM2NTUyNjE3NDY1Njc2NTc0NGM2MTczNzQ1MzZjNmY3MDY1Njc2NTc0NDY2OTcyNzM3NDUzNmM2ZjcwNjU2NzY1NzQ1NTc0Njk2YzY5N2E2MTc0Njk2ZjZlNjc2NTc0NGY3MDc0Njk2ZDYxNmM1NTc0Njk2YzY5N2E2MTc0Njk2ZjZlNjM2YzYxNjk2ZDRkNzU2Yzc0Njk3MDZjNjU2NzY1NzQ1Mzc0NjE2YjY1NTQ2ZjZiNjU2ZTQ5NjQ3MjY1NjI2MTZjNjE2ZTYzNjU1MDZmNzI3NDY2NmY2YzY5NmY3Mzc0NjE2YjY1NzU2ZTczNzQ2MTZiNjU2OTZlNjM2ZjcyNzI2NTYzNzQyMDZlNzU2ZDYyNjU3MjIwNmY2NjIwNDU1MzQ0NTQyMDc0NzI2MTZlNzM2NjY1NzI3MzYxNzI2Nzc1NmQ2NTZlNzQyMDY0NjU2MzZmNjQ2NTIwNjU3MjcyNmY3MjIwMjgyOTNhMjA3NDZmNmYyMDY2NjU3NzIwNjE3MjY3NzU2ZDY1NmU3NDczNzQ2ZjZmMjA2ZDYxNmU3OTIwNjE3MjY3NzU2ZDY1NmU3NDczNzc3MjZmNmU2NzIwNmU3NTZkNjI2NTcyMjA2ZjY2MjA2MTcyNjc3NTZkNjU2ZTc0NzM2MzYxNmU2ZTZmNzQyMDczNzU2Mjc0NzI2MTYzNzQyMDYyNjU2MzYxNzU3MzY1MjA3MjY1NzM3NTZjNzQyMDc3NmY3NTZjNjQyMDYyNjUyMDZlNjU2NzYxNzQ2OTc2NjU0ZDc1NmM3NDY5NDU1MzQ0NTQ0ZTQ2NTQ1NDcyNjE2ZTczNjY2NTcyNDU1MzQ0NTQ0ZTQ2NTQ1NDcyNjE2ZTczNjY2NTcyNDU1MzQ0NTQ1NDcyNjE2ZTczNjY2NTcyNzM3OTZlNjMyMDcyNjU3Mzc1NmM3NDY5NmU3MDc1NzQyMDc0NmY2ZjIwNmM2ZjZlNjc2OTZlNzA3NTc0MjA3NDZmNmYyMDczNjg2ZjcyNzQ2MzYxNzM3NDIwNzQ2ZjIwNjkzNjM0MjA2NTcyNzI2ZjcyNGQ2MTZlNjE2NzY1NjQ1NjY1NjMyMDY5NmU2NDY1NzgyMDZmNzU3NDIwNmY2NjIwNzI2MTZlNjc2NTQ1NTM0NDU0MjA2NTc4NzA2NTYzNzQ2NTY0NDU0NzRjNDQ3Mzc0NmY3MjYxNjc2NTIwNjQ2NTYzNmY2NDY1MjA2NTcyNzI2ZjcyM2EyMDc1NmU2YjZlNmY3NzZlMjA3MjY1NjM2NTY5NzY2NTY0MjA3NDZmNmI2NTZlMjA2MTY2NzQ2NTcyMjA3Mzc3NjE3MDY1Nzg2MzY4NjE2ZTY3NjU2MjYxNjQyMDYxNzI3MjYxNzkyMDZjNjU2ZTY3NzQ2ODc3NzI2ZjZlNjcyMDcyNjU3NDc1NzI2ZTY1NjQyMDczNzc2MTcwMjA3NDZmNmI2NTZlNzM3NzYxNzA1NDZmNmI2NTZlNzM0NjY5Nzg2NTY0NDk2ZTcwNzU3NDY5NmU3NjYxNmM2OTY0MjA3NjYxNmM3NTY1Nzc3MjYxNzA3MDY1NjQ1ZjY1Njc2YzY0NWY2MzZmNmU3NDcyNjE2Mzc0NWY2MTY0NjQ3MjY1NzM3MzYzNmY2ZDcwNmY3NTZlNjQ1ZjYxNzM2ODczNzc2MTcwNWY3Mzc3NjE3MDczNjM2ZjZkNzA2Zjc1NmU2NDVmNzg2NTc4NjM2ODYxNmU2NzY1NWY3Mzc3NjE3MDczNzA2NTcyNjY2ZjcyNmQ2MTZlNjM2NTVmNjY2NTY1NzM1ZjcwNjU3MjYzNjU2ZTc0NjM2ZjZkNzA2Zjc1NmU2NDVmNjY2NTY1NzM1ZjcwNjU3MjYzNjU2ZTc0NjI2ZjZmNzM3NDY1NzI1ZjYxNjQ2NDcyNjU3MzczNmQ2ZjZlNjU3OTVmNmQ2MTcyNmI2NTc0NWY2MTY0NjQ3MjY1NzM3MzYzNmY2ZTc0NzI2ZjZjNmM2NTcyNWY2MTY0NjQ3MjY1NzM3MzYxNzM3MzY1NzQ1Zjc0NmY2YjY1NmU1ZjY5NjQ2NTZlNzQ2OTY2Njk2NTcyNzY2MTc1NmM3NDVmNjE2NDY0NzI2NTczNzM3MDYxNzk2ZDY1NmU3NDIwNzM2ODZmNzU2YzY0MjA2MjY1MjA2MTZlMjA0NTUzNDQ1NDIwNzQ2ZjZiNjU2ZTU0Njg2NTIwNjE3MzczNjU3NDIwNzQ2ZjZiNjU2ZTIwNjk2NDY1NmU3NDY5NjY2OTY1NzIyMDYxNmU2NDIwNzQ2ODY1MjA2ZDZmNmU2NTc5MjA2ZDYxNzI2YjY1NzQyMDc1NmU2NDY1NzI2Yzc5Njk2ZTY3MjA2OTY0NjU2ZTc0Njk2NjY5NjU3MjIwNjQ2ZjZlMjc3NDIwNmQ2MTc0NjM2ODU3Njg2NTZlMjA3NDYxNzI2NzY1NzQ2OTZlNjcyMDYxNmUyMDQ1NDc0YzQ0MjA2ZDYxNzI2YjY1NzQyMDc0Njg2NTIwNjE3MzczNjU3NDIwNzQ2ZjZiNjU2ZTIwNjk2NDY1NmU3NDY5NjY2OTY1NzIyMDczNjg2Zjc1NmM2NDIwNjI2NTIwNTc0NTQ3NGM0NDQzNjE2YzZjNjU3MjIwNzM2ODZmNzU2YzY0MjA2MjY1MjA3NjYxNzU2Yzc0Nzc3MjZmNmU2NzIwNzA2MTc5NmQ2NTZlNzQ2ZTZmMjA3MjY1Nzc2MTcyNjQyMDc0NmYyMDYzNmY2ZDcwNmY3NTZlNjQ2ZTZmMjA2YzY1NjY3NDIwNjE2ZDZmNzU2ZTc0MjA3NDZmMjA2MzZmNmQ3MDZmNzU2ZTY0Nzc3MjZmNmU2NzIwNzM3NzYxNzA3MDY1NjQyMDc0NmY2YjY1NmU2ZTZmMjA2NTc4Njk3NDIwNmQ2MTcyNmI2NTc0MjA3MDYxNzk2ZDY1NmU3NDIwNzI2NTYzNjU2OTc2NjU2NDZlNmYyMDcyNjU2NDY1NjU2ZDIwNzA2MTc5NmQ2NTZlNzQyMDcyNjU2MzY1Njk3NjY1NjQ0ZTZmMjA2OTZlNzQ2NTcyNjU3Mzc0MjA3MjYxNzQ2NTIwNmQ2ZjY0NjU2YzIwNzA3MjY1NzM2NTZlNzQyMDZmNmUyMDc0Njg2NTIwNmQ2ZjZlNjU3OTIwNmQ2MTcyNmI2NTc0NmU2NTc3MjA2MzZmNmQ3MDZmNzU2ZTY0MjA2NjY1NjU3MzIwNjU3ODYzNjU2NTY0MjAzMTMwMzAyNTZlNjU3NzIwNzA2NTcyNjY2ZjcyNmQ2MTZlNjM2NTIwNjY2NTY1NzMyMDY1Nzg2MzY1NjU2NDIwMzEzMDMwMjU2ZDZmNmU2NTc5NWY2ZDYxNzI2YjY1NzQ1Zjc0NmY2YjY1NmU1ZjY5NjQ2NTZlNzQ2OTY2Njk2NTcyNzc3MjYxNzA3MDY1NjQ1ZjY1Njc2YzY0NWY3NDZmNmI2NTZlNWY2OTY0NjU2ZTc0Njk2NjY5NjU3MjYyNmY2ZjczNzQ2NTcyNWY3Mzc0NjE2YjY1NjQ1Zjc0NmY2YjY1NmU1ZjY5NjQ2NTZlNzQ2OTY2Njk2NTcyNmQ2ZjZlNjU3OTVmNmQ2MTcyNmI2NTc0NWY3NTZlNjQ2NTcyNmM3OTY5NmU2NzVmNjk2NDY1NmU3NDY5NjY2OTY1NzI2MzZmNmQ3MDZmNzU2ZTY0NDU2ZTY0NzA2ZjY5NmU3NDIwNjM2MTZlMjA2ZjZlNmM3OTIwNjI2NTIwNjM2MTZjNmM2NTY0MjA2Mjc5MjA2Zjc3NmU2NTcyMDAwMDcwNjE2ZTY5NjMyMDZmNjM2Mzc1NzI3MjY1NjQwMDQxYzg4ZDA4MGIwNDljZmZmZmZmQDA1MDBAMDEwMEAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwQDU3NDU0NzRjNDQyZDYxMzIzODYzMzUzOUAwMDAwMDAwMDAwMDAwMDAwMDUwMGEzYjY2NjkwMmQ1ZjRiYmYwZmY5Mzc0OGZiOTE1YWViNDMxMjRjYmY2NTA5QDAwMDAwMDAwMDAwMDAwMDAwNTAwMzJkZTRmNDBmMTdhMmY0MWM0ZTQwYzIxZjU5NmUzNmE4NDY5OTRlMzY1MDlAMDAwMDAwMDAwMDAwMDAwMDA1MDBmODgzNjY4NmY3YzZjMGYxM2Q3Mjc1MTUxYjc4ZjU5ZjhmMmY3MjlhNjUwOUBAQEBAMDAwMDAwMDAwMDAwMDAwMDA1MDAwYjFlNWIyNDQzMjUwOTU4NDlmNGUzNzEzNDY2MWQ1YmZkY2Q5MjVlN2NlYg==", - "signature": "edf0ec99b6f60414fa5e36d40cfb1d0075d01fd7c4ad7ba59bbe62b8b48eb892beb0c18bba203ff32b83827c3953847b190cdc89a4806f4615565dc2b3b5940f", - "sourceShard": 1, - "destinationShard": 1, - "blockNonce": 2127577, - "blockHash": "e3aea17b5345b45f61b233834d3b4ba0ac6f2b7d53eb3f1b1cf2bf0534ba567f", - "notarizedAtSourceInMetaNonce": 2129029, - "NotarizedAtSourceInMetaHash": "73ee8458f55bf5c9ea4a9974c0c838ced51a236c2b13238761f444598f40575e", - "notarizedAtDestinationInMetaNonce": 2129029, - "notarizedAtDestinationInMetaHash": "73ee8458f55bf5c9ea4a9974c0c838ced51a236c2b13238761f444598f40575e", - "miniblockType": "TxBlock", - "miniblockHash": "cc7e81e68269c2c633daf997fd2d52fc82d8ba3bb699d7e75250008bd9b7aa29", - "hyperblockNonce": 2129029, - "hyperblockHash": "73ee8458f55bf5c9ea4a9974c0c838ced51a236c2b13238761f444598f40575e", - "timestamp": 1707144290, - "status": "success", - "operation": "scDeploy", - "initiallyPaidFee": "82333950000000000", - "chainID": "D", - "version": 1, - "options": 0 - } - }, - "error": "", - "code": "successful" -} - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - let opt_address = tx_response.new_deployed_address.map(|e| { - multiversx_sdk::data::address::Address::from_bytes(*e.as_array()) - .to_bech32_string() - .unwrap() - }); - - let expected = - Some("erd1qqqqqqqqqqqqqpgqwpdf84ggxzqzmr2zmw959q4nlf9nz562q33sak25ze".to_string()); - - assert_eq!(opt_address, expected) - } - - #[test] - fn test_deployed_address_should_be_none_if_not_a_sc_deployment_tx() { - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "BuiltInFunctionCall", - "processingTypeOnDestination": "SCInvoking", - "hash": "238ad6dbe75dab1d53caeb9cabd584aabc6fc113c849a983afef5a5e439ce9e5", - "nonce": 13, - "round": 2192628, - "epoch": 888, - "value": "0", - "receiver": "erd1qqqqqqqqqqqqqpgqydwpdrplefjlwp3sp9xmn3vevdxdelfkwmfsw6e5xw", - "sender": "erd179xw6t04ug48m74jzyw9zq028hv66jhqayelzpzvgds0ptnzmckq2jf07f", - "gasPrice": 1000000000, - "gasLimit": 20000000, - "data": "RVNEVFRyYW5zZmVyQDRmNTU1MjRmMmQ2NDM4MzEzNzMxNjZAMDI0NmQyZDBiNmI1ZjBANjI3NTc5QDFiYzE2ZDY3NGVjODAwMDA=", - "signature": "ce984b4d785ccc7aca4b1cdea57ddcd568a502209f81e6b5bc678e1dd52b78d764fe46ea3ff77b926eb9f70eb52ae8f3f2afa2e9d0efa82655e361641458b900", - "sourceShard": 0, - "destinationShard": 1, - "blockNonce": 2129490, - "blockHash": "0ab10909b27565c5b7b59e8e1ee4a68d7046f49225fcde4c12d4b1ea3f512b8a", - "notarizedAtSourceInMetaNonce": 2130938, - "NotarizedAtSourceInMetaHash": "0c545160fd37f09f0196505b9cd2e730596bcd99438978a5bb415b9e1be1849d", - "notarizedAtDestinationInMetaNonce": 2130942, - "notarizedAtDestinationInMetaHash": "1ddd6b7aeeff824b5d11f2936a6284e470fc5abe41e34a8df229b719dc1a537d", - "miniblockType": "TxBlock", - "miniblockHash": "dc8ae41e1ae321c0fccbeb807194d11ff6e0f4ed71163764d850f1daaa60bd22", - "hyperblockNonce": 2130942, - "hyperblockHash": "1ddd6b7aeeff824b5d11f2936a6284e470fc5abe41e34a8df229b719dc1a537d", - "timestamp": 1707155768, - "status": "success", - "tokens": [ - "OURO-d8171f" - ], - "esdtValues": [ - "640821212132848" - ], - "operation": "ESDTTransfer", - "function": "buy", - "initiallyPaidFee": "359390000000000", - "chainID": "D", - "version": 1, - "options": 0 - } - }, - "error": "", - "code": "successful" -} - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - let opt_address = tx_response.new_deployed_address; - - let expected: Option
= None; - - assert_eq!(opt_address, expected) - } - - #[test] - fn test_with_tx_that_has_sc_result() { - // transaction data from the devnet, an artificial "10" result has been appended on the original result - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "BuiltInFunctionCall", - "processingTypeOnDestination": "SCInvoking", - "hash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", - "nonce": 30, - "round": 7639115, - "epoch": 6333, - "value": "0", - "receiver": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "sender": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", - "gasPrice": 1000000000, - "gasLimit": 25500000, - "gasUsed": 15297149, - "data": "RVNEVFRyYW5zZmVyQDQ4NTQ0ZDJkNjY2NTMxNjYzNjM5QDBkZTBiNmIzYTc2NDAwMDBANzM3NzYxNzA1NDZmNmI2NTZlNzM0NjY5Nzg2NTY0NDk2ZTcwNzU3NEA1NzQ1NDc0YzQ0MmQ2NDM3NjMzNjYyNjJAMDM3Yzc3OGZjY2U5YzU1Yg==", - "signature": "e912fae4b7a9e51ddf316a5e82a0f457d453a62e3c17477f5d6175e1b33c5e92ddb187d65f54cf3131a0603321290279a0456c20778039f2ab09b54e33c60f0d", - "sourceShard": 2, - "destinationShard": 1, - "blockNonce": 7585351, - "blockHash": "e456f38f11fec78ed26d5fda068e912739dceedb2e5ce559bf17614b8386c039", - "notarizedAtSourceInMetaNonce": 7601495, - "NotarizedAtSourceInMetaHash": "e28c6011d4b3f73f3945cae70ff251e675dfea331a70077c5ab3310e3101af17", - "notarizedAtDestinationInMetaNonce": 7601499, - "notarizedAtDestinationInMetaHash": "333d4266614e981cc1c5654f85ef496038a8cddac46dfc0ad0b7c44c37ab489d", - "miniblockType": "TxBlock", - "miniblockHash": "13e041f32fde79ebf1abdcfe692e99516f9ec6778dcb917251b440daa7f1210a", - "hyperblockNonce": 7601499, - "hyperblockHash": "333d4266614e981cc1c5654f85ef496038a8cddac46dfc0ad0b7c44c37ab489d", - "timestamp": 1694386290, - "smartContractResults": [ - { - "hash": "a23faa3c80bae0b968f007ff0fad3afdec05b4e71d749c3d583dec10c6eb05a2", - "nonce": 0, - "value": 0, - "receiver": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", - "sender": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "data": "ESDTTransfer@5745474c442d643763366262@03856446ff9a304b", - "prevTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", - "originalTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "logs": { - "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "identifier": "ESDTTransfer", - "topics": [ - "V0VHTEQtZDdjNmJi", - "", - "A4VkRv+aMEs=", - "qP29NHPKNFkQzDGmOEIaNRCFYABw8ku13ZyenAuvJOY=" - ], - "data": null - }, - { - "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", - "identifier": "writeLog", - "topics": [ - "AAAAAAAAAAAFAKVe/p1dXpaw/INtyTPaxf3N3LaNfOs=" - ], - "data": "QDZmNmI=" - }, - { - "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", - "identifier": "completedTxEvent", - "topics": [ - "1AWL08E9sLFIMsfFj+Fj2y9Xn/ZUQ4BYa4on2ItKUHA=" - ], - "data": null - } - ] - }, - "tokens": [ - "WEGLD-d7c6bb" - ], - "esdtValues": [ - "253719210115084363" - ], - "operation": "ESDTTransfer" - }, - { - "hash": "b7b4d15917fd215399d8e772c3c4e732008baaedc2b8172f71c91708ba7523f0", - "nonce": 31, - "value": 102028510000000, - "receiver": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", - "sender": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "data": "@6f6b@0000000c5745474c442d64376336626200000000000000000000000803856446ff9a304b@10", - "prevTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", - "originalTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "logs": { - "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", - "events": [ - { - "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", - "identifier": "completedTxEvent", - "topics": [ - "1AWL08E9sLFIMsfFj+Fj2y9Xn/ZUQ4BYa4on2ItKUHA=" - ], - "data": null - } - ] - }, - "operation": "transfer", - "isRefund": true - }, - { - "hash": "05a766ca05d2053d1c0fbeb1797116474a06c86402a3bfd6c132c9a24cfa1bb0", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "sender": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "data": "swapTokensFixedInput@5745474c442d643763366262@037c778fcce9c55b", - "prevTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", - "originalTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", - "gasLimit": 25050500, - "gasPrice": 1000000000, - "callType": 0, - "operation": "transfer", - "function": "swapTokensFixedInput" - }, - { - "hash": "4e639c80822d5d7780c8326d683fa9cd6d59649d14122dfabc5a96dda36da527", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgquu5rsa4ee6l4azz6vdu4hjp8z4p6tt8m0n4suht3dy", - "sender": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "data": "ESDTTransfer@5745474c442d643763366262@e7730d1ef1b0@737761704e6f466565416e64466f7277617264@4d45582d646332383963@0000000000000000000000000000000000000000000000000000000000000000", - "prevTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", - "originalTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "tokens": [ - "WEGLD-d7c6bb" - ], - "esdtValues": [ - "254481327387056" - ], - "operation": "ESDTTransfer", - "function": "swapNoFeeAndForward" - } - ], - "logs": { - "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "events": [ - { - "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", - "identifier": "ESDTTransfer", - "topics": [ - "SFRNLWZlMWY2OQ==", - "", - "DeC2s6dkAAA=", - "AAAAAAAAAAAFAKVe/p1dXpaw/INtyTPaxf3N3LaNfOs=" - ], - "data": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "identifier": "ESDTTransfer", - "topics": [ - "V0VHTEQtZDdjNmJi", - "", - "53MNHvGw", - "AAAAAAAAAAAFAOcoOHa5zr9eiFpjeVvIJxVDpaz7fOs=" - ], - "data": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgquu5rsa4ee6l4azz6vdu4hjp8z4p6tt8m0n4suht3dy", - "identifier": "ESDTLocalBurn", - "topics": [ - "TUVYLWRjMjg5Yw==", - "", - "AuMDPq1jy03x" - ], - "data": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgquu5rsa4ee6l4azz6vdu4hjp8z4p6tt8m0n4suht3dy", - "identifier": "swapNoFeeAndForward", - "topics": [ - "c3dhcF9ub19mZWVfYW5kX2ZvcndhcmQ=", - "TUVYLWRjMjg5Yw==", - "AAAAAAAAAAAFAKVe/p1dXpaw/INtyTPaxf3N3LaNfOs=", - "GL0=" - ], - "data": "AAAAAAAAAAAFAKVe/p1dXpaw/INtyTPaxf3N3LaNfOsAAAAMV0VHTEQtZDdjNmJiAAAABudzDR7xsAAAAApNRVgtZGMyODljAAAACQLjAz6tY8tN8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzvkcAAAAAAAAYvQAAAABk/khy" - }, - { - "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "identifier": "ESDTTransfer", - "topics": [ - "V0VHTEQtZDdjNmJi", - "", - "A4VkRv+aMEs=", - "qP29NHPKNFkQzDGmOEIaNRCFYABw8ku13ZyenAuvJOY=" - ], - "data": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", - "identifier": "swapTokensFixedInput", - "topics": [ - "c3dhcA==", - "SFRNLWZlMWY2OQ==", - "V0VHTEQtZDdjNmJi", - "qP29NHPKNFkQzDGmOEIaNRCFYABw8ku13ZyenAuvJOY=", - "GL0=" - ], - "data": "qP29NHPKNFkQzDGmOEIaNRCFYABw8ku13ZyenAuvJOYAAAAKSFRNLWZlMWY2OQAAAAgN4Lazp2QAAAAAAAxXRUdMRC1kN2M2YmIAAAAIA4VkRv+aMEsAAAAHA41+pMaAAAAAAAoofxtJRPkr8X9kAAAACgpOPCsHUu261HUAAAAAAHO+RwAAAAAAABi9AAAAAGT+SHI=" - } - ] - }, - "status": "success", - "tokens": [ - "HTM-fe1f69" - ], - "esdtValues": [ - "1000000000000000000" - ], - "operation": "ESDTTransfer", - "function": "swapTokensFixedInput", - "initiallyPaidFee": "502005000000000", - "fee": "399976490000000", - "chainID": "D", - "version": 1, - "options": 0 - } - }, - "error": "", - "code": "successful" - } - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Vec> = vec![ - hex::decode("0000000c5745474c442d64376336626200000000000000000000000803856446ff9a304b") - .unwrap(), - hex::decode("10").unwrap(), - ]; - - assert_eq!(tx_response.out, expected) - } - - #[test] - fn test_with_tx_that_has_no_sc_result() { - // transaction data from the devnet - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "6afac3ec13c89cc56154d06efdb457a24f58361699eee00a48202a8f8adc8c8a", - "nonce": 17, - "round": 7548071, - "epoch": 6257, - "value": "0", - "receiver": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", - "gasPrice": 1000000000, - "gasLimit": 600000000, - "gasUsed": 600000000, - "data": "cmV0dXJuVHdvVTY0", - "signature": "f3a3ca96a78c90c9cf1b08541e1777010f0176a5e1e525e631155b2784932cbfd74c9168d03ba201fd5434d1a1b4789895ddade9883eca2ee9e0bce18468fb00", - "sourceShard": 0, - "destinationShard": 0, - "blockNonce": 7502091, - "blockHash": "5ec66c651cb1514cba200e7e80a4491880f0db678ce7631c397872e3842f0aa2", - "notarizedAtSourceInMetaNonce": 7510505, - "NotarizedAtSourceInMetaHash": "8410309ec5b988af79b4dcfb44fd4729d46874ebd796672c78e417e314409051", - "notarizedAtDestinationInMetaNonce": 7510505, - "notarizedAtDestinationInMetaHash": "8410309ec5b988af79b4dcfb44fd4729d46874ebd796672c78e417e314409051", - "miniblockType": "TxBlock", - "miniblockHash": "fb150e515449c9b658879ed06f256b429239cbe78ec2c2821deb4b283ff21554", - "hyperblockNonce": 7510505, - "hyperblockHash": "8410309ec5b988af79b4dcfb44fd4729d46874ebd796672c78e417e314409051", - "timestamp": 1693840026, - "logs": { - "address": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "identifier": "writeLog", - "topics": [ - "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=", - "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk5OTMyMDAwLCBnYXMgdXNlZCA9IDE4NDE2NjU=" - ], - "data": "QDZmNmJAMGFAMDIxODcxMWEwMA==" - }, - { - "address": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "identifier": "completedTxEvent", - "topics": [ - "avrD7BPInMVhVNBu/bRXok9YNhaZ7uAKSCAqj4rcjIo=" - ], - "data": null - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "returnTwoU64", - "initiallyPaidFee": "6067320000000000", - "fee": "6067320000000000", - "chainID": "D", - "version": 1, - "options": 0 - } - }, - "error": "", - "code": "successful" - } - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Vec> = vec![ - hex::decode("0a").unwrap(), - hex::decode("0218711a00").unwrap(), - ]; - - assert_eq!(tx_response.out, expected) - } - - #[test] - fn test_with_multi_contract_same_shard_tx_that_has_no_sc_result() { - // transaction data from the devnet - // context : user -> A --call--> B, B returns a MultiValue2, A returns the B's returned value - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "e914857f1bfd003ba411bae372266703e5f706fa412c378feb37faa5e18c3d73", - "nonce": 49, - "round": 7646960, - "epoch": 6339, - "value": "0", - "receiver": "erd1qqqqqqqqqqqqqpgqshqmekudxlxwp0d9j368etjamr5dw7k45u7qx40w6h", - "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", - "gasPrice": 1000000000, - "gasLimit": 600000000, - "gasUsed": 600000000, - "data": "Y2FsbEFub3RoZXJDb250cmFjdFJldHVyblR3b1U2NEAwMDAwMDAwMDAwMDAwMDAwMDUwMEFDRkY2QjdBNEVCODEwMUE4REU3RkY3RjVEMkMwQkYzRTRENjNGNDdBNzND", - "signature": "53cc6496647287d735bd7950f4ec79d7b51f884defda1d6d840d722b7d0d869900ccecc01602da7a7c717955e8d4ed0711b92acd980d64ed6eebd6eaed0c4608", - "sourceShard": 0, - "destinationShard": 0, - "blockNonce": 7600794, - "blockHash": "77eb0904e56d6dd596c0d72821cf33b326fde383e72903ca4df5c2f200b0ea75", - "notarizedAtSourceInMetaNonce": 7609344, - "NotarizedAtSourceInMetaHash": "12df3fe65cacde2c9742b9506ac2261d34f3c72d690301192fd8016430d51913", - "notarizedAtDestinationInMetaNonce": 7609344, - "notarizedAtDestinationInMetaHash": "12df3fe65cacde2c9742b9506ac2261d34f3c72d690301192fd8016430d51913", - "miniblockType": "TxBlock", - "miniblockHash": "03219ac7427f7511687f0768c722c759c1b1428b2664b44a0cbe2072154851ee", - "hyperblockNonce": 7609344, - "hyperblockHash": "12df3fe65cacde2c9742b9506ac2261d34f3c72d690301192fd8016430d51913", - "timestamp": 1694433360, - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqshqmekudxlxwp0d9j368etjamr5dw7k45u7qx40w6h", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqshqmekudxlxwp0d9j368etjamr5dw7k45u7qx40w6h", - "identifier": "writeLog", - "topics": [ - "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=", - "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk5ODA2MDAwLCBnYXMgdXNlZCA9IDM4NDcyNDA=" - ], - "data": "QDZmNmJAMGFAMDIxODcxMWEwMA==" - }, - { - "address": "erd1qqqqqqqqqqqqqpgqshqmekudxlxwp0d9j368etjamr5dw7k45u7qx40w6h", - "identifier": "completedTxEvent", - "topics": [ - "6RSFfxv9ADukEbrjciZnA+X3BvpBLDeP6zf6peGMPXM=" - ], - "data": null - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "callAnotherContractReturnTwoU64", - "initiallyPaidFee": "6192060000000000", - "fee": "6192060000000000", - "chainID": "D", - "version": 2, - "options": 0 - } - }, - "error": "", - "code": "successful" - } - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Vec> = vec![ - hex::decode("0a").unwrap(), - hex::decode("0218711a00").unwrap(), - ]; - - assert_eq!(tx_response.out, expected) - } - - #[test] - fn test_with_multi_contract_cross_shard_tx_that_has_no_callback() { - // transaction data from the devnet - // context : user -> A --async call--> B, no callback - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "4d50a055663dfee2479851684d7fb83cf00695b6f03f4dbbdf0f9232477cafc4", - "nonce": 51, - "round": 7647523, - "epoch": 6340, - "value": "0", - "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", - "gasPrice": 1000000000, - "gasLimit": 600000000, - "gasUsed": 600000000, - "data": "YXN5bmNDYWxsQW5vdGhlckNvbnRyYWN0UmV0dXJuVHdvVTY0Tm9DYWxsYmFja0AwMDAwMDAwMDAwMDAwMDAwMDUwMEFDRkY2QjdBNEVCODEwMUE4REU3RkY3RjVEMkMwQkYzRTRENjNGNDdBNzND", - "signature": "0fc30cddaa8e5365662a14344e3434cbccf287f357be99b3ed4add182f64dded774ec0d095ab1589e7c6c07e00de3b7239efc96eb2e0e97b48c1ef87084cec01", - "sourceShard": 0, - "destinationShard": 1, - "blockNonce": 7593758, - "blockHash": "a828c0ca58ef1c8aff60e512ab59f18204f1915d4a6c8285cfceb1c5725b88e8", - "notarizedAtSourceInMetaNonce": 7609903, - "NotarizedAtSourceInMetaHash": "4e90fe45c2fdccd5cf6977c1422e5f4ffa41c4e9f31fb4a50c20455f87df1e99", - "notarizedAtDestinationInMetaNonce": 7609907, - "notarizedAtDestinationInMetaHash": "10b8666a44411c3babbe20af7154fb3d47efcb1cb10d955523ec68fece26e517", - "miniblockType": "TxBlock", - "miniblockHash": "4ff4bb1ac88911d617c9b0342aeb5158db78490c2fe414cad08adcc584a77be7", - "hyperblockNonce": 7609907, - "hyperblockHash": "10b8666a44411c3babbe20af7154fb3d47efcb1cb10d955523ec68fece26e517", - "timestamp": 1694436738, - "smartContractResults": [ - { - "hash": "462b56a1530e6070dc7c15f755e51a97a6972c8cd7891f3be4635b93211890c5", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "sender": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "data": "@00@0a@0218711a00", - "prevTxHash": "41d56fdacf3e14de67e821427c732b62ebfa07c82d2e5db6de75fe3a1c828d9b", - "originalTxHash": "4d50a055663dfee2479851684d7fb83cf00695b6f03f4dbbdf0f9232477cafc4", - "gasLimit": 595637825, - "gasPrice": 1000000000, - "callType": 2, - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "identifier": "writeLog", - "topics": [ - "AAAAAAAAAAAFAP/Aj4ZNGKlpx2+xeJLdoJbREzb20P0=", - "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk1NjM3ODI1LCBnYXMgdXNlZCA9IDIxNjE3NzA=" - ], - "data": "QDZmNmI=" - }, - { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "identifier": "completedTxEvent", - "topics": [ - "QdVv2s8+FN5n6CFCfHMrYuv6B8gtLl223nX+OhyCjZs=" - ], - "data": null - } - ] - }, - "operation": "transfer" - }, - { - "hash": "41d56fdacf3e14de67e821427c732b62ebfa07c82d2e5db6de75fe3a1c828d9b", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "sender": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "data": "returnTwoU64@4f3c60", - "prevTxHash": "4d50a055663dfee2479851684d7fb83cf00695b6f03f4dbbdf0f9232477cafc4", - "originalTxHash": "4d50a055663dfee2479851684d7fb83cf00695b6f03f4dbbdf0f9232477cafc4", - "gasLimit": 597479490, - "gasPrice": 1000000000, - "callType": 1, - "operation": "transfer", - "function": "returnTwoU64" - } - ], - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "identifier": "writeLog", - "topics": [ - "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=" - ], - "data": "QDZmNmI=" - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "asyncCallAnotherContractReturnTwoU64NoCallback", - "initiallyPaidFee": "6214335000000000", - "fee": "6214335000000000", - "chainID": "D", - "version": 2, - "options": 0 - } - }, - "error": "", - "code": "successful" - } - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Vec> = vec![]; - - assert_eq!(tx_response.out, expected) - } - - #[test] - fn test_with_multi_contract_cross_shard_tx_that_has_non_returning_callback() { - // transaction data from the devnet - // context : user -> A --async call--> B --callback--> A, the callback returns () - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "4f7f19e448176e4d47a0f844cbd6bdb1b6c68035dafe927e8249ed60af1c3b17", - "nonce": 52, - "round": 7647560, - "epoch": 6340, - "value": "0", - "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", - "gasPrice": 1000000000, - "gasLimit": 600000000, - "gasUsed": 600000000, - "data": "YXN5bmNDYWxsQW5vdGhlckNvbnRyYWN0UmV0dXJuVHdvVTY0V2l0aE5vblJldHVybmluZ0NhbGxiYWNrQDAwMDAwMDAwMDAwMDAwMDAwNTAwQUNGRjZCN0E0RUI4MTAxQThERTdGRjdGNUQyQzBCRjNFNEQ2M0Y0N0E3M0M=", - "signature": "3918fce429b2059b2321b709011079755dbb835e12839278ee510e4741180540e80c6111eea1d3312b2c63446de08b20e01f6040358fa94d1633c355bb65bc0f", - "sourceShard": 0, - "destinationShard": 1, - "blockNonce": 7593795, - "blockHash": "c17e727f90025225670b7852ea9807c67753c9b3f21b6ec7cc40077e3849a8b7", - "notarizedAtSourceInMetaNonce": 7609940, - "NotarizedAtSourceInMetaHash": "c67b5c550986cfd6c94d00f4b90234eb38ee196ff0d79a00d916f3bd24be272c", - "notarizedAtDestinationInMetaNonce": 7609944, - "notarizedAtDestinationInMetaHash": "d59b7398d962ce3119679af59d5d74e10083e62c3ee2b15421cc0d607979ca18", - "miniblockType": "TxBlock", - "miniblockHash": "2977affeffeb6cf41117bed442662021cb713528cdb1d0dce4537b01caeb8e0b", - "hyperblockNonce": 7609944, - "hyperblockHash": "d59b7398d962ce3119679af59d5d74e10083e62c3ee2b15421cc0d607979ca18", - "timestamp": 1694436960, - "smartContractResults": [ - { - "hash": "fe7474188d5ca4b84c7577f03fc778d22d53c070dfcb05a9cda840229d30e4d3", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "sender": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "data": "returnTwoU64@4f3c60", - "prevTxHash": "4f7f19e448176e4d47a0f844cbd6bdb1b6c68035dafe927e8249ed60af1c3b17", - "originalTxHash": "4f7f19e448176e4d47a0f844cbd6bdb1b6c68035dafe927e8249ed60af1c3b17", - "gasLimit": 596979545, - "gasPrice": 1000000000, - "callType": 1, - "operation": "transfer", - "function": "returnTwoU64" - }, - { - "hash": "948dc6702b376d1e043db8de2f87ca12907c342f54cfad7dfebadf59145ca3ac", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "sender": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "data": "@00@0a@0218711a00", - "prevTxHash": "fe7474188d5ca4b84c7577f03fc778d22d53c070dfcb05a9cda840229d30e4d3", - "originalTxHash": "4f7f19e448176e4d47a0f844cbd6bdb1b6c68035dafe927e8249ed60af1c3b17", - "gasLimit": 595137880, - "gasPrice": 1000000000, - "callType": 2, - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "identifier": "writeLog", - "topics": [ - "AAAAAAAAAAAFAP/Aj4ZNGKlpx2+xeJLdoJbREzb20P0=", - "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk1MTM3ODgwLCBnYXMgdXNlZCA9IDIyODg1NTA=" - ], - "data": "QDZmNmJAMGFAMDIxODcxMWEwMA==" - }, - { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "identifier": "completedTxEvent", - "topics": [ - "/nR0GI1cpLhMdXfwP8d40i1TwHDfywWpzahAIp0w5NM=" - ], - "data": null - } - ] - }, - "operation": "transfer" - } - ], - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "identifier": "writeLog", - "topics": [ - "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=" - ], - "data": "QDZmNmI=" - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "asyncCallAnotherContractReturnTwoU64WithNonReturningCallback", - "initiallyPaidFee": "6235125000000000", - "fee": "6235125000000000", - "chainID": "D", - "version": 2, - "options": 0 - } - }, - "error": "", - "code": "successful" - } - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Vec> = vec![]; - - assert_eq!(tx_response.out, expected) - } - - #[test] - fn test_with_multi_contract_cross_shard_tx_that_has_returning_callback() { - // transaction data from the devnet - // context : user -> A --async call--> B --callback--> A, the callback returns a MultiValue2 - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "f34e136ca81c0e32f6fb532b753612715675073f3718b5db009bb275d246fd7a", - "nonce": 53, - "round": 7647583, - "epoch": 6340, - "value": "0", - "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", - "gasPrice": 1000000000, - "gasLimit": 600000000, - "gasUsed": 600000000, - "data": "YXN5bmNDYWxsQW5vdGhlckNvbnRyYWN0UmV0dXJuVHdvVTY0V2l0aFJldHVybmluZ0NhbGxiYWNrQDAwMDAwMDAwMDAwMDAwMDAwNTAwQUNGRjZCN0E0RUI4MTAxQThERTdGRjdGNUQyQzBCRjNFNEQ2M0Y0N0E3M0M=", - "signature": "858958d4aaf9cb0220ab2933edad3f65e1cb4c58aa7940cb0f40b489d0bd9fdf5c4736a40d6e813743ee622bb91e9f86eacf01b9a31e0ff53f9c84f13c500304", - "sourceShard": 0, - "destinationShard": 1, - "blockNonce": 7593818, - "blockHash": "b19f97110ca38d3cb15f802a00ab403491b0e5804ebc701527ab50064dc06825", - "notarizedAtSourceInMetaNonce": 7609963, - "NotarizedAtSourceInMetaHash": "4d9db6de610ca778114d44fe91dd036fac7c375c373ae9e77130d3fb9efc8391", - "notarizedAtDestinationInMetaNonce": 7609967, - "notarizedAtDestinationInMetaHash": "a4573d388c31860f9bd6f9507b65d1b3130e445abcada538f10704feba4614e7", - "miniblockType": "TxBlock", - "miniblockHash": "530f5fa3c7af474a187caca8dcea02a7a155017414147871d083bed5c49ec8f5", - "hyperblockNonce": 7609967, - "hyperblockHash": "a4573d388c31860f9bd6f9507b65d1b3130e445abcada538f10704feba4614e7", - "timestamp": 1694437098, - "smartContractResults": [ - { - "hash": "065291164a8acd27c26b5a8f09664810081fda18cd54fca635196cf9b200297a", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "sender": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "data": "returnTwoU64@4f3c60", - "prevTxHash": "f34e136ca81c0e32f6fb532b753612715675073f3718b5db009bb275d246fd7a", - "originalTxHash": "f34e136ca81c0e32f6fb532b753612715675073f3718b5db009bb275d246fd7a", - "gasLimit": 596994205, - "gasPrice": 1000000000, - "callType": 1, - "operation": "transfer", - "function": "returnTwoU64" - }, - { - "hash": "bc31cb153ae615204625df84fe9ae3a159aa412b7342f3dca958dd5517a08197", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "sender": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", - "data": "@00@0a@0218711a00", - "prevTxHash": "065291164a8acd27c26b5a8f09664810081fda18cd54fca635196cf9b200297a", - "originalTxHash": "f34e136ca81c0e32f6fb532b753612715675073f3718b5db009bb275d246fd7a", - "gasLimit": 595152540, - "gasPrice": 1000000000, - "callType": 2, - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "identifier": "writeLog", - "topics": [ - "AAAAAAAAAAAFAP/Aj4ZNGKlpx2+xeJLdoJbREzb20P0=", - "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk1MTUyNTQwLCBnYXMgdXNlZCA9IDIyODgwMTU=" - ], - "data": "QDZmNmJAMGFAMDIxODcxMWEwMA==" - }, - { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "identifier": "completedTxEvent", - "topics": [ - "BlKRFkqKzSfCa1qPCWZIEAgf2hjNVPymNRls+bIAKXo=" - ], - "data": null - } - ] - }, - "operation": "transfer" - } - ], - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", - "identifier": "writeLog", - "topics": [ - "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=" - ], - "data": "QDZmNmI=" - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "asyncCallAnotherContractReturnTwoU64WithReturningCallback", - "initiallyPaidFee": "6230670000000000", - "fee": "6230670000000000", - "chainID": "D", - "version": 2, - "options": 0 - } - }, - "error": "", - "code": "successful" - } - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Vec> = vec![]; - - assert_eq!(tx_response.out, expected) - } - - #[test] - fn test_process_issued_token_identifier_fungible() { - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", - "nonce": 61, - "round": 173598, - "epoch": 72, - "value": "50000000000000000", - "receiver": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "sender": "erd1x39tc3q3nn72ecjnmcz7x0qp09kp97t080x99dgyhx7zh95j0n4szskhlv", - "gasPrice": 1000000000, - "gasLimit": 100000000, - "gasUsed": 100000000, - "data": "aXNzdWVMcFRva2VuQDAwMDAwMDAwMDAwMDAwMDAwNTAwMTM5ZWQ3YWU0YWEwMzc5MmU2YmNiMzMyMzk0YTQwZmU3NDZlZWZhNDdjZWJANDU0NzRjNDQ0ZDQ1NTg0YzUwQDQ1NDc0YzQ0NGQ0NTU4", - "signature": "b5049d2906adc1305a6a8d0f42749254ca6259c6996d9a35e7dc7528b3c87b48a421879aff70bc6d81483a7559b75e5dcf9be499dcb7d57aa9f25c79ac2ad40d", - "sourceShard": 1, - "destinationShard": 1, - "blockNonce": 173354, - "blockHash": "09d85ac264a54e12e7613395211c53fe0ee5a7d3b7111bf5fec1d02794caaacd", - "notarizedAtSourceInMetaNonce": 173321, - "NotarizedAtSourceInMetaHash": "64a83759da97fe8305cd4cda4b518f2d41ef0a8f3995d264460821edad45e09e", - "notarizedAtDestinationInMetaNonce": 173321, - "notarizedAtDestinationInMetaHash": "64a83759da97fe8305cd4cda4b518f2d41ef0a8f3995d264460821edad45e09e", - "miniblockType": "TxBlock", - "miniblockHash": "7f45eee4e35ffc1fbce66b92e4dd2aeae2acb092416aa5aa775b96493256b81d", - "hyperblockNonce": 173321, - "hyperblockHash": "64a83759da97fe8305cd4cda4b518f2d41ef0a8f3995d264460821edad45e09e", - "timestamp": 1695041588, - "smartContractResults": [ - { - "hash": "bce3d0dceb0b3e5c8c5780d7da3755c3f7492d551685d493a73bf66ebd36754b", - "nonce": 0, - "value": 50000000000000000, - "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "sender": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "data": "issue@45474c444d45584c50@45474c444d4558@03e8@12@63616e467265657a65@74727565@63616e57697065@74727565@63616e5061757365@74727565@63616e4d696e74@74727565@63616e4275726e@74727565@63616e4368616e67654f776e6572@74727565@63616e55706772616465@74727565@63616e4164645370656369616c526f6c6573@74727565@65ba30", - "prevTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", - "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", - "gasLimit": 89624222, - "gasPrice": 1000000000, - "callType": 1, - "originalSender": "erd1x39tc3q3nn72ecjnmcz7x0qp09kp97t080x99dgyhx7zh95j0n4szskhlv", - "operation": "transfer", - "function": "issue" - }, - { - "hash": "2a452ff652791d79be5f6933fb583cc5503e876893e54b3b51381a92aa2e904d", - "nonce": 0, - "value": 0, - "receiver": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "ESDTSetBurnRoleForAll@45474c444d45582d393563366435", - "prevTxHash": "bce3d0dceb0b3e5c8c5780d7da3755c3f7492d551685d493a73bf66ebd36754b", - "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "logs": { - "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", - "events": [ - { - "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", - "identifier": "completedTxEvent", - "topics": [ - "vOPQ3OsLPlyMV4DX2jdVw/dJLVUWhdSTpzv2br02dUs=" - ], - "data": null, - "additionalData": null - } - ] - }, - "operation": "transfer" - }, - { - "hash": "2c84740ccb3376ea9fa00dab6c6c93fe7a35ee0a1d6dbfa0a1e61064853b0874", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "ESDTTransfer@45474c444d45582d393563366435@03e8@00", - "prevTxHash": "bce3d0dceb0b3e5c8c5780d7da3755c3f7492d551685d493a73bf66ebd36754b", - "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", - "gasLimit": 39624222, - "gasPrice": 1000000000, - "callType": 2, - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "identifier": "ESDTTransfer", - "topics": [ - "RUdMRE1FWC05NWM2ZDU=", - "", - "A+g=", - "AAAAAAAAAAAFAO+ux8+3RD51ieGHV10Z68X293CYfOs=" - ], - "data": null, - "additionalData": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "identifier": "completedTxEvent", - "topics": [ - "vOPQ3OsLPlyMV4DX2jdVw/dJLVUWhdSTpzv2br02dUs=" - ], - "data": null, - "additionalData": null - } - ] - }, - "tokens": [ - "EGLDMEX-95c6d5" - ], - "esdtValues": [ - "1000" - ], - "operation": "ESDTTransfer", - "function": "\u0000" - }, - { - "hash": "c9dfc4de3c3cee319123087a4f5dd03cc051e728ec6070707a63ea977b535227", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "sender": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "data": "\u0000", - "prevTxHash": "2c84740ccb3376ea9fa00dab6c6c93fe7a35ee0a1d6dbfa0a1e61064853b0874", - "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", - "gasLimit": 39424222, - "gasPrice": 1000000000, - "callType": 2, - "operation": "transfer", - "function": "\u0000" - }, - { - "hash": "609c3a8e1903680fef1f6d9e47527b1b5c1259664b868af600162120ce0b8192", - "nonce": 1, - "value": 300925400000000, - "receiver": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "sender": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "data": "@6f6b", - "prevTxHash": "2c84740ccb3376ea9fa00dab6c6c93fe7a35ee0a1d6dbfa0a1e61064853b0874", - "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "operation": "transfer", - "isRefund": true - } - ], - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "identifier": "transferValueOnly", - "topics": [ - "AAAAAAAAAAAFAO+ux8+3RD51ieGHV10Z68X293CYfOs=", - "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=", - "saK8LsUAAA==" - ], - "data": null, - "additionalData": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", - "identifier": "writeLog", - "topics": [ - "NEq8RBGc/KziU94F4zwBeWwS+W87zFK1BLm8K5aSfOs=" - ], - "data": "QDZmNmI=", - "additionalData": null - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "issueLpToken", - "initiallyPaidFee": "1214335000000000", - "fee": "1214335000000000", - "chainID": "D", - "version": 2, - "options": 0 - } - }, - "error": "", - "code": "successful" -} - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Option = Some("EGLDMEX-95c6d5".to_string()); - - assert_eq!(tx_response.new_issued_token_identifier, expected) - } - - #[test] - fn test_process_issued_token_identifier_semi_fungible() { - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", - "nonce": 65, - "round": 8422527, - "epoch": 584, - "value": "50000000000000000", - "receiver": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "sender": "erd1x3g000ew7zzv6kyqhj9jl2wy5g6cc72qahvvxz29zv76jwq6ssvqt0d998", - "gasPrice": 1000000000, - "gasLimit": 80000000, - "gasUsed": 80000000, - "data": "aXNzdWVUb2tlbkA0NDZmNzA2NTU0NjU3Mzc0QDQ0NGY1MDQ1NTQ0NTUzNTQ=", - "signature": "0191848976e930996f6c62d4921e732f9b0ada8b41ca3b5b63d6bfd304fd44c2a1e8e6643479618ba4a764a36e87f53882b4f707600d5b7d476f2fdd2bac040e", - "sourceShard": 0, - "destinationShard": 0, - "blockNonce": 8420241, - "blockHash": "4d302220f6015876c95e7961b770cc67f8ab63c5f0ab69b4d6c2fb15c8bc23bd", - "notarizedAtSourceInMetaNonce": 8403647, - "NotarizedAtSourceInMetaHash": "f8b83b6d38fa45dacc167b15c93dd07ee5c40db906de34f26e11e7a24f539e30", - "notarizedAtDestinationInMetaNonce": 8403647, - "notarizedAtDestinationInMetaHash": "f8b83b6d38fa45dacc167b15c93dd07ee5c40db906de34f26e11e7a24f539e30", - "miniblockType": "TxBlock", - "miniblockHash": "b7b8fc9f3b81d7daae1113cbf73457e16ee31f3a864ef3729a1a21f3a929e112", - "hyperblockNonce": 8403647, - "hyperblockHash": "f8b83b6d38fa45dacc167b15c93dd07ee5c40db906de34f26e11e7a24f539e30", - "timestamp": 1646652762, - "smartContractResults": [ - { - "hash": "9aecf3bd5dd5c706a28d1cc7059ac20db74340f136816f667dbefcc58daa3aba", - "nonce": 0, - "value": 50000000000000000, - "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "sender": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "data": "issueSemiFungible@446f706554657374@444f504554455354@63616e467265657a65@74727565@63616e57697065@74727565@63616e5061757365@74727565@63616e4368616e67654f776e6572@74727565@63616e55706772616465@74727565@63616e4164645370656369616c526f6c6573@74727565@5ca148", - "prevTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", - "originalTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", - "gasLimit": 75958360, - "gasPrice": 1000000000, - "callType": 1, - "originalSender": "erd1x3g000ew7zzv6kyqhj9jl2wy5g6cc72qahvvxz29zv76jwq6ssvqt0d998", - "operation": "transfer", - "function": "issueSemiFungible" - }, - { - "hash": "aacfe9088bb9d2d5b3fbe9cab2b2f1c6a7e9cbab2f1a41020e2c819fc9b43570", - "nonce": 66, - "value": 0, - "receiver": "erd1x3g000ew7zzv6kyqhj9jl2wy5g6cc72qahvvxz29zv76jwq6ssvqt0d998", - "sender": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "data": "@6f6b", - "prevTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", - "originalTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "operation": "transfer" - }, - { - "hash": "3f6f0f3de9e942884e7e1592823a7db7ce935a3f9d3359d8c1ee98a5645332d8", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "@00@444f5045544553542d373732303063", - "prevTxHash": "9aecf3bd5dd5c706a28d1cc7059ac20db74340f136816f667dbefcc58daa3aba", - "originalTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", - "gasLimit": 25958360, - "gasPrice": 1000000000, - "callType": 2, - "originalSender": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "logs": { - "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "identifier": "completedTxEvent", - "topics": [ - "muzzvV3VxwaijRzHBZrCDbdDQPE2gW9mfb78xY2qOro=" - ], - "data": null - } - ] - }, - "operation": "transfer" - }, - { - "hash": "c6e4f7c5da455009fb4f6967ce8a273a97b826aa617fa798ffd0cf17bde6b97a", - "nonce": 1, - "value": 225516180000000, - "receiver": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "sender": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "data": "@6f6b", - "prevTxHash": "3f6f0f3de9e942884e7e1592823a7db7ce935a3f9d3359d8c1ee98a5645332d8", - "originalTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "operation": "transfer", - "isRefund": true - } - ], - "logs": { - "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "identifier": "transferValueOnly", - "topics": [ - "AAAAAAAAAAAFAH6d74PDz8xLqvowrlOA5lVDBMUghBg=", - "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=", - "saK8LsUAAA==" - ], - "data": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", - "identifier": "writeLog", - "topics": [ - "NFD3vy7whM1YgLyLL6nEojWMeUDt2MMJRRM9qTgahBg=" - ], - "data": "QDZmNmI=" - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "issueToken", - "initiallyPaidFee": "914840000000000", - "fee": "914840000000000", - "chainID": "1", - "version": 1, - "options": 0 - } - }, - "error": "", - "code": "successful" -} - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Option = Some("DOPETEST-77200c".to_string()); - - assert_eq!(tx_response.new_issued_token_identifier, expected) - } - - #[test] - fn test_process_issued_token_identifier_non_fungible() { - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", - "nonce": 16, - "round": 820170, - "epoch": 341, - "value": "50000000000000000", - "receiver": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "sender": "erd162knt53z7m0f9jjms9wxphr3q9d7zu4ky85xs2cc0ekrqz7k4fdq85lkuc", - "gasPrice": 1000000000, - "gasLimit": 200000000, - "gasUsed": 200000000, - "data": "aXNzdWVUb2tlbkA2NzY1NmU2NTdhNzk3M0A0NzQ1NGU=", - "signature": "e80d45f4de419799a2bbff1cae1235521c8eef1853ee45b02f95c2da74ce50d241bf75b6ab0c650245562700862ea9759caad40f3e381ac0c4d82cfe56e67c09", - "sourceShard": 2, - "destinationShard": 2, - "blockNonce": 819313, - "blockHash": "a1db4ef13f07b86678000df9cc78f244d83dcc35ae51de545f333bf616930d39", - "notarizedAtSourceInMetaNonce": 819396, - "NotarizedAtSourceInMetaHash": "6d9e511e46d318aa5b77cbfdfde14d2ce8515ce4e954b286f130a6b518ddf26a", - "notarizedAtDestinationInMetaNonce": 819396, - "notarizedAtDestinationInMetaHash": "6d9e511e46d318aa5b77cbfdfde14d2ce8515ce4e954b286f130a6b518ddf26a", - "miniblockType": "TxBlock", - "miniblockHash": "afdb278522181aeb9b12f08840e6c534e398e6af9c7f757548308e300e7ec4e9", - "hyperblockNonce": 819396, - "hyperblockHash": "6d9e511e46d318aa5b77cbfdfde14d2ce8515ce4e954b286f130a6b518ddf26a", - "timestamp": 1698921020, - "smartContractResults": [ - { - "hash": "6fe0cc002802af1744f394eee4a69224b5e775961d8386e04e7a5b9242f7ff65", - "nonce": 0, - "value": 50000000000000000, - "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "sender": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "data": "issueNonFungible@67656e657a7973@47454e@63616e467265657a65@74727565@63616e57697065@74727565@63616e5061757365@74727565@63616e5472616e736665724e4654437265617465526f6c65@74727565@63616e4368616e67654f776e6572@66616c7365@63616e55706772616465@66616c7365@63616e4164645370656369616c526f6c6573@74727565@5e30e4", - "prevTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", - "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", - "gasLimit": 196098365, - "gasPrice": 1000000000, - "callType": 1, - "originalSender": "erd162knt53z7m0f9jjms9wxphr3q9d7zu4ky85xs2cc0ekrqz7k4fdq85lkuc", - "operation": "transfer", - "function": "issueNonFungible" - }, - { - "hash": "98afe82512c79f1caaf171bd5919ee469d11ba0c4f725aefcab834278c0f1e58", - "nonce": 0, - "value": 0, - "receiver": "erd1lllllllllllllllllllllllllllllllllllllllllllllllllupq9x7ny0", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "ESDTSetBurnRoleForAll@47454e2d383638353933", - "prevTxHash": "6fe0cc002802af1744f394eee4a69224b5e775961d8386e04e7a5b9242f7ff65", - "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "logs": { - "address": "erd1lllllllllllllllllllllllllllllllllllllllllllllllllupq9x7ny0", - "events": [ - { - "address": "erd1lllllllllllllllllllllllllllllllllllllllllllllllllupq9x7ny0", - "identifier": "completedTxEvent", - "topics": [ - "b+DMACgCrxdE85Tu5KaSJLXndZYdg4bgTnpbkkL3/2U=" - ], - "data": null, - "additionalData": null - } - ] - }, - "operation": "transfer" - }, - { - "hash": "83494ad9369738b574a7266cbfb12ce63ccf634950cd6b0ec16107b8fb42f8f6", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "sender": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "data": "setSpecialRole@47454e2d383638353933@00000000000000000500de51fa8943c26e6933419f9bb7ceb79b7ff4f7bbaa5a@45534454526f6c654e4654437265617465@5e30e4", - "prevTxHash": "112d18ec0364b4700b1bfb3df517c80dba547a53373ece2a9e71acd5266e7b64", - "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", - "gasLimit": 142399698, - "gasPrice": 1000000000, - "callType": 1, - "operation": "transfer", - "function": "setSpecialRole" - }, - { - "hash": "112d18ec0364b4700b1bfb3df517c80dba547a53373ece2a9e71acd5266e7b64", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "@00@47454e2d383638353933", - "prevTxHash": "6fe0cc002802af1744f394eee4a69224b5e775961d8386e04e7a5b9242f7ff65", - "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", - "gasLimit": 146098365, - "gasPrice": 1000000000, - "callType": 2, - "originalSender": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "identifier": "writeLog", - "topics": [ - "AAAAAAAAAAAFAN5R+olDwm5pM0Gfm7fOt5t/9Pe7qlo=" - ], - "data": "QDZmNmI=", - "additionalData": null - } - ] - }, - "operation": "transfer" - }, - { - "hash": "db5d74970374337956fa61fb4fd90057b3f6a82ea3e259b389934b71a1652e5f", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "ESDTSetRole@47454e2d383638353933@45534454526f6c654e4654437265617465", - "prevTxHash": "83494ad9369738b574a7266cbfb12ce63ccf634950cd6b0ec16107b8fb42f8f6", - "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "identifier": "ESDTSetRole", - "topics": [ - "R0VOLTg2ODU5Mw==", - "", - "", - "RVNEVFJvbGVORlRDcmVhdGU=" - ], - "data": null, - "additionalData": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "identifier": "completedTxEvent", - "topics": [ - "g0lK2TaXOLV0pyZsv7Es5jzPY0lQzWsOwWEHuPtC+PY=" - ], - "data": null, - "additionalData": null - } - ] - }, - "operation": "ESDTSetRole", - "function": "ESDTSetRole" - }, - { - "hash": "a6a665f47977a59c4c2baf460281fc938e04ae0f87ac2e78040a14ae27822701", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "@00", - "prevTxHash": "83494ad9369738b574a7266cbfb12ce63ccf634950cd6b0ec16107b8fb42f8f6", - "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", - "gasLimit": 92399698, - "gasPrice": 1000000000, - "callType": 2, - "originalSender": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "identifier": "writeLog", - "topics": [ - "AAAAAAAAAAAFAN5R+olDwm5pM0Gfm7fOt5t/9Pe7qlo=", - "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gOTIzOTk2OTgsIGdhcyB1c2VkID0gMzE0MTg4MA==" - ], - "data": "QDZmNmI=", - "additionalData": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "identifier": "completedTxEvent", - "topics": [ - "g0lK2TaXOLV0pyZsv7Es5jzPY0lQzWsOwWEHuPtC+PY=" - ], - "data": null, - "additionalData": null - } - ] - }, - "operation": "transfer" - } - ], - "logs": { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "identifier": "transferValueOnly", - "topics": [ - "AAAAAAAAAAAFAN5R+olDwm5pM0Gfm7fOt5t/9Pe7qlo=", - "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=", - "saK8LsUAAA==" - ], - "data": null, - "additionalData": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", - "identifier": "writeLog", - "topics": [ - "0q010iL23pLKW4FcYNxxAVvhcrYh6GgrGH5sMAvWqlo=" - ], - "data": "QDZmNmI=", - "additionalData": null - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "issueToken", - "initiallyPaidFee": "2097020000000000", - "fee": "2097020000000000", - "chainID": "D", - "version": 1, - "options": 0 - } - }, - "error": "", - "code": "successful" -} - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Option = Some("GEN-868593".to_string()); - - assert_eq!(tx_response.new_issued_token_identifier, expected) - } - - #[test] - fn test_process_issued_token_identifier_meta_esdt() { - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", - "nonce": 419, - "round": 1787093, - "epoch": 744, - "value": "50000000000000000", - "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "sender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "gasPrice": 1000000000, - "gasLimit": 600000000, - "gasUsed": 157220928, - "data": "ZGVwbG95QXNoc3dhcExQQUNTdHJhdGVneUA0MTRjNTAyZDYzNjE2NTYxNjMzNUA0MTU0NTMyZDM0NjMzMDM5MzIzMEAwM2U4QDAzZThAQDNiOWFjYTAwQDAwMDAwMDAwMDAwMDAwMDAwNTAwOTU3MzkwYWVkYTQzMmY1MmE0MTFkNTE5NzRmZTkzZDQwZDI3NzMzZTA0NjNAMDAwMDAwMDAwMDAwMDAwMDA1MDBkMTJjYzczY2JkYTZmMjY1OWM5NTllNWQ1NzU4YWY5MmNhMTM4NDg2NTIzM0AwMDAwMDAwMDAwMDAwMDAwMDUwMDUxZGY3MTc1OGNmMmFjYTViNDZkZWQ4MTU1OGI1NTE1ZGMyOWYzZjM1MjMzQEAwMDAwMDAwMDAwMDAwMDAwMDUwMDdlNGExZGZjNDM3Y2VkNDlkYjlmMTYzNzk4NDE2Yjg0YWMyMWQ0Yzk3Y2ViMDAwMDAwMGM1NzQ1NDc0YzQ0MmQ2MTMyMzg2MzM1MzkwMDAwMDAwMDAwMDAwMDAwMDUwMGE4YmE5ZTY4NjI2YmJjOTkzZmQ3OTVlOGJiNmY0Nzk0M2IyZjVmZmE3Y2ViMDAwMDAwMGE1NTU0NGIyZDMxMzQ2NDM1Mzc2NEAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwNTAwNTFkZjcxNzU4Y2YyYWNhNWI0NmRlZDgxNTU4YjU1MTVkYzI5ZjNmMzUyMzMwMDAwMDAwYjQyNTU1MzQ0MmQ2NDM0NjMzMDMxMzQwMDAwMDAwMDAwQDAxODZhMEAyNzEw", - "signature": "4648af0b96eb430e4986b9fb760549742de09c809b46b984e5d995c898d80c25bfc0717c30da34bd89cd3005d98ee895afa39ee588b7b74b4807c63cbeade807", - "sourceShard": 1, - "destinationShard": 1, - "blockNonce": 1785520, - "blockHash": "8f926a5d79fa84bc69949a21bfbba17447091a8a074ac172fa0b88e4475a1214", - "notarizedAtSourceInMetaNonce": 1785568, - "NotarizedAtSourceInMetaHash": "eebd1aa5c3dde083f9c367242c054affedd36bfc95f7bcc1d4e2d90beb5754e9", - "notarizedAtDestinationInMetaNonce": 1785568, - "notarizedAtDestinationInMetaHash": "eebd1aa5c3dde083f9c367242c054affedd36bfc95f7bcc1d4e2d90beb5754e9", - "miniblockType": "TxBlock", - "miniblockHash": "b85d82db6d69cbc1911b3455d2837eeb3170b391926efa2eacb4d9c8e3c96ee4", - "hyperblockNonce": 1785568, - "hyperblockHash": "eebd1aa5c3dde083f9c367242c054affedd36bfc95f7bcc1d4e2d90beb5754e9", - "timestamp": 1704722558, - "smartContractResults": [ - { - "hash": "ea9a96c079e66249e6b73c0341991dad96ca81f855f2fc4abe0d432be117a882", - "nonce": 420, - "value": 4427790720000000, - "receiver": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "data": "@6f6b", - "prevTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", - "originalTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "operation": "transfer", - "isRefund": true - }, - { - "hash": "6082975132a2c9d8197dfd0f9852b454ad344740eebdbdf93f620b2796ab723b", - "nonce": 0, - "value": 50000000000000000, - "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "data": "registerMetaESDT@415453417368537761704c5041435661756c74@4156415348@12@63616e467265657a65@66616c7365@63616e57697065@66616c7365@63616e5061757365@66616c7365@63616e5472616e736665724e4654437265617465526f6c65@66616c7365@63616e4368616e67654f776e6572@66616c7365@63616e55706772616465@66616c7365@63616e4164645370656369616c526f6c6573@74727565@9eb30a87c92674ab1469700c0b385b3850e86de80f87dec6cf3213c7e379a646@408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43@03eb4a30", - "prevTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", - "originalTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", - "gasLimit": 125751600, - "gasPrice": 1000000000, - "callType": 1, - "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "operation": "transfer", - "function": "registerMetaESDT" - }, - { - "hash": "290f85d7ec2f7d5797510290358e9e0f76bb880451efaacb0d69280b8d94c67a", - "nonce": 0, - "value": 0, - "receiver": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "ESDTSetBurnRoleForAll@41564153482d376438623564", - "prevTxHash": "6082975132a2c9d8197dfd0f9852b454ad344740eebdbdf93f620b2796ab723b", - "originalTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "logs": { - "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", - "events": [ - { - "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", - "identifier": "completedTxEvent", - "topics": [ - "YIKXUTKiydgZff0PmFK0VK00R0Duvb35P2ILJ5arcjs=" - ], - "data": null, - "additionalData": null - } - ] - }, - "operation": "transfer" - }, - { - "hash": "1aa62a6251edd216bd4e5ae59f7e676d5d2f88597685e0ec0e25ac4434bfccdb", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "@00@41564153482d376438623564@d0644194444642fd16ee156307f6fda0e8f8baf4c496e1a1dc85e027ecc08a4a@9eb30a87c92674ab1469700c0b385b3850e86de80f87dec6cf3213c7e379a646@408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43@00", - "prevTxHash": "6082975132a2c9d8197dfd0f9852b454ad344740eebdbdf93f620b2796ab723b", - "originalTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", - "gasLimit": 75751600, - "gasPrice": 1000000000, - "callType": 2, - "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "logs": { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "identifier": "writeLog", - "topics": [ - "AAAAAAAAAAAFAH6UefeHERqHcLpMz2gC3xXGhFsJBGM=", - "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNzU3NTE2MDAsIGdhcyB1c2VkID0gNDE3NjA1OQ==" - ], - "data": "QDZmNmI=", - "additionalData": [ - "QDZmNmI=" - ] - }, - { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "identifier": "completedTxEvent", - "topics": [ - "YIKXUTKiydgZff0PmFK0VK00R0Duvb35P2ILJ5arcjs=" - ], - "data": null, - "additionalData": null - } - ] - }, - "operation": "transfer" - } - ], - "logs": { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "identifier": "transferValueOnly", - "topics": [ - "", - "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=" - ], - "data": "RGVwbG95RnJvbVNvdXJjZQ==", - "additionalData": [ - "RGVwbG95RnJvbVNvdXJjZQ==", - "aW5pdA==", - "QUxQLWNhZWFjNQ==", - "QVRTLTRjMDkyMA==", - "A+g=", - "A+g=", - "", - "O5rKAA==" - ] - }, - { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "identifier": "transferValueOnly", - "topics": [ - "", - "AAAAAAAAAAAFADJ0SE0vUW6bO5SurLeFIMfK/HtBBGM=" - ], - "data": "RGVwbG95RnJvbVNvdXJjZQ==", - "additionalData": [ - "RGVwbG95RnJvbVNvdXJjZQ==", - "aW5pdA==", - "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=", - "AAAAAAAAAAAFAJVzkK7aQy9SpBHVGXT+k9QNJ3M+BGM=", - "AAAAAAAAAAAFANEsxzy9pvJlnJWeXVdYr5LKE4SGUjM=", - "AAAAAAAAAAAFAFHfcXWM8qyltG3tgVWLVRXcKfPzUjM=", - "", - "AAAAAAAAAAAFAH5KHfxDfO1J258WN5hBa4SsIdTJfOsAAAAMV0VHTEQtYTI4YzU5AAAAAAAAAAAFAKi6nmhia7yZP9eV6LtvR5Q7L1/6fOsAAAAKVVRLLTE0ZDU3ZA==", - "AAAAAQAAAAAAAAAABQBR33F1jPKspbRt7YFVi1UV3Cnz81IzAAAAC0JVU0QtZDRjMDE0AAAAAAA=", - "AYag", - "JxA=" - ] - }, - { - "address": "erd1qqqqqqqqqqqqqpgqxf6ysnf029hfkwu546kt0pfqcl90c76pq33s0a320f", - "identifier": "transferValueOnly", - "topics": [ - "", - "AAAAAAAAAAAFANEsxzy9pvJlnJWeXVdYr5LKE4SGUjM=" - ], - "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "additionalData": [ - "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "Z2V0RmFybWluZ1Rva2VuSWQ=" - ] - }, - { - "address": "erd1qqqqqqqqqqqqqpgqxf6ysnf029hfkwu546kt0pfqcl90c76pq33s0a320f", - "identifier": "transferValueOnly", - "topics": [ - "", - "AAAAAAAAAAAFANEsxzy9pvJlnJWeXVdYr5LKE4SGUjM=" - ], - "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "additionalData": [ - "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "Z2V0RmFybVRva2VuSWQ=" - ] - }, - { - "address": "erd1qqqqqqqqqqqqqpgqxf6ysnf029hfkwu546kt0pfqcl90c76pq33s0a320f", - "identifier": "transferValueOnly", - "topics": [ - "", - "AAAAAAAAAAAFANEsxzy9pvJlnJWeXVdYr5LKE4SGUjM=" - ], - "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "additionalData": [ - "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "Z2V0UmV3YXJkVG9rZW5JZA==" - ] - }, - { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "identifier": "transferValueOnly", - "topics": [ - "saK8LsUAAA==", - "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=" - ], - "data": "QXN5bmNDYWxs", - "additionalData": [ - "QXN5bmNDYWxs", - "cmVnaXN0ZXJNZXRhRVNEVA==", - "QVRTQXNoU3dhcExQQUNWYXVsdA==", - "QVZBU0g=", - "Eg==", - "Y2FuRnJlZXpl", - "ZmFsc2U=", - "Y2FuV2lwZQ==", - "ZmFsc2U=", - "Y2FuUGF1c2U=", - "ZmFsc2U=", - "Y2FuVHJhbnNmZXJORlRDcmVhdGVSb2xl", - "ZmFsc2U=", - "Y2FuQ2hhbmdlT3duZXI=", - "ZmFsc2U=", - "Y2FuVXBncmFkZQ==", - "ZmFsc2U=", - "Y2FuQWRkU3BlY2lhbFJvbGVz", - "dHJ1ZQ==" - ] - }, - { - "address": "erd1qqqqqqqqqqqqqpgqxf6ysnf029hfkwu546kt0pfqcl90c76pq33s0a320f", - "identifier": "SCDeploy", - "topics": [ - "AAAAAAAAAAAFADJ0SE0vUW6bO5SurLeFIMfK/HtBBGM=", - "AAAAAAAAAAAFAH6UefeHERqHcLpMz2gC3xXGhFsJBGM=", - "fvRqbue54Womde/CN2IkRGkrx8tsU+xkLvi3+uwMkhY=" - ], - "data": null, - "additionalData": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", - "identifier": "SCDeploy", - "topics": [ - "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=", - "AAAAAAAAAAAFAH6UefeHERqHcLpMz2gC3xXGhFsJBGM=", - "E3blQfRJfCKLWDr06Od703DSZenIzq8KND+xUjmGY/M=" - ], - "data": null, - "additionalData": null - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "deployAshswapLPACStrategy", - "initiallyPaidFee": "6936045000000000", - "fee": "2508254280000000", - "chainID": "D", - "version": 1, - "options": 0 - } - }, - "error": "", - "code": "successful" -} - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Option = Some("AVASH-7d8b5d".to_string()); - - assert_eq!(tx_response.new_issued_token_identifier, expected) - } - - #[test] - fn test_set_special_roles_should_not_process_issued_token_identifier() { - let data = r#" - { - "data": { - "transaction": { - "type": "normal", - "processingTypeOnSource": "SCInvoking", - "processingTypeOnDestination": "SCInvoking", - "hash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", - "nonce": 420, - "round": 1787109, - "epoch": 744, - "value": "0", - "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "sender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "gasPrice": 1000000000, - "gasLimit": 600000000, - "gasUsed": 129636807, - "data": "ZmluaXNoVmF1bHREZXBsb3ltZW50cw==", - "signature": "dca943ef1a788bfa6cb0e9aa3900b8340e4908075cbfefaa2a66688f6f0c0fed349edb2eb48eec427cd9098822fba875e4d66072fbdb44cb7f4c1a416736e20c", - "sourceShard": 1, - "destinationShard": 1, - "blockNonce": 1785536, - "blockHash": "93ca539e81612768b67a85b7135f7c104e76bec031a758a6b1782910ae49dd8f", - "notarizedAtSourceInMetaNonce": 1785584, - "NotarizedAtSourceInMetaHash": "71d17afe660282bb42de1ea3eec3e3534a179bd32aa1471c2861ce411bf30552", - "notarizedAtDestinationInMetaNonce": 1785584, - "notarizedAtDestinationInMetaHash": "71d17afe660282bb42de1ea3eec3e3534a179bd32aa1471c2861ce411bf30552", - "miniblockType": "TxBlock", - "miniblockHash": "f8c60565af746e92d2c9c09a92734e5eb8da7e42c67a86854c93b349bfe287eb", - "hyperblockNonce": 1785584, - "hyperblockHash": "71d17afe660282bb42de1ea3eec3e3534a179bd32aa1471c2861ce411bf30552", - "timestamp": 1704722654, - "smartContractResults": [ - { - "hash": "c3ce9c364de3823ffae250c2bfb40aaf2b18f771ed4bd37bf788ad83a2c651f3", - "nonce": 421, - "value": 4703631930000000, - "receiver": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "data": "@6f6b", - "prevTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", - "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "operation": "transfer", - "isRefund": true - }, - { - "hash": "50f9c25a1402ce6d87ae9f890659c8a67462292e471e02c74d64ff7ba1995e60", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "data": "setSpecialRole@41564153482d376438623564@00000000000000000500d00cc0e63887ff6b792d34234a44e7ac6b575d4b0463@45534454526f6c654e4654437265617465@45534454526f6c654e46544164645175616e74697479@45534454526f6c654e46544275726e@0192c6db2c69f50b6968fb22ac558337a851719519cfd1e6bbf79a07bbcf18bc@cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0@03eb4a30", - "prevTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", - "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", - "gasLimit": 125751600, - "gasPrice": 1000000000, - "callType": 1, - "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "operation": "transfer", - "function": "setSpecialRole" - }, - { - "hash": "d6a5824a60b6c9050462c3f5a02ace00c36e8b4ba1958d132bd394e2ed1e7226", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "ESDTSetRole@41564153482d376438623564@45534454526f6c654e4654437265617465@45534454526f6c654e46544164645175616e74697479@45534454526f6c654e46544275726e", - "prevTxHash": "50f9c25a1402ce6d87ae9f890659c8a67462292e471e02c74d64ff7ba1995e60", - "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "logs": { - "address": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", - "identifier": "ESDTSetRole", - "topics": [ - "QVZBU0gtN2Q4YjVk", - "", - "", - "RVNEVFJvbGVORlRDcmVhdGU=", - "RVNEVFJvbGVORlRBZGRRdWFudGl0eQ==", - "RVNEVFJvbGVORlRCdXJu" - ], - "data": null, - "additionalData": null - }, - { - "address": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", - "identifier": "completedTxEvent", - "topics": [ - "UPnCWhQCzm2Hrp+JBlnIpnRiKS5HHgLHTWT/e6GZXmA=" - ], - "data": null, - "additionalData": null - } - ] - }, - "operation": "ESDTSetRole", - "function": "ESDTSetRole" - }, - { - "hash": "bf1b8b4b301ff548368dfd972896489d5e2a088d5cbdfa1bfe2421cc7f641f7a", - "nonce": 0, - "value": 0, - "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", - "data": "@00@a68d44c751eba85db0713db8dc9c10c78749189ec0d6f1af5fc67bb656c1254b@0192c6db2c69f50b6968fb22ac558337a851719519cfd1e6bbf79a07bbcf18bc@cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0@00", - "prevTxHash": "50f9c25a1402ce6d87ae9f890659c8a67462292e471e02c74d64ff7ba1995e60", - "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", - "gasLimit": 75751600, - "gasPrice": 1000000000, - "callType": 2, - "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", - "logs": { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "identifier": "transferValueOnly", - "topics": [ - "", - "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=" - ], - "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "additionalData": [ - "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "c2V0U2hhcmVUb2tlbklkZW50aWZpZXI=", - "QVZBU0gtN2Q4YjVk" - ] - }, - { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "identifier": "transferValueOnly", - "topics": [ - "", - "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=" - ], - "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "additionalData": [ - "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", - "c2V0U3RyYXRlZ3lBZGRyZXNz", - "AAAAAAAAAAAFADJ0SE0vUW6bO5SurLeFIMfK/HtBBGM=" - ] - }, - { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "identifier": "completedTxEvent", - "topics": [ - "UPnCWhQCzm2Hrp+JBlnIpnRiKS5HHgLHTWT/e6GZXmA=" - ], - "data": null, - "additionalData": null - } - ] - }, - "operation": "transfer" - }, - { - "hash": "9d75a398545f488d4764149245e6ec3101debfce99477c353ac11c3239acd897", - "nonce": 1, - "value": 648519550000000, - "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "data": "@6f6b", - "prevTxHash": "bf1b8b4b301ff548368dfd972896489d5e2a088d5cbdfa1bfe2421cc7f641f7a", - "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", - "gasLimit": 0, - "gasPrice": 1000000000, - "callType": 0, - "operation": "transfer", - "isRefund": true - } - ], - "logs": { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "events": [ - { - "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", - "identifier": "transferValueOnly", - "topics": [ - "", - "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=" - ], - "data": "QXN5bmNDYWxs", - "additionalData": [ - "QXN5bmNDYWxs", - "c2V0U3BlY2lhbFJvbGU=", - "QVZBU0gtN2Q4YjVk", - "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=", - "RVNEVFJvbGVORlRDcmVhdGU=", - "RVNEVFJvbGVORlRBZGRRdWFudGl0eQ==", - "RVNEVFJvbGVORlRCdXJu" - ] - } - ] - }, - "status": "success", - "operation": "transfer", - "function": "finishVaultDeployments", - "initiallyPaidFee": "6082170000000000", - "fee": "1378538070000000", - "chainID": "D", - "version": 1, - "options": 0 - } - }, - "error": "", - "code": "successful" -} - "#; - - let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) - .unwrap() - .data - .unwrap() - .transaction; - let tx_response = TxResponse::from_network_tx(tx_on_network); - - let expected: Option = None; - - assert_eq!(tx_response.new_issued_token_identifier, expected) - } } diff --git a/framework/scenario/src/scenario/model/transaction/tx_response_status.rs b/framework/scenario/src/scenario/model/transaction/tx_response_status.rs index 5c9d057615..e7902047c6 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_response_status.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_response_status.rs @@ -9,7 +9,7 @@ pub struct TxResponseStatus { impl TxResponseStatus { /// Creates a [`TxResponseStatus`] - pub(crate) fn new(status: u64, message: &str) -> Self { + pub fn new(status: u64, message: &str) -> Self { Self { status, message: message.to_string(), @@ -17,7 +17,7 @@ impl TxResponseStatus { } /// Creates a [`TxResponseStatus`] that signals an error. - pub(crate) fn signal_error(message: &str) -> Self { + pub fn signal_error(message: &str) -> Self { Self::new(4, message) } diff --git a/framework/scenario/src/scenario/model/transaction/tx_response_utils.rs b/framework/scenario/src/scenario/model/transaction/tx_response_utils.rs deleted file mode 100644 index 36c86e920a..0000000000 --- a/framework/scenario/src/scenario/model/transaction/tx_response_utils.rs +++ /dev/null @@ -1,35 +0,0 @@ -use multiversx_sdk::data::transaction::ApiSmartContractResult; - -/// Checks for invalid topics. -pub fn process_topics_error(topics: Option<&Vec>) -> Option { - if topics.is_none() { - return Some("missing topics".to_string()); - } - - let topics = topics.unwrap(); - if topics.len() != 2 { - Some(format!( - "expected to have 2 topics, found {} instead", - topics.len() - )) - } else { - None - } -} - -/// Decodes the data of a smart contract result. -pub fn decode_scr_data_or_panic(data: &str) -> Vec> { - let mut split = data.split('@'); - let _ = split.next().expect("SCR data should start with '@'"); - let result_code = split.next().expect("missing result code"); - assert_eq!(result_code, "6f6b", "result code is not 'ok'"); - - split - .map(|encoded_arg| hex::decode(encoded_arg).expect("error hex-decoding result")) - .collect() -} - -/// Checks if the given smart contract result is an out smart contract result. -pub fn is_out_scr(scr: &&ApiSmartContractResult) -> bool { - scr.nonce != 0 && scr.data.starts_with('@') -} diff --git a/framework/scenario/src/scenario/model/transaction/typed_response.rs b/framework/scenario/src/scenario/model/transaction/typed_response.rs index 90bb2e245a..a25974a1b8 100644 --- a/framework/scenario/src/scenario/model/transaction/typed_response.rs +++ b/framework/scenario/src/scenario/model/transaction/typed_response.rs @@ -1,5 +1,6 @@ use super::{Log, TxResponse, TxResponseStatus}; use multiversx_sc::codec::{PanicErrorHandler, TopDecodeMulti}; +use unwrap_infallible::UnwrapInfallible; pub struct TypedResponse where @@ -19,7 +20,8 @@ where pub fn from_raw(raw_response: &TxResponse) -> Self { let result: Result = if raw_response.tx_error.is_success() { let mut result_raw = raw_response.out.clone(); - let Ok(decoded) = T::multi_decode_or_handle_err(&mut result_raw, PanicErrorHandler); + let decoded = T::multi_decode_or_handle_err(&mut result_raw, PanicErrorHandler) + .unwrap_infallible(); Ok(decoded) } else { Err(raw_response.tx_error.clone()) diff --git a/framework/scenario/src/scenario/model/value/address_key.rs b/framework/scenario/src/scenario/model/value/address_key.rs index 5bbc1d79ae..f54e05b2f3 100644 --- a/framework/scenario/src/scenario/model/value/address_key.rs +++ b/framework/scenario/src/scenario/model/value/address_key.rs @@ -1,6 +1,8 @@ +use multiversx_sc::types::{Address, TestAddress, TestSCAddress}; + use super::{value_from_slice, AddressValue}; use crate::{ - multiversx_sc::types::Address, + facade::expr::Bech32Address, scenario_format::{ interpret_trait::{InterpretableFrom, InterpreterContext, IntoRaw}, value_interpreter::interpret_string, @@ -114,3 +116,39 @@ impl From<&Address> for AddressKey { } } } + +impl From<&Bech32Address> for AddressKey { + fn from(from: &Bech32Address) -> Self { + AddressKey { + value: from.to_address().clone(), + original: from.to_bech32_expr(), + } + } +} + +impl From for AddressKey { + fn from(from: Bech32Address) -> Self { + AddressKey { + original: from.to_bech32_expr(), + value: from.into_address(), + } + } +} + +impl From> for AddressKey { + fn from(from: TestAddress) -> Self { + AddressKey { + value: from.eval_to_array().into(), + original: from.eval_to_expr(), + } + } +} + +impl From> for AddressKey { + fn from(from: TestSCAddress) -> Self { + AddressKey { + value: from.eval_to_array().into(), + original: from.eval_to_expr(), + } + } +} diff --git a/framework/scenario/src/scenario/model/value/address_value.rs b/framework/scenario/src/scenario/model/value/address_value.rs index 85886e4cf8..fdde631ede 100644 --- a/framework/scenario/src/scenario/model/value/address_value.rs +++ b/framework/scenario/src/scenario/model/value/address_value.rs @@ -1,11 +1,18 @@ +use multiversx_sc::{ + api::ManagedTypeApi, + types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom, TxFromSpecified}, +}; use std::fmt; -use crate::multiversx_sc::types::Address; +use crate::multiversx_sc::types::{Address, TestAddress, TestSCAddress}; -use crate::scenario_format::{ - interpret_trait::{InterpretableFrom, InterpreterContext, IntoRaw}, - serde_raw::ValueSubTree, - value_interpreter::{interpret_string, interpret_subtree}, +use crate::{ + facade::expr::Bech32Address, + scenario_format::{ + interpret_trait::{InterpretableFrom, InterpreterContext, IntoRaw}, + serde_raw::ValueSubTree, + value_interpreter::{interpret_string, interpret_subtree}, + }, }; use super::AddressKey; @@ -107,8 +114,124 @@ impl From<&Address> for AddressValue { } } +impl From<&Bech32Address> for AddressValue { + fn from(from: &Bech32Address) -> Self { + AddressValue { + value: from.to_address().clone(), + original: ValueSubTree::Str(from.to_bech32_expr()), + } + } +} + +impl From for AddressValue { + fn from(from: Bech32Address) -> Self { + AddressValue { + original: ValueSubTree::Str(from.to_bech32_expr()), + value: from.into_address(), + } + } +} + impl From<&str> for AddressValue { fn from(from: &str) -> Self { AddressValue::interpret_from(from, &InterpreterContext::default()) } } + +impl From> for AddressValue { + fn from(from: TestAddress) -> Self { + AddressValue { + value: from.eval_to_array().into(), + original: ValueSubTree::Str(from.eval_to_expr()), + } + } +} + +impl From> for AddressValue { + fn from(from: TestSCAddress) -> Self { + AddressValue { + value: from.eval_to_array().into(), + original: ValueSubTree::Str(from.eval_to_expr()), + } + } +} + +impl From<&AddressValue> for ManagedAddress +where + M: ManagedTypeApi, +{ + #[inline] + fn from(address_value: &AddressValue) -> Self { + ManagedAddress::from_address(&address_value.value) + } +} + +impl TxFrom for AddressValue +where + Env: TxEnv, +{ + fn resolve_address(&self, _env: &Env) -> ManagedAddress { + self.into() + } +} + +impl AnnotatedValue> for AddressValue +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> multiversx_sc::types::ManagedBuffer { + ManagedBuffer::from(self.original.to_string()) + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + ManagedAddress::from_address(&self.value) + } + + fn into_value(self, _env: &Env) -> ManagedAddress { + ManagedAddress::from_address(&self.value) + } + + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&ManagedAddress) -> R, + { + f(&ManagedAddress::from_address(&self.value)) + } +} + +impl AnnotatedValue> for &AddressValue +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> multiversx_sc::types::ManagedBuffer { + ManagedBuffer::from(self.original.to_string()) + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + ManagedAddress::from_address(&self.value) + } + + fn into_value(self, _env: &Env) -> ManagedAddress { + ManagedAddress::from_address(&self.value) + } + + fn with_value_ref(&self, _env: &Env, f: F) -> R + where + F: FnOnce(&ManagedAddress) -> R, + { + f(&ManagedAddress::from_address(&self.value)) + } +} + +impl TxFromSpecified for AddressValue where Env: TxEnv {} + +impl TxFrom for &AddressValue +where + Env: TxEnv, +{ + fn resolve_address(&self, _env: &Env) -> ManagedAddress { + ManagedAddress::from_address(&self.value) + } +} + +impl TxFromSpecified for &AddressValue where Env: TxEnv {} diff --git a/framework/scenario/src/scenario/model/value/value_check.rs b/framework/scenario/src/scenario/model/value/value_check.rs index 5299aa9e1b..9091f73594 100644 --- a/framework/scenario/src/scenario/model/value/value_check.rs +++ b/framework/scenario/src/scenario/model/value/value_check.rs @@ -21,6 +21,10 @@ where pub fn is_star(&self) -> bool { matches!(self, CheckValue::Star) } + + pub fn is_equal_to(&self, _value: T) -> bool { + matches!(self, CheckValue::Equal(_value)) + } } impl InterpretableFrom for CheckValue diff --git a/framework/scenario/src/scenario/model/value/value_set_big_uint.rs b/framework/scenario/src/scenario/model/value/value_set_big_uint.rs index c21c913851..003370509d 100644 --- a/framework/scenario/src/scenario/model/value/value_set_big_uint.rs +++ b/framework/scenario/src/scenario/model/value/value_set_big_uint.rs @@ -95,7 +95,7 @@ impl From<&BigUint> for BigUintValue { impl From> for BigUintValue { fn from(from: crate::multiversx_sc::types::BigUint) -> Self { - let value = BigUint::from_bytes_be(from.to_bytes_be().as_slice()); + let value = from.to_alloc(); BigUintValue { original: ValueSubTree::Str(value.to_string()), value, @@ -103,6 +103,17 @@ impl From> for BigUin } } +impl From> + for BigUintValue +{ + fn from(from: crate::multiversx_sc::types::AnnotatedEgldPayment) -> Self { + BigUintValue { + value: from.value.to_alloc(), + original: ValueSubTree::Str(from.annotation.to_string()), + } + } +} + impl From<&str> for BigUintValue { fn from(from: &str) -> Self { BigUintValue::interpret_from(from, &InterpreterContext::default()) diff --git a/framework/scenario/src/scenario/model/value/value_set_bytes.rs b/framework/scenario/src/scenario/model/value/value_set_bytes.rs index 33fb896d01..627f2ace9c 100644 --- a/framework/scenario/src/scenario/model/value/value_set_bytes.rs +++ b/framework/scenario/src/scenario/model/value/value_set_bytes.rs @@ -1,3 +1,5 @@ +use multiversx_sc::types::{AnnotatedValue, ManagedBuffer, TxCodeValue, TxEnv}; + use crate::scenario_format::{ interpret_trait::{InterpretableFrom, InterpreterContext, IntoRaw}, serde_raw::ValueSubTree, @@ -134,3 +136,33 @@ impl fmt::Display for BytesValue { self.original.fmt(f) } } + +impl AnnotatedValue> for BytesValue +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer<::Api> { + self.original.to_concatenated_string().into() + } + + fn to_value(&self, _env: &Env) -> ManagedBuffer { + self.value.clone().into() + } +} + +impl TxCodeValue for BytesValue where Env: TxEnv {} + +impl AnnotatedValue> for &BytesValue +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer<::Api> { + self.original.to_concatenated_string().into() + } + + fn to_value(&self, _env: &Env) -> ManagedBuffer { + self.value.clone().into() + } +} + +impl TxCodeValue for &BytesValue where Env: TxEnv {} diff --git a/framework/scenario/src/scenario/model/value/value_set_u64.rs b/framework/scenario/src/scenario/model/value/value_set_u64.rs index 1fdabe5cf7..b332543116 100644 --- a/framework/scenario/src/scenario/model/value/value_set_u64.rs +++ b/framework/scenario/src/scenario/model/value/value_set_u64.rs @@ -36,6 +36,15 @@ impl Default for U64Value { } } +impl InterpretableFrom for U64Value { + fn interpret_from(from: u64, _context: &InterpreterContext) -> Self { + U64Value { + value: from, + original: ValueSubTree::Str(from.to_string()), + } + } +} + impl InterpretableFrom for U64Value { fn interpret_from(from: ValueSubTree, context: &InterpreterContext) -> Self { let bytes = interpret_subtree(&from, context); diff --git a/framework/scenario/src/scenario/run_vm/sc_call.rs b/framework/scenario/src/scenario/run_vm/sc_call.rs index abbe9ee6ff..0a66578eaf 100644 --- a/framework/scenario/src/scenario/run_vm/sc_call.rs +++ b/framework/scenario/src/scenario/run_vm/sc_call.rs @@ -1,6 +1,6 @@ use crate::{ - multiversx_sc::codec::{CodecFrom, PanicErrorHandler, TopEncodeMulti}, - scenario::model::{ScCallStep, TxESDT, TypedScCall}, + multiversx_sc::codec::{PanicErrorHandler, TopEncodeMulti}, + scenario::model::{ScCallStep, TxESDT}, scenario_model::TxResponse, }; @@ -8,6 +8,7 @@ use multiversx_chain_vm::{ tx_execution::execute_current_tx_context_input, tx_mock::{TxInput, TxResult, TxTokenTransfer}, }; +use multiversx_sc::{abi::TypeAbiFrom, codec::TopDecodeMulti}; use super::{check_tx_output, tx_input_util::generate_tx_hash, ScenarioVMRunner}; @@ -28,13 +29,18 @@ impl ScenarioVMRunner { /// /// It takes the `contract_call` argument separately from the SC call step, /// so we can benefit from type inference in the result. + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] + #[allow(deprecated)] pub fn perform_sc_call_get_result( &mut self, - typed_sc_call: TypedScCall, + typed_sc_call: crate::scenario_model::TypedScCall, ) -> RequestedResult where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { let sc_call_step: ScCallStep = typed_sc_call.into(); let tx_result = diff --git a/framework/scenario/src/scenario/run_vm/set_state.rs b/framework/scenario/src/scenario/run_vm/set_state.rs index 187ba21e83..8284d42422 100644 --- a/framework/scenario/src/scenario/run_vm/set_state.rs +++ b/framework/scenario/src/scenario/run_vm/set_state.rs @@ -1,7 +1,7 @@ use crate::scenario::model::SetStateStep; use multiversx_chain_vm::{ - types::{VMAddress, VMCodeMetadata}, + types::VMCodeMetadata, world_mock::{ AccountData, AccountEsdt, BlockInfo as CrateBlockInfo, BlockchainState, EsdtData, EsdtInstance, EsdtInstanceMetadata, EsdtInstances, EsdtRoles, @@ -155,7 +155,7 @@ fn convert_scenario_esdt_instance_to_world_mock( creator: scenario_esdt .creator .as_ref() - .map(|creator| VMAddress::from_slice(creator.value.as_slice())), + .map(|creator| creator.to_vm_address()), royalties: scenario_esdt .royalties .as_ref() diff --git a/framework/scenario/src/scenario/tx_to_step.rs b/framework/scenario/src/scenario/tx_to_step.rs new file mode 100644 index 0000000000..82e236e48b --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step.rs @@ -0,0 +1,11 @@ +mod step_annotation; +mod step_wrapper; +mod tx_to_step_call; +mod tx_to_step_deploy; +mod tx_to_step_query; +mod tx_to_step_trait; +mod tx_to_step_transfer; + +pub use step_annotation::*; +pub use step_wrapper::{StepWithResponse, StepWrapper}; +pub use tx_to_step_trait::*; diff --git a/framework/scenario/src/scenario/tx_to_step/step_annotation.rs b/framework/scenario/src/scenario/tx_to_step/step_annotation.rs new file mode 100644 index 0000000000..2a5a2dac51 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/step_annotation.rs @@ -0,0 +1,87 @@ +use multiversx_chain_scenario_format::serde_raw::ValueSubTree; +use multiversx_sc::types::{ + AnnotatedValue, BigUint, Code, ManagedAddress, ManagedBuffer, TokenIdentifier, TxCodeValue, + TxEnv, TxGas, +}; + +use crate::scenario_model::{AddressValue, BigUintValue, BytesKey, BytesValue, U64Value}; + +pub fn address_annotated(env: &Env, from: &Addr) -> AddressValue +where + Env: TxEnv, + Addr: AnnotatedValue>, +{ + let annotation = from.annotation(env).to_string(); + AddressValue { + value: from.to_value(env).to_address(), + original: ValueSubTree::Str(annotation), + } +} + +pub fn u64_annotated(env: &Env, from: &T) -> U64Value +where + Env: TxEnv, + T: AnnotatedValue, +{ + let annotation = from.annotation(env).to_string(); + U64Value { + value: from.to_value(env), + original: ValueSubTree::Str(annotation), + } +} + +pub fn big_uint_annotated(env: &Env, from: &T) -> BigUintValue +where + Env: TxEnv, + T: AnnotatedValue>, +{ + let annotation = from.annotation(env).to_string(); + BigUintValue { + value: from.to_value(env).to_alloc(), + original: ValueSubTree::Str(annotation), + } +} + +pub fn bytes_annotated(env: &Env, value: T) -> BytesValue +where + Env: TxEnv, + T: AnnotatedValue>, +{ + let annotation = value.annotation(env).to_string(); + BytesValue { + value: value.into_value(env).to_vec(), + original: ValueSubTree::Str(annotation), + } +} + +pub fn token_identifier_annotated(env: &Env, value: T) -> BytesKey +where + Env: TxEnv, + T: AnnotatedValue>, +{ + let annotation = value.annotation(env).to_string(); + BytesKey { + value: value.into_value(env).into_managed_buffer().to_vec(), + original: annotation, + } +} + +pub fn code_annotated(env: &Env, code: Code) -> BytesValue +where + Env: TxEnv, + CodeValue: TxCodeValue, +{ + bytes_annotated(env, code.0) +} + +pub fn gas_annotated(env: &Env, gas: Gas) -> U64Value +where + Env: TxEnv, + Gas: TxGas, +{ + let annotation = gas.gas_annotation(env).to_string(); + U64Value { + value: gas.gas_value(env), + original: ValueSubTree::Str(annotation), + } +} diff --git a/framework/scenario/src/scenario/tx_to_step/step_wrapper.rs b/framework/scenario/src/scenario/tx_to_step/step_wrapper.rs new file mode 100644 index 0000000000..9d9a0199d5 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/step_wrapper.rs @@ -0,0 +1,48 @@ +use multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{RHListExec, TxEnv}, +}; + +use crate::scenario_model::{ScCallStep, ScDeployStep, ScQueryStep, TxResponse}; + +pub struct StepWrapper { + pub env: Env, + pub step: Step, + pub result_handler: RH, +} + +impl StepWrapper +where + Env: TxEnv, + Step: StepWithResponse, + RH: RHListExec, + RH::ListReturns: NestedTupleFlatten, +{ + pub fn process_result(self) -> ::Unpacked { + let response = self.step.into_response(); + let tuple_result = self.result_handler.list_process_result(&response); + tuple_result.flatten_unpack() + } +} + +pub trait StepWithResponse { + fn into_response(self) -> TxResponse; +} + +impl StepWithResponse for ScCallStep { + fn into_response(self) -> TxResponse { + self.response.expect("SC call step did not return result") + } +} + +impl StepWithResponse for ScDeployStep { + fn into_response(self) -> TxResponse { + self.response.expect("SC deploy step did not return result") + } +} + +impl StepWithResponse for ScQueryStep { + fn into_response(self) -> TxResponse { + self.response.expect("SC query step did not return result") + } +} diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs new file mode 100644 index 0000000000..475326eac7 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs @@ -0,0 +1,132 @@ +use multiversx_sc::types::{ + Code, FunctionCall, NotPayable, RHListExec, Tx, TxEnv, TxFromSpecified, TxGas, TxPayment, + TxToSpecified, UpgradeCall, +}; + +use crate::{ + imports::MxscPath, + scenario_model::{ScCallStep, TxESDT, TxExpect, TxResponse}, + ScenarioEnvExec, +}; + +use super::{address_annotated, gas_annotated, StepWrapper, TxToStep}; + +impl TxToStep + for Tx, RH> +where + Env: TxEnv, + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, + RH: RHListExec, +{ + type Step = ScCallStep; + + fn tx_to_step(self) -> StepWrapper { + let mut step = tx_to_sc_call_step( + &self.env, + self.from, + self.to, + self.payment, + self.gas, + self.data, + ); + step.expect = Some(self.result_handler.list_tx_expect()); + + StepWrapper { + env: self.env, + step, + result_handler: self.result_handler, + } + } +} + +pub fn tx_to_sc_call_step( + env: &Env, + from: From, + to: To, + payment: Payment, + gas: Gas, + data: FunctionCall, +) -> ScCallStep +where + Env: TxEnv, + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, +{ + let mut step = ScCallStep::new() + .from(address_annotated(env, &from)) + .to(address_annotated(env, &to)) + .function(data.function_name.to_string().as_str()); + for arg in data.arg_buffer.iter_buffers() { + step.tx.arguments.push(arg.to_vec().into()); + } + + step.tx.gas_limit = gas_annotated(env, gas); + + let full_payment_data = payment.into_full_payment_data(env); + if let Some(annotated_egld_payment) = full_payment_data.egld { + step.tx.egld_value = annotated_egld_payment.into(); + } else { + step.tx.esdt_value = full_payment_data + .multi_esdt + .iter() + .map(TxESDT::from) + .collect(); + } + + step +} + +impl<'w, From, To, RH> TxToStep, RH> + for Tx< + ScenarioEnvExec<'w>, + From, + To, + NotPayable, + (), + UpgradeCall, Code>>, + RH, + > +where + From: TxFromSpecified>, + To: TxToSpecified>, + RH: RHListExec>, +{ + type Step = ScCallStep; + + fn tx_to_step(self) -> StepWrapper, Self::Step, RH> { + let mut step = tx_to_sc_call_upgrade_step(&self.env, self.from, self.to, self.data); + step.expect = Some(self.result_handler.list_tx_expect()); + + StepWrapper { + env: self.env, + step, + result_handler: self.result_handler, + } + } +} + +pub fn tx_to_sc_call_upgrade_step<'a, 'w: 'a, From, To>( + env: &'a ScenarioEnvExec<'w>, + from: From, + to: To, + data: UpgradeCall, Code>, +) -> ScCallStep +where + From: TxFromSpecified>, + To: TxToSpecified>, +{ + let mut step = ScCallStep::new() + .from(address_annotated(env, &from)) + .to(address_annotated(env, &to)) + .function("upgrade"); + for arg in data.arg_buffer.iter_buffers() { + step.tx.arguments.push(arg.to_vec().into()); + } + + step +} diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs new file mode 100644 index 0000000000..4e49be51b4 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs @@ -0,0 +1,63 @@ +use multiversx_sc::types::{ + Code, DeployCall, RHListExec, Tx, TxCodeValue, TxEnv, TxFromSpecified, TxGas, TxPayment, +}; + +use crate::scenario_model::{ScDeployStep, TxExpect, TxResponse}; + +use super::{address_annotated, code_annotated, gas_annotated, StepWrapper, TxToStep}; + +impl TxToStep + for Tx>, RH> +where + Env: TxEnv, + From: TxFromSpecified, + Payment: TxPayment, + Gas: TxGas, + CodeValue: TxCodeValue, + RH: RHListExec, +{ + type Step = ScDeployStep; + + fn tx_to_step(self) -> StepWrapper { + let mut step = + tx_to_sc_deploy_step(&self.env, self.from, self.payment, self.gas, self.data); + step.expect = Some(self.result_handler.list_tx_expect()); + + StepWrapper { + env: self.env, + step, + result_handler: self.result_handler, + } + } +} + +pub fn tx_to_sc_deploy_step( + env: &Env, + from: From, + payment: Payment, + gas: Gas, + data: DeployCall>, +) -> ScDeployStep +where + Env: TxEnv, + From: TxFromSpecified, + Payment: TxPayment, + Gas: TxGas, + CodeValue: TxCodeValue, +{ + let mut step = ScDeployStep::new() + .from(address_annotated(env, &from)) + .code(code_annotated(env, data.code_source)); + for arg in data.arg_buffer.iter_buffers() { + step.tx.arguments.push(arg.to_vec().into()); + } + + step.tx.gas_limit = gas_annotated(env, gas); + + let full_payment_data = payment.into_full_payment_data(env); + if let Some(annotated_egld_payment) = full_payment_data.egld { + step.tx.egld_value = annotated_egld_payment.into(); + } + + step +} diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_query.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_query.rs new file mode 100644 index 0000000000..b9e25a707d --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_query.rs @@ -0,0 +1,42 @@ +use multiversx_sc::types::{FunctionCall, RHListExec, Tx, TxEnv, TxNoPayment, TxToSpecified}; + +use crate::scenario_model::{ScQueryStep, TxExpect, TxResponse}; + +use super::{address_annotated, StepWrapper, TxToQueryStep}; + +impl TxToQueryStep + for Tx, RH> +where + Env: TxEnv, + To: TxToSpecified, + Payment: TxNoPayment, + RH: RHListExec, +{ + type Step = ScQueryStep; + + fn tx_to_query_step(self) -> StepWrapper { + let mut step = tx_to_sc_query_step(&self.env, self.to, self.data); + step.expect = Some(self.result_handler.list_tx_expect()); + + StepWrapper { + env: self.env, + step, + result_handler: self.result_handler, + } + } +} + +pub fn tx_to_sc_query_step(env: &Env, to: To, data: FunctionCall) -> ScQueryStep +where + Env: TxEnv, + To: TxToSpecified, +{ + let mut step = ScQueryStep::new() + .to(address_annotated(env, &to)) + .function(data.function_name.to_string().as_str()); + for arg in data.arg_buffer.iter_buffers() { + step.tx.arguments.push(arg.to_vec().into()); + } + + step +} diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_trait.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_trait.rs new file mode 100644 index 0000000000..60615e6bb5 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_trait.rs @@ -0,0 +1,13 @@ +use super::StepWrapper; + +pub trait TxToStep { + type Step; + + fn tx_to_step(self) -> StepWrapper; +} + +pub trait TxToQueryStep { + type Step; + + fn tx_to_query_step(self) -> StepWrapper; +} diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs new file mode 100644 index 0000000000..d2bf9636c9 --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs @@ -0,0 +1,54 @@ +use multiversx_sc::types::{Tx, TxEnv, TxFromSpecified, TxGas, TxPayment, TxToSpecified}; + +use crate::scenario_model::TransferStep; + +use super::{address_annotated, gas_annotated, StepWrapper, TxToStep}; + +impl TxToStep for Tx +where + Env: TxEnv, + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, +{ + type Step = TransferStep; + + fn tx_to_step(self) -> StepWrapper { + let step = tx_to_transfer_step(&self.env, self.from, self.to, self.payment, self.gas); + + StepWrapper { + env: self.env, + step, + result_handler: self.result_handler, + } + } +} + +pub fn tx_to_transfer_step( + env: &Env, + from: From, + to: To, + payment: Payment, + gas: Gas, +) -> TransferStep +where + Env: TxEnv, + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, +{ + let mut step = TransferStep::new() + .from(address_annotated(env, &from)) + .to(address_annotated(env, &to)); + + step.tx.gas_limit = gas_annotated(env, gas); + + let full_payment_data = payment.into_full_payment_data(env); + if let Some(annotated_egld_payment) = full_payment_data.egld { + step.tx.egld_value = annotated_egld_payment.into(); + } + + step +} diff --git a/framework/scenario/src/standalone/account_tool.rs b/framework/scenario/src/standalone/account_tool.rs deleted file mode 100644 index c1f4c5f605..0000000000 --- a/framework/scenario/src/standalone/account_tool.rs +++ /dev/null @@ -1,142 +0,0 @@ -use super::scenario_cli::AccountArgs; -use multiversx_chain_scenario_format::serde_raw::{ - AccountRaw, EsdtFullRaw, EsdtInstanceRaw, EsdtRaw, ScenarioRaw, StepRaw, ValueSubTree, -}; -use multiversx_sdk::{ - blockchain::CommunicationProxy, - data::{address::Address, esdt::EsdtBalance}, -}; -use std::collections::{BTreeMap, HashMap}; - -pub async fn print_account_as_scenario_set_state(api: String, args: &AccountArgs) { - let scenario_raw = - retrieve_account_as_scenario_set_state(api, args.address.clone(), false).await; - println!("{}", scenario_raw.to_json_string()); -} - -pub async fn retrieve_account_as_scenario_set_state( - api: String, - addr: String, - hex_encoded: bool, -) -> ScenarioRaw { - let address = Address::from_bech32_string(&addr).unwrap(); - let blockchain = CommunicationProxy::new(api); - let account = blockchain.get_account(&address).await.unwrap(); - - let account_esdt = blockchain - .get_account_esdt_tokens(&address) - .await - .unwrap_or_else(|err| panic!("failed to retrieve ESDT tokens for address {addr}: {err}")); - let account_esdt_roles = blockchain - .get_account_esdt_roles(&address) - .await - .unwrap_or_else(|err| panic!("failed to retrieve ESDT roles for address {addr}: {err}")); - let account_storage = blockchain - .get_account_storage_keys(&address) - .await - .unwrap_or_else(|err| panic!("failed to retrieve storage for address {addr}: {err}")); - - let addr_pretty = if !hex_encoded { - if account.code.is_empty() { - format!("address:{addr}") - } else { - format!("sc:{addr}") - } - } else { - format!("0x{}", hex::encode(address.to_bytes())) - }; - - let mut accounts = BTreeMap::new(); - accounts.insert( - addr_pretty, - AccountRaw { - nonce: Some(ValueSubTree::Str(account.nonce.to_string())), - balance: Some(ValueSubTree::Str(account.balance.to_string())), - esdt: convert_esdt(account_esdt, account_esdt_roles), - username: Some(ValueSubTree::Str(account.username.to_string())), - storage: convert_storage(account_storage), - comment: None, - code: retrieve_code(account.code), - code_metadata: None, // TODO: retrieve code metadata - owner: None, - developer_rewards: None, - }, - ); - - ScenarioRaw { - check_gas: None, - comment: None, - gas_schedule: None, - name: None, - steps: vec![StepRaw::SetState { - accounts, - block_hashes: Vec::new(), - new_addresses: Vec::new(), - new_token_identifiers: Vec::new(), - comment: None, - current_block_info: None, - previous_block_info: None, - }], - } -} - -fn retrieve_code(code: String) -> Option { - if code.is_empty() { - None - } else { - Some(ValueSubTree::Str(format!("0x{code}"))) - } -} - -fn convert_storage(account_storage: HashMap) -> BTreeMap { - account_storage - .into_iter() - .filter(|(k, _)| !k.starts_with("454c524f4e44")) - .map(|(k, v)| (format!("0x{k}"), ValueSubTree::Str(format!("0x{v}")))) - .collect() -} - -fn convert_esdt( - sdk_esdt: HashMap, - sdk_esdt_roles: HashMap>, -) -> BTreeMap { - let mut result = BTreeMap::new(); - for (key, value) in sdk_esdt.into_iter() { - let (token_identifier, nonce) = split_token_identifer_nonce(key); - let esdt_raw = result - .entry(format!("str:{}", token_identifier.clone())) - .or_insert(EsdtRaw::Full(EsdtFullRaw::default())); - if let EsdtRaw::Full(esdt_full_raw) = esdt_raw { - esdt_full_raw.instances.push(EsdtInstanceRaw { - nonce: Some(ValueSubTree::Str(nonce.to_string())), - balance: Some(ValueSubTree::Str(value.balance)), - // TODO: add creator, royalties, etc ... - ..Default::default() - }); - } - } - - for (key, roles) in sdk_esdt_roles.into_iter() { - let (token_identifier, _) = split_token_identifer_nonce(key); - let esdt_raw = result - .entry(format!("str:{}", token_identifier.clone())) - .or_insert(EsdtRaw::Full(EsdtFullRaw::default())); - if let EsdtRaw::Full(esdt_full_raw) = esdt_raw { - esdt_full_raw.roles = roles; - } - } - - result -} - -fn split_token_identifer_nonce(full_identifier: String) -> (String, u64) { - let tokens = full_identifier.split('-').collect::>(); - match tokens.len() { - 2 => (full_identifier, 0), - 3 => ( - format!("{}-{}", tokens[0], tokens[1]), - u64::from_str_radix(tokens[2], 16).unwrap(), - ), - _ => panic!("could not process token identifier: {full_identifier}"), - } -} diff --git a/framework/scenario/src/standalone/mod.rs b/framework/scenario/src/standalone/mod.rs deleted file mode 100644 index 84ecea3916..0000000000 --- a/framework/scenario/src/standalone/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod account_tool; -mod scenario_cli; - -pub use account_tool::retrieve_account_as_scenario_set_state; -pub use scenario_cli::cli_main; diff --git a/framework/scenario/src/standalone/scenario_cli.rs b/framework/scenario/src/standalone/scenario_cli.rs deleted file mode 100644 index c7049728f4..0000000000 --- a/framework/scenario/src/standalone/scenario_cli.rs +++ /dev/null @@ -1,44 +0,0 @@ -use clap::{Args, Parser, Subcommand}; - -use super::account_tool; - -/// Parsed arguments of the meta crate CLI. -#[derive(Default, PartialEq, Eq, Debug, Parser)] -#[command(version, about)] -#[command(propagate_version = true)] -pub struct ScenarioCliArgs { - /// Provide the target API you want the real data to come from - #[arg(long = "api")] - #[clap(global = true)] - pub api: Option, - - #[command(subcommand)] - pub command: Option, -} - -#[derive(Clone, PartialEq, Eq, Debug, Subcommand)] -pub enum ScenarioCliAction { - #[command( - about = "Generates a scenario test initialized with real data fetched from the blockchain." - )] - Account(AccountArgs), -} - -#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] -pub struct AccountArgs { - /// Provide the address you want to retrieve data from - #[arg(long = "address", verbatim_doc_comment)] - pub address: String, -} - -/// Entry point in the program when calling it as a standalone tool. -pub async fn cli_main() { - let cli_args = ScenarioCliArgs::parse(); - let api = cli_args.api.expect("API needs tp be specified"); - match &cli_args.command { - Some(ScenarioCliAction::Account(args)) => { - account_tool::print_account_as_scenario_set_state(api, args).await; - }, - None => {}, - } -} diff --git a/framework/scenario/src/whitebox_legacy.rs b/framework/scenario/src/whitebox_legacy.rs index aec0d8c980..9d90a4cb7e 100644 --- a/framework/scenario/src/whitebox_legacy.rs +++ b/framework/scenario/src/whitebox_legacy.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod address_factory; mod contract_obj_wrapper; mod mandos_generator; diff --git a/framework/scenario/src/whitebox_legacy/contract_obj_wrapper.rs b/framework/scenario/src/whitebox_legacy/contract_obj_wrapper.rs index edb4f8f019..b88377b98d 100644 --- a/framework/scenario/src/whitebox_legacy/contract_obj_wrapper.rs +++ b/framework/scenario/src/whitebox_legacy/contract_obj_wrapper.rs @@ -16,9 +16,8 @@ use multiversx_chain_scenario_format::interpret_trait::InterpretableFrom; use multiversx_chain_vm::{ tx_mock::{TxContext, TxContextStack, TxFunctionName, TxResult}, types::VMAddress, - world_mock::EsdtInstanceMetadata, }; -use multiversx_sc::types::H256; +use multiversx_sc::types::{BigUint, H256}; use num_traits::Zero; use super::{ @@ -180,7 +179,8 @@ impl BlockchainStateWrapper { impl BlockchainStateWrapper { pub fn create_user_account(&mut self, egld_balance: &num_bigint::BigUint) -> Address { let address = self.address_factory.new_address(); - self.create_account_raw(&address, egld_balance, None, None, None); + self.world + .create_account_raw(&address, BigUint::from(egld_balance)); address } @@ -190,7 +190,8 @@ impl BlockchainStateWrapper { address: &Address, egld_balance: &num_bigint::BigUint, ) { - self.create_account_raw(address, egld_balance, None, None, None); + self.world + .create_account_raw(address, BigUint::from(egld_balance)); } pub fn create_sc_account( @@ -288,15 +289,8 @@ impl BlockchainStateWrapper { _sc_identifier: Option>, _sc_mandos_path_expr: Option>, ) { - let vm_address = to_vm_address(address); - if self.world.get_state().account_exists(&vm_address) { - panic!("Address already used: {:?}", address_to_hex(address)); - } - - let account = Account::new().balance(egld_balance); - self.world - .set_state_step(SetStateStep::new().put_account(address, account)); + .create_account_raw(address, BigUint::from(egld_balance)); } // Has to be used before perfoming a deploy from a SC @@ -344,19 +338,7 @@ impl BlockchainStateWrapper { } pub fn set_egld_balance(&mut self, address: &Address, balance: &num_bigint::BigUint) { - let vm_address = to_vm_address(address); - match self.world.get_mut_state().accounts.get_mut(&vm_address) { - Some(acc) => { - acc.egld_balance = balance.clone(); - - self.add_mandos_set_account(address); - }, - - None => panic!( - "set_egld_balance: Account {:?} does not exist", - address_to_hex(address) - ), - } + self.world.set_egld_balance(address, BigUint::from(balance)); } pub fn set_esdt_balance( @@ -365,23 +347,8 @@ impl BlockchainStateWrapper { token_id: &[u8], balance: &num_bigint::BigUint, ) { - let vm_address = to_vm_address(address); - match self.world.get_mut_state().accounts.get_mut(&vm_address) { - Some(acc) => { - acc.esdt.set_esdt_balance( - token_id.to_vec(), - 0, - balance, - EsdtInstanceMetadata::default(), - ); - - self.add_mandos_set_account(address); - }, - None => panic!( - "set_esdt_balance: Account {:?} does not exist", - address_to_hex(address) - ), - } + self.world + .set_esdt_balance(address, token_id, BigUint::from(balance)); } pub fn set_nft_balance( @@ -392,14 +359,14 @@ impl BlockchainStateWrapper { balance: &num_bigint::BigUint, attributes: &T, ) { - self.set_nft_balance_all_properties( + self.world.set_nft_balance_all_properties( address, token_id, nonce, - balance, + BigUint::from(balance), attributes, 0, - None, + None::
, None, None, &[], @@ -411,18 +378,8 @@ impl BlockchainStateWrapper { address: &Address, developer_rewards: num_bigint::BigUint, ) { - let vm_address: VMAddress = to_vm_address(address); - match self.world.get_mut_state().accounts.get_mut(&vm_address) { - Some(acc) => { - acc.developer_rewards = developer_rewards; - - self.add_mandos_set_account(address); - }, - None => panic!( - "set_developer_rewards: Account {:?} does not exist", - address_to_hex(address) - ), - } + self.world + .set_developer_rewards(address, &developer_rewards); } #[allow(clippy::too_many_arguments)] @@ -439,30 +396,18 @@ impl BlockchainStateWrapper { hash: Option<&[u8]>, uris: &[Vec], ) { - let vm_address = to_vm_address(address); - match self.world.get_mut_state().accounts.get_mut(&vm_address) { - Some(acc) => { - acc.esdt.set_esdt_balance( - token_id.to_vec(), - nonce, - balance, - EsdtInstanceMetadata { - creator: creator.map(to_vm_address), - attributes: serialize_attributes(attributes), - royalties, - name: name.unwrap_or_default().to_vec(), - hash: hash.map(|h| h.to_vec()), - uri: uris.to_vec(), - }, - ); - - self.add_mandos_set_account(address); - }, - None => panic!( - "set_nft_balance: Account {:?} does not exist", - address_to_hex(address) - ), - } + self.world.set_nft_balance_all_properties( + address, + token_id, + nonce, + BigUint::from(balance), + attributes, + royalties, + creator, + name, + hash, + uris, + ); } pub fn set_esdt_local_roles( @@ -471,22 +416,7 @@ impl BlockchainStateWrapper { token_id: &[u8], roles: &[EsdtLocalRole], ) { - let vm_address = to_vm_address(address); - match self.world.get_mut_state().accounts.get_mut(&vm_address) { - Some(acc) => { - let mut roles_raw = Vec::new(); - for role in roles { - roles_raw.push(role.as_role_name().to_vec()); - } - acc.esdt.set_roles(token_id.to_vec(), roles_raw); - - self.add_mandos_set_account(address); - }, - None => panic!( - "set_esdt_local_roles: Account {:?} does not exist", - address_to_hex(address) - ), - } + self.world.set_esdt_local_roles(address, token_id, roles); } pub fn set_block_epoch(&mut self, block_epoch: u64) { @@ -856,15 +786,6 @@ fn address_to_hex(address: &Address) -> String { hex::encode(address.as_bytes()) } -fn serialize_attributes(attributes: &T) -> Vec { - let mut serialized_attributes = Vec::new(); - if let Result::Err(err) = attributes.top_encode(&mut serialized_attributes) { - panic!("Failed to encode attributes: {err:?}") - } - - serialized_attributes -} - fn print_token_balance_raw( token_nonce: u64, token_balance: &num_bigint::BigUint, diff --git a/framework/scenario/src/whitebox_legacy/tx_mandos.rs b/framework/scenario/src/whitebox_legacy/tx_mandos.rs index 6d7babb5ba..505591bc68 100644 --- a/framework/scenario/src/whitebox_legacy/tx_mandos.rs +++ b/framework/scenario/src/whitebox_legacy/tx_mandos.rs @@ -31,7 +31,7 @@ impl ScCallMandos { } pub fn add_egld_value(&mut self, egld_value: &num_bigint::BigUint) { - self.egld_value = egld_value.clone(); + self.egld_value.clone_from(egld_value); } pub fn add_esdt_transfer( @@ -101,6 +101,6 @@ impl TxExpectMandos { } pub fn set_message(&mut self, msg: &str) { - self.message = msg.to_owned(); + self.message = msg.to_string(); } } diff --git a/framework/scenario/tests/contract_call_test.rs b/framework/scenario/tests/contract_call_test.rs index cacd39fd96..b6ff5ea1fb 100644 --- a/framework/scenario/tests/contract_call_test.rs +++ b/framework/scenario/tests/contract_call_test.rs @@ -3,6 +3,7 @@ use multiversx_sc_scenario::scenario_model::ScCallStep; use num_traits::Zero; #[test] +#[allow(deprecated)] fn test_contract_call_multi_esdt() { let tx = ScCallStep::new() .from("address:sender") diff --git a/framework/scenario/tests/contract_without_macros.rs b/framework/scenario/tests/contract_without_macros.rs index 0252be4b1e..1121e88fdd 100644 --- a/framework/scenario/tests/contract_without_macros.rs +++ b/framework/scenario/tests/contract_without_macros.rs @@ -9,7 +9,7 @@ #![allow(unused)] use multiversx_sc::{ - contract_base::ProxyObjBase, + contract_base::ProxyObjNew, types::{BigInt, ManagedAddress}, }; use multiversx_sc_scenario::api::{SingleTxApi, StaticApi}; @@ -102,11 +102,116 @@ mod module_1 { } pub trait ProxyTrait: multiversx_sc::contract_base::ProxyObjBase + Sized { + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] fn version( &mut self, - ) -> multiversx_sc::types::ContractCallNoPayment> { - let ___address___ = self.extract_address(); - multiversx_sc::types::ContractCallNoPayment::new(___address___, "version") + ) -> multiversx_sc::types::Tx< + multiversx_sc::types::TxScEnv, + (), + Self::To, + (), + (), + multiversx_sc::types::FunctionCall, + multiversx_sc::types::OriginalResultMarker>, + > { + multiversx_sc::types::TxBaseWithEnv::new_tx_from_sc() + .to(self.extract_proxy_to()) + .original_result() + .raw_call("version") + } + } +} + +mod sampler_adder_proxy { + #![allow(dead_code)] + #![allow(clippy::all)] + use multiversx_sc::proxy_imports::*; + pub struct AdderProxy; + impl TxProxyTrait for AdderProxy + where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, + { + type TxProxyMethods = AdderProxyMethods; + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + AdderProxyMethods { wrapped_tx: tx } + } + } + pub struct AdderProxyMethods + where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, + { + wrapped_tx: Tx, + } + #[rustfmt::skip] + impl AdderProxyMethods + where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, + { + pub fn init>>( + self, + initial_value: Arg0, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .argument(&initial_value) + .original_result() + } + } + #[rustfmt::skip] + impl AdderProxyMethods + where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, + { + pub fn upgrade>>( + self, + initial_value: Arg0, + ) -> TxTypedUpgrade { + self.wrapped_tx + .payment(NotPayable) + .raw_upgrade() + .argument(&initial_value) + .original_result() + } + } + #[rustfmt::skip] + impl AdderProxyMethods + where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, + { + pub fn sum( + self, + ) -> TxTypedCall> { + self.wrapped_tx.payment(NotPayable).raw_call("getSum").original_result() + } + /// Add desired amount to the storage variable. + pub fn add>>( + self, + value: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("add") + .argument(&value) + .original_result() } } } @@ -120,21 +225,25 @@ mod sample_adder { pub trait Adder: super::module_1::VersionModule + multiversx_sc::contract_base::ContractBase + Sized { - fn init(&self, initial_value: &BigInt) { - self.set_sum(initial_value); + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] + fn init(&self, initial_value: multiversx_sc::types::BigUint) { + self.sum().set(initial_value); } - fn add(&self, value: BigInt) { - let mut sum = self.get_sum(); - sum.add_assign(value); - self.set_sum(&sum); + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] + fn upgrade(&self, initial_value: multiversx_sc::types::BigUint) { + self.init(initial_value); } - fn get_sum(&self) -> BigInt; - fn set_sum(&self, sum: &BigInt); - fn add_version(&self) { - self.add(self.version()) + /// Add desired amount to the storage variable. + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] + fn add(&self, value: multiversx_sc::types::BigUint) { + self.sum().update(|sum| *sum += value); } - fn callback(&self); - fn callbacks(&self) -> self::CallbackProxyObj; + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] + fn sum(&self) -> SingleValueMapper>; } ///////////////////////////////////////////////////////////////////////////////////////////////// @@ -148,17 +257,14 @@ mod sample_adder { where C: AutoImpl + super::module_1::AutoImpl, { - fn get_sum(&self) -> BigInt { - let mut ___key___ = multiversx_sc::storage::StorageKey::::new(&b"sum"[..]); - multiversx_sc::storage_get(multiversx_sc::types::ManagedRef::new(&___key___)) - } - fn set_sum(&self, sum: &BigInt) { + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] + fn sum(&self) -> SingleValueMapper> { let mut ___key___ = multiversx_sc::storage::StorageKey::::new(&b"sum"[..]); - multiversx_sc::storage_set(multiversx_sc::types::ManagedRef::new(&___key___), &sum); - } - fn callback(&self) {} - fn callbacks(&self) -> self::CallbackProxyObj { - as multiversx_sc::contract_base::CallbackProxyObjBase>::new_cb_proxy_obj() + , + > as multiversx_sc::storage::mappers::StorageMapper>::new(___key___) } } @@ -171,11 +277,11 @@ mod sample_adder { Adder + multiversx_sc::contract_base::ContractBase + super::module_1::EndpointWrappers { #[inline] - fn call_get_sum(&self) { + fn call_sum(&self) { ::init_static(); multiversx_sc::io::call_value_init::not_payable::(); let () = multiversx_sc::io::load_endpoint_args::(()); - let result = self.get_sum(); + let result = self.sum(); multiversx_sc::io::finish_multi::(&result); } #[inline] @@ -184,9 +290,19 @@ mod sample_adder { multiversx_sc::io::call_value_init::not_payable::(); let (initial_value, ()) = multiversx_sc::io::load_endpoint_args::< Self::Api, - (multiversx_sc::types::BigInt, ()), + (multiversx_sc::types::BigUint, ()), >(("initial_value", ())); - self.init(&initial_value); + self.init(initial_value); + } + #[inline] + fn call_upgrade(&self) { + ::init_static(); + multiversx_sc::io::call_value_init::not_payable::(); + let (initial_value, ()) = multiversx_sc::io::load_endpoint_args::< + Self::Api, + (multiversx_sc::types::BigUint, ()), + >(("initial_value", ())); + self.upgrade(initial_value); } #[inline] fn call_add(&self) { @@ -194,38 +310,55 @@ mod sample_adder { multiversx_sc::io::call_value_init::not_payable::(); let (value, ()) = multiversx_sc::io::load_endpoint_args::< Self::Api, - (multiversx_sc::types::BigInt, ()), + (multiversx_sc::types::BigUint, ()), >(("value", ())); self.add(value); } - fn call(&self, fn_name: &str) -> bool { if match fn_name { "callBack" => { - Adder::callback(self); + self::EndpointWrappers::callback(self); + return true; + }, + "init" + if ::external_view_init_override() => + { + multiversx_sc::external_view_contract::external_view_contract_constructor::< + Self::Api, + >(); return true; }, "getSum" => { - self.call_get_sum(); + self.call_sum(); true }, - "init" => { + "init" + if !::external_view_init_override() => + { self.call_init(); true }, + "upgrade" => { + self.call_upgrade(); + true + }, "add" => { self.call_add(); true }, - _other => false, + other => false, } { return true; } - if super::module_1::EndpointWrappers::call(self, fn_name) { - return true; - } false } + fn callback_selector( + &self, + mut ___cb_closure___: multiversx_sc::types::CallbackClosureForDeser, + ) -> multiversx_sc::types::CallbackSelectorResult { + multiversx_sc::types::CallbackSelectorResult::NotProcessed(___cb_closure___) + } + fn callback(&self) {} } impl EndpointWrappers for multiversx_sc::contract_base::UniversalContractObj where @@ -233,24 +366,224 @@ mod sample_adder { { } + pub struct AbiProvider {} + impl multiversx_sc::contract_base::ContractAbiProvider for AbiProvider { + type Api = multiversx_sc::api::uncallable::UncallableApi; + fn abi() -> multiversx_sc::abi::ContractAbi { + let mut contract_abi = multiversx_sc::abi::ContractAbi::new( + multiversx_sc::abi::BuildInfoAbi { + contract_crate: multiversx_sc::abi::ContractCrateBuildAbi { + name: "adder", + version: "0.0.0", + git_version: "", + }, + framework: multiversx_sc::abi::FrameworkBuildAbi::create(), + }, + &[ + "One of the simplest smart contracts possible,", + "it holds a single variable in storage, which anyone can increment.", + ], + "Adder", + false, + ); + let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new( + &[], + "getSum", + "sum", + false, + false, + multiversx_sc::abi::EndpointMutabilityAbi::Readonly, + multiversx_sc::abi::EndpointTypeAbi::Endpoint, + &[], + &[], + false, + ); + endpoint_abi + .add_output::< + SingleValueMapper>, + >(&[]); + contract_abi + .add_type_descriptions::< + SingleValueMapper>, + >(); + contract_abi.endpoints.push(endpoint_abi); + let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new( + &[], + "init", + "init", + false, + false, + multiversx_sc::abi::EndpointMutabilityAbi::Mutable, + multiversx_sc::abi::EndpointTypeAbi::Init, + &[], + &[], + false, + ); + endpoint_abi.add_input::>("initial_value"); + contract_abi.add_type_descriptions::>(); + contract_abi.constructors.push(endpoint_abi); + let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new( + &[], + "upgrade", + "upgrade", + false, + false, + multiversx_sc::abi::EndpointMutabilityAbi::Mutable, + multiversx_sc::abi::EndpointTypeAbi::Upgrade, + &[], + &[], + false, + ); + endpoint_abi.add_input::>("initial_value"); + contract_abi.add_type_descriptions::>(); + contract_abi.upgrade_constructors.push(endpoint_abi); + let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new( + &["Add desired amount to the storage variable."], + "add", + "add", + false, + false, + multiversx_sc::abi::EndpointMutabilityAbi::Mutable, + multiversx_sc::abi::EndpointTypeAbi::Endpoint, + &[], + &[], + false, + ); + endpoint_abi.add_input::>("value"); + contract_abi.add_type_descriptions::>(); + contract_abi.endpoints.push(endpoint_abi); + contract_abi + } + } + + #[allow(non_snake_case)] + pub mod endpoints { + use super::EndpointWrappers; + pub fn sum() + where + A: multiversx_sc::api::VMApi, + { + super::EndpointWrappers::call_sum( + &multiversx_sc::contract_base::UniversalContractObj::::new(), + ); + } + pub fn init() + where + A: multiversx_sc::api::VMApi, + { + super::EndpointWrappers::call_init( + &multiversx_sc::contract_base::UniversalContractObj::::new(), + ); + } + pub fn upgrade() + where + A: multiversx_sc::api::VMApi, + { + super::EndpointWrappers::call_upgrade( + &multiversx_sc::contract_base::UniversalContractObj::::new(), + ); + } + pub fn add() + where + A: multiversx_sc::api::VMApi, + { + super::EndpointWrappers::call_add( + &multiversx_sc::contract_base::UniversalContractObj::::new(), + ); + } + pub fn callBack() + where + A: multiversx_sc::api::VMApi, + { + super::EndpointWrappers::callback( + &multiversx_sc::contract_base::UniversalContractObj::::new(), + ); + } + } pub trait ProxyTrait: multiversx_sc::contract_base::ProxyObjBase + super::module_1::ProxyTrait { - fn get_sum( + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] + fn sum( + &mut self, + ) -> multiversx_sc::types::Tx< + multiversx_sc::types::TxScEnv, + (), + Self::To, + (), + (), + multiversx_sc::types::FunctionCall, + multiversx_sc::types::OriginalResultMarker< + SingleValueMapper>, + >, + > { + multiversx_sc::types::TxBaseWithEnv::new_tx_from_sc() + .to(self.extract_proxy_to()) + .original_result() + .raw_call("getSum") + } + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] + fn init>>( + &mut self, + initial_value: Arg0, + ) -> multiversx_sc::types::Tx< + multiversx_sc::types::TxScEnv, + (), + Self::To, + (), + (), + multiversx_sc::types::DeployCall, ()>, + multiversx_sc::types::OriginalResultMarker<()>, + > { + multiversx_sc::types::TxBaseWithEnv::new_tx_from_sc() + .raw_deploy() + .argument(&initial_value) + .original_result() + .to(self.extract_proxy_to()) + } + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] + fn upgrade< + Arg0: multiversx_sc::types::ProxyArg>, + >( &mut self, - ) -> multiversx_sc::types::ContractCallNoPayment> { - let ___address___ = self.extract_address(); - multiversx_sc::types::ContractCallNoPayment::new(___address___, "get_sum") + initial_value: Arg0, + ) -> multiversx_sc::types::Tx< + multiversx_sc::types::TxScEnv, + (), + Self::To, + (), + (), + multiversx_sc::types::FunctionCall, + multiversx_sc::types::OriginalResultMarker<()>, + > { + multiversx_sc::types::TxBaseWithEnv::new_tx_from_sc() + .to(self.extract_proxy_to()) + .original_result() + .raw_call("upgrade") + .argument(&initial_value) } - fn add( + #[allow(clippy::too_many_arguments)] + #[allow(clippy::type_complexity)] + fn add>>( &mut self, - amount: &BigInt, - ) -> multiversx_sc::types::ContractCallNoPayment { - let ___address___ = self.extract_address(); - let mut ___contract_call___ = - multiversx_sc::types::ContractCallNoPayment::new(___address___, "add"); - multiversx_sc::types::ContractCall::proxy_arg(&mut ___contract_call___, amount); - ___contract_call___ + value: Arg0, + ) -> multiversx_sc::types::Tx< + multiversx_sc::types::TxScEnv, + (), + Self::To, + (), + (), + multiversx_sc::types::FunctionCall, + multiversx_sc::types::OriginalResultMarker<()>, + > { + multiversx_sc::types::TxBaseWithEnv::new_tx_from_sc() + .to(self.extract_proxy_to()) + .original_result() + .raw_call("add") + .argument(&value) } } @@ -287,17 +620,21 @@ mod sample_adder { A: multiversx_sc::api::VMApi, { fn call(&self, fn_name: &str) -> bool { - EndpointWrappers::call( - &multiversx_sc::contract_base::UniversalContractObj::::new(), - fn_name, - ) + EndpointWrappers::call(self, fn_name) } } + pub fn contract_obj() -> ContractObj + where + A: multiversx_sc::api::VMApi, + { + ContractObj { + _phantom: core::marker::PhantomData, + } + } pub struct ContractBuilder; - - impl multiversx_sc::contract_base::CallableContractBuilder for ContractBuilder { - fn new_contract_obj( + impl multiversx_sc::contract_base::CallableContractBuilder for self::ContractBuilder { + fn new_contract_obj( &self, ) -> multiversx_sc::types::heap::Box { @@ -307,26 +644,62 @@ mod sample_adder { } } - pub struct AbiProvider {} + pub struct Proxy + where + A: multiversx_sc::api::VMApi + 'static, + { + _phantom: core::marker::PhantomData, + } - impl multiversx_sc::contract_base::ContractAbiProvider for AbiProvider { - type Api = multiversx_sc::api::uncallable::UncallableApi; + impl multiversx_sc::contract_base::ProxyObjBase for Proxy + where + A: multiversx_sc::api::VMApi + 'static, + { + type Api = A; + type To = (); - fn abi() -> multiversx_sc::abi::ContractAbi { - multiversx_sc::abi::ContractAbi::default() + fn extract_opt_address( + &mut self, + ) -> multiversx_sc::types::ManagedOption< + Self::Api, + multiversx_sc::types::ManagedAddress, + > { + multiversx_sc::types::ManagedOption::none() + } + + fn extract_address(&mut self) -> multiversx_sc::types::ManagedAddress { + multiversx_sc::api::ErrorApiImpl::signal_error( + &::error_api_impl(), + multiversx_sc::err_msg::RECIPIENT_ADDRESS_NOT_SET.as_bytes(), + ) } + + fn extract_proxy_to(&mut self) -> Self::To {} } - pub fn contract_obj() -> ContractObj + impl multiversx_sc::contract_base::ProxyObjNew for Proxy where - A: multiversx_sc::api::VMApi, + A: multiversx_sc::api::VMApi + 'static, { - ContractObj { - _phantom: core::marker::PhantomData, + type ProxyTo = ProxyTo; + + fn new_proxy_obj() -> Self { + Proxy { + _phantom: core::marker::PhantomData, + } + } + + fn contract( + mut self, + address: multiversx_sc::types::ManagedAddress, + ) -> Self::ProxyTo { + ProxyTo { + address: multiversx_sc::types::ManagedOption::some(address), + } } } - pub struct Proxy + pub struct ProxyTo where A: multiversx_sc::api::VMApi + 'static, { @@ -334,22 +707,12 @@ mod sample_adder { multiversx_sc::types::ManagedOption>, } - impl multiversx_sc::contract_base::ProxyObjBase for Proxy + impl multiversx_sc::contract_base::ProxyObjBase for ProxyTo where A: multiversx_sc::api::VMApi + 'static, { type Api = A; - - fn new_proxy_obj() -> Self { - Proxy { - address: multiversx_sc::types::ManagedOption::none(), - } - } - - fn contract(mut self, address: multiversx_sc::types::ManagedAddress) -> Self { - self.address = multiversx_sc::types::ManagedOption::some(address); - self - } + type To = multiversx_sc::types::ManagedAddress; fn extract_opt_address( &mut self, @@ -370,11 +733,17 @@ mod sample_adder { ); address.unwrap_or_sc_panic(multiversx_sc::err_msg::RECIPIENT_ADDRESS_NOT_SET) } + + fn extract_proxy_to(&mut self) -> Self::To { + self.extract_address() + } } impl super::module_1::ProxyTrait for Proxy where A: multiversx_sc::api::VMApi {} + impl super::module_1::ProxyTrait for ProxyTo where A: multiversx_sc::api::VMApi {} impl ProxyTrait for Proxy where A: multiversx_sc::api::VMApi {} + impl ProxyTrait for ProxyTo where A: multiversx_sc::api::VMApi {} pub struct CallbackProxyObj where @@ -413,29 +782,26 @@ fn contract_without_macros_basic() { let adder = sample_adder::contract_obj::(); - adder.init(&BigInt::from(5)); - assert_eq!(BigInt::from(5), adder.get_sum()); - - adder.add(BigInt::from(7)); - assert_eq!(BigInt::from(12), adder.get_sum()); + adder.init(multiversx_sc::types::BigUint::from(5u32)); + assert_eq!(multiversx_sc::types::BigUint::from(5u32), adder.sum().get()); - adder.add(BigInt::from(-1)); - assert_eq!(BigInt::from(11), adder.get_sum()); + adder.add(multiversx_sc::types::BigUint::from(7u32)); + assert_eq!( + multiversx_sc::types::BigUint::from(12u32), + adder.sum().get() + ); assert_eq!(BigInt::from(100), adder.version()); - adder.add_version(); - assert_eq!(BigInt::from(111), adder.get_sum()); - assert!(!adder.call("invalid_endpoint")); - assert!(adder.call("version")); + assert!(adder.call("getSum")); let mut own_proxy = sample_adder::Proxy::::new_proxy_obj().contract(ManagedAddress::zero()); - let _ = own_proxy.get_sum(); + let _ = own_proxy.sum(); - let _ = multiversx_sc_meta::abi_json::contract_abi::(); + let _ = multiversx_sc_meta_lib::abi_json::contract_abi::(); } fn world() -> multiversx_sc_scenario::ScenarioWorld { diff --git a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs index 66bafe5278..9e0cfa8c74 100644 --- a/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_biguint_test.rs @@ -3,7 +3,7 @@ use multiversx_sc::{ codec, codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, derive::ManagedVecItem, - types::{BigUint, ManagedType}, + types::{BigUint, ManagedType, ManagedVecItemPayload}, }; use multiversx_sc_scenario::api::StaticApi; @@ -22,7 +22,8 @@ pub struct ManagedStructWithBigUint { #[allow(clippy::assertions_on_constants)] fn struct_with_numbers_static() { assert_eq!( - as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE, + as multiversx_sc::types::ManagedVecItem>::payload_size( + ), 8 ); assert!( @@ -37,8 +38,9 @@ fn managed_struct_to_bytes_writer() { big_uint: BigUint::from(fortytwo), num: 0x12345, }; - let mut arr: [u8; 8] = [0u8; - as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE]; + + let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); + let payload_slice = payload.payload_slice_mut(); let handle_bytes = s.big_uint.get_handle().to_be_bytes(); let expected = [0xff, 0xff, 0xff, handle_bytes[3], 0x00, 0x01, 0x23, 0x45]; @@ -46,9 +48,9 @@ fn managed_struct_to_bytes_writer() { as multiversx_sc::types::ManagedVecItem>::to_byte_writer( &s, |bytes| { - arr[0.. as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE].copy_from_slice(bytes); + payload_slice.copy_from_slice(bytes); - assert_eq!(arr, expected); + assert_eq!(payload_slice, expected); }, ); } @@ -68,7 +70,7 @@ fn managed_struct_from_bytes_reader() { bytes.copy_from_slice( &arr [0 - .. as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE], + .. as multiversx_sc::types::ManagedVecItem>::payload_size()], ); }, ); diff --git a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs index 1e0889c27c..fc7d95343e 100644 --- a/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_esdt_token_payment_test.rs @@ -3,7 +3,10 @@ use multiversx_sc::{ codec, codec::derive::{NestedDecode, NestedEncode, TopDecode, TopEncode}, derive::ManagedVecItem, - types::{BigUint, EsdtTokenPayment, ManagedByteArray, ManagedType, TokenIdentifier}, + types::{ + BigUint, EsdtTokenPayment, ManagedByteArray, ManagedType, ManagedVecItemPayload, + TokenIdentifier, + }, }; use multiversx_sc_scenario::api::StaticApi; @@ -26,7 +29,7 @@ pub struct ManagedStructWithToken { #[allow(clippy::assertions_on_constants)] fn struct_with_numbers_static() { assert_eq!( - as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE, + as multiversx_sc::types::ManagedVecItem>::payload_size(), 28 ); assert!( @@ -46,8 +49,9 @@ fn struct_to_bytes_writer() { eth_address_1: ManagedByteArray::new_from_bytes(&[1u8; 20]), eth_address_2: ManagedByteArray::new_from_bytes(&[2u8; 20]), }; - let mut arr: [u8; 28] = [0u8; - as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE]; + + let mut payload = as multiversx_sc::types::ManagedVecItem>::PAYLOAD::new_buffer(); + let payload_slice = payload.payload_slice_mut(); let handle1 = s.token.token_identifier.get_handle().to_be_bytes(); let handle2 = s.token.amount.get_handle().to_be_bytes(); @@ -62,11 +66,9 @@ fn struct_to_bytes_writer() { as multiversx_sc::types::ManagedVecItem>::to_byte_writer( &s, |bytes| { - arr[0 - .. as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE] - .copy_from_slice(bytes); + payload_slice.copy_from_slice(bytes); - assert_eq!(arr, expected); + assert_eq!(payload_slice, expected); }, ); } @@ -96,7 +98,7 @@ fn struct_from_bytes_reader() { bytes.copy_from_slice( &arr [0 - .. as multiversx_sc::types::ManagedVecItem>::PAYLOAD_SIZE], + .. as multiversx_sc::types::ManagedVecItem>::payload_size()], ); }, ); diff --git a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs index 23e7caca77..1c139f5b84 100644 --- a/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs +++ b/framework/scenario/tests/derive_managed_vec_item_simple_enum.rs @@ -19,7 +19,7 @@ enum SimpleEnum { #[allow(clippy::assertions_on_constants)] fn enum_static() { assert_eq!( - ::PAYLOAD_SIZE, + ::payload_size(), 1 ); assert!(::SKIPS_RESERIALIZATION); diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs index f69056f5d6..e5ee344e3c 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_1_test.rs @@ -1,4 +1,7 @@ -use multiversx_sc::codec::test_util::{check_dep_encode_decode, check_top_encode_decode}; +use multiversx_sc::{ + codec::test_util::{check_dep_encode_decode, check_top_encode_decode}, + types::ManagedVecItemPayload, +}; multiversx_sc::derive_imports!(); @@ -20,7 +23,7 @@ pub struct Struct1 { #[allow(clippy::assertions_on_constants)] fn struct_1_static() { assert_eq!( - ::PAYLOAD_SIZE, + ::payload_size(), 16 ); assert!(::SKIPS_RESERIALIZATION); @@ -39,13 +42,13 @@ fn struct_1_encode_decode_skips_reserialization() { }; #[rustfmt::skip] - let bytes_1 = &[ - /* u_8 */ 0x01, - /* u_16 */ 0x00, 0x02, - /* u_32 */ 0x00, 0x00, 0x00, 0x03, - /* u_64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - /* bool */ 0x01, - ]; + let bytes_1 = &[ + /* u_8 */ 0x01, + /* u_16 */ 0x00, 0x02, + /* u_32 */ 0x00, 0x00, 0x00, 0x03, + /* u_64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + /* bool */ 0x01, + ]; check_top_encode_decode(s.clone(), bytes_1); check_dep_encode_decode(s, bytes_1); @@ -60,13 +63,14 @@ fn struct_1_to_bytes_writer() { u_64: 4u64, bool_field: true, }; - let mut arr: [u8; 16] = [0u8; ::PAYLOAD_SIZE]; + + let mut payload = ::PAYLOAD::new_buffer(); + let payload_slice = payload.payload_slice_mut(); ::to_byte_writer(&s, |bytes| { - arr[0..::PAYLOAD_SIZE] - .copy_from_slice(bytes); + payload_slice.copy_from_slice(bytes); assert_eq!( - arr, + payload_slice, [ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, @@ -92,7 +96,7 @@ fn struct_1_from_bytes_reader() { let struct_from_bytes = ::from_byte_reader(|bytes| { bytes.copy_from_slice( - &arr[0..::PAYLOAD_SIZE], + &arr[0..::payload_size()], ); }); assert_eq!(s, struct_from_bytes); diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs index 3adfbb34bd..87fee5ed62 100644 --- a/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs +++ b/framework/scenario/tests/derive_managed_vec_item_struct_2_test.rs @@ -13,14 +13,14 @@ pub struct Struct2 { pub u_64: u64, pub bool_field: bool, pub opt_field: Option, - pub arr: [u16; 2], + pub arr: u32, } #[test] #[allow(clippy::assertions_on_constants)] fn struct_2_static() { assert_eq!( - ::PAYLOAD_SIZE, + ::payload_size(), 22 ); assert!(!::SKIPS_RESERIALIZATION); @@ -35,19 +35,19 @@ fn struct_to_bytes_writer() { u_64: 4u64, bool_field: true, opt_field: Some(5), - arr: [0x6111, 0x6222], + arr: 0x61116222, }; #[rustfmt::skip] - let expected_payload = &[ - /* u_8 */ 0x01, - /* u_16 */ 0x00, 0x02, - /* u_32 */ 0x00, 0x00, 0x00, 0x03, - /* u_64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - /* bool */ 0x01, + let expected_payload = &[ + /* u_8 */ 0x01, + /* u_16 */ 0x00, 0x02, + /* u_32 */ 0x00, 0x00, 0x00, 0x03, + /* u_64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + /* bool */ 0x01, /* opt */ 0x01, 0x05, /* arr */ 0x61, 0x11, 0x62, 0x22, - ]; + ]; ::to_byte_writer(&s, |bytes| { assert_eq!(bytes, &expected_payload[..]); @@ -63,19 +63,19 @@ fn struct_2_from_bytes_reader() { u_64: 4u64, bool_field: false, opt_field: Some(5), - arr: [0x6111, 0x6222], + arr: 0x61116222, }; #[rustfmt::skip] - let payload = &[ - /* u_8 */ 0x01, - /* u_16 */ 0x00, 0x02, - /* u_32 */ 0x00, 0x00, 0x00, 0x03, - /* u_64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - /* bool */ 0x00, + let payload = &[ + /* u_8 */ 0x01, + /* u_16 */ 0x00, 0x02, + /* u_32 */ 0x00, 0x00, 0x00, 0x03, + /* u_64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + /* bool */ 0x00, /* opt */ 0x01, 0x05, /* arr */ 0x61, 0x11, 0x62, 0x22, - ]; + ]; let struct_from_bytes = ::from_byte_reader(|bytes| { diff --git a/framework/scenario/tests/derive_managed_vec_item_struct_3.rs b/framework/scenario/tests/derive_managed_vec_item_struct_3.rs new file mode 100644 index 0000000000..a849617d60 --- /dev/null +++ b/framework/scenario/tests/derive_managed_vec_item_struct_3.rs @@ -0,0 +1,49 @@ +use multiversx_sc_scenario::api::StaticApi; + +multiversx_sc::derive_imports!(); +multiversx_sc::imports!(); + +// to test, run the following command in the crate folder: +// cargo expand --test derive_managed_vec_item_struct_2_test > expanded.rs + +/// Obtained from a contract from the community. +/// +/// Unusually large, payload size is 74. +#[derive(ManagedVecItem)] +pub struct Auction { + pub auctioned_token_type: TokenIdentifier, + pub auctioned_token_nonce: u64, + pub nr_auctioned_tokens: BigUint, + pub auction_type: AuctionType, + pub payment_token_type: EgldOrEsdtTokenIdentifier, + pub payment_token_nonce: u64, + pub min_bid: BigUint, + pub max_bid: Option>, + pub start_time: u64, + pub deadline: u64, + + pub original_owner: ManagedAddress, + pub current_bid: BigUint, + pub current_winner: ManagedAddress, + pub marketplace_cut_percentage: BigUint, + pub creator_royalties_percentage: BigUint, +} + +#[derive(ManagedVecItem)] +pub enum AuctionType { + None, + NftBid, + Nft, + SftAll, + SftOnePerPayment, +} + +#[test] +#[allow(clippy::assertions_on_constants)] +fn struct_3_static() { + assert_eq!( + as multiversx_sc::types::ManagedVecItem>::payload_size(), + 74 + ); + assert!(! as multiversx_sc::types::ManagedVecItem>::SKIPS_RESERIALIZATION); +} diff --git a/framework/scenario/tests/hex_call_data_arg_load.rs b/framework/scenario/tests/hex_call_data_arg_load.rs index ef5c60ffb1..0001ceb799 100644 --- a/framework/scenario/tests/hex_call_data_arg_load.rs +++ b/framework/scenario/tests/hex_call_data_arg_load.rs @@ -1,5 +1,3 @@ -#![feature(exhaustive_patterns)] - use multiversx_sc::{ codec::{ multi_types::{MultiValue2, MultiValueVec, OptionalValue}, @@ -9,15 +7,17 @@ use multiversx_sc::{ HexCallDataDeserializer, }; use multiversx_sc_scenario::api::StaticApi; +use unwrap_infallible::UnwrapInfallible; #[test] fn test_simple_args() { let input: &[u8] = b"func@1111@2222"; let mut de = HexCallDataDeserializer::new(input); - let Ok(arg1) = i32::multi_decode_or_handle_err(&mut de, PanicErrorHandler); + + let arg1 = i32::multi_decode_or_handle_err(&mut de, PanicErrorHandler).unwrap_infallible(); assert_eq!(arg1, 0x1111i32); - let Ok(arg2) = i32::multi_decode_or_handle_err(&mut de, PanicErrorHandler); + let arg2 = i32::multi_decode_or_handle_err(&mut de, PanicErrorHandler).unwrap_infallible(); assert_eq!(arg2, 0x2222i32); de.assert_no_more_args(PanicErrorHandler).unwrap(); @@ -27,7 +27,9 @@ fn test_simple_args() { fn test_simple_managed_arg() { let input: &[u8] = b"some_other_func@05"; let mut de = HexCallDataDeserializer::new(input); - let Ok(arg1) = BigUint::::multi_decode_or_handle_err(&mut de, PanicErrorHandler); + + let arg1 = BigUint::::multi_decode_or_handle_err(&mut de, PanicErrorHandler) + .unwrap_infallible(); assert_eq!(arg1, BigUint::from(5u32)); de.assert_no_more_args(PanicErrorHandler).unwrap(); @@ -37,7 +39,9 @@ fn test_simple_managed_arg() { fn test_simple_vec_arg() { let input: &[u8] = b"some_other_func@000000020000000300000006"; let mut de = HexCallDataDeserializer::new(input); - let Ok(arg1) = Vec::::multi_decode_or_handle_err(&mut de, PanicErrorHandler); + + let arg1 = + Vec::::multi_decode_or_handle_err(&mut de, PanicErrorHandler).unwrap_infallible(); assert_eq!(arg1, [2usize, 3usize, 6usize].to_vec()); de.assert_no_more_args(PanicErrorHandler).unwrap(); @@ -47,8 +51,11 @@ fn test_simple_vec_arg() { fn test_var_args() { let input: &[u8] = b"func@1111@2222"; let mut de = HexCallDataDeserializer::new(input); - let Ok(var_arg) = MultiValueVec::::multi_decode_or_handle_err(&mut de, PanicErrorHandler); + + let var_arg = MultiValueVec::::multi_decode_or_handle_err(&mut de, PanicErrorHandler) + .unwrap_infallible(); let arg_vec = var_arg.into_vec(); + assert_eq!(arg_vec.len(), 2); assert_eq!(arg_vec[0], 0x1111i32); assert_eq!(arg_vec[1], 0x2222i32); @@ -58,9 +65,11 @@ fn test_var_args() { fn test_multi_arg_2() { let input: &[u8] = b"func@1111@2222"; let mut de = HexCallDataDeserializer::new(input); - let Ok(tuple_arg) = - MultiValue2::::multi_decode_or_handle_err(&mut de, PanicErrorHandler); + + let tuple_arg = MultiValue2::::multi_decode_or_handle_err(&mut de, PanicErrorHandler) + .unwrap_infallible(); let tuple = tuple_arg.into_tuple(); + assert_eq!(tuple.0, 0x1111i32); assert_eq!(tuple.1, 0x2222i32); } @@ -69,14 +78,19 @@ fn test_multi_arg_2() { fn test_var_multi_arg_2() { let input: &[u8] = b"func@1111@2222"; let mut de = HexCallDataDeserializer::new(input); - let Ok(tuple_arg) = MultiValueVec::>::multi_decode_or_handle_err( + + let tuple_arg = MultiValueVec::>::multi_decode_or_handle_err( &mut de, PanicErrorHandler, - ); + ) + .unwrap_infallible(); let tuple_vec = tuple_arg.into_vec(); + assert_eq!(tuple_vec.len(), 1); + let mut iter = tuple_vec.into_iter(); let tuple = iter.next().unwrap().into_tuple(); + assert_eq!(tuple.0, 0x1111i32); assert_eq!(tuple.1, 0x2222i32); } @@ -85,10 +99,13 @@ fn test_var_multi_arg_2() { fn test_opt_multi_arg_2() { let input: &[u8] = b"func@1111@2222"; let mut de = HexCallDataDeserializer::new(input); - let Ok(opt_tuple_arg) = OptionalValue::>::multi_decode_or_handle_err( + + let opt_tuple_arg = OptionalValue::>::multi_decode_or_handle_err( &mut de, PanicErrorHandler, - ); + ) + .unwrap_infallible(); + match opt_tuple_arg { OptionalValue::Some(tuple_arg) => { let tuple = tuple_arg.into_tuple(); @@ -105,10 +122,13 @@ fn test_opt_multi_arg_2() { fn test_async_call_result_ok() { let input: &[u8] = b"func@@1111@2222"; let mut de = HexCallDataDeserializer::new(input); - let Ok(acr) = AsyncCallResult::>::multi_decode_or_handle_err( + + let acr = AsyncCallResult::>::multi_decode_or_handle_err( &mut de, PanicErrorHandler, - ); + ) + .unwrap_infallible(); + match acr { AsyncCallResult::Ok(tuple_arg) => { let tuple = tuple_arg.into_tuple(); @@ -125,11 +145,13 @@ fn test_async_call_result_ok() { fn test_async_call_result_ok2() { let input: &[u8] = b"func@00"; let mut de = HexCallDataDeserializer::new(input); - let Ok(acr) = - AsyncCallResult::>>::multi_decode_or_handle_err( - &mut de, - PanicErrorHandler, - ); + + let acr = AsyncCallResult::>>::multi_decode_or_handle_err( + &mut de, + PanicErrorHandler, + ) + .unwrap_infallible(); + match acr { AsyncCallResult::Ok(var_args) => { assert_eq!(var_args.len(), 0); @@ -144,10 +166,13 @@ fn test_async_call_result_ok2() { fn test_async_call_result_err() { let input: &[u8] = b"func@0123@1111"; let mut de = HexCallDataDeserializer::new(input); - let Ok(acr) = AsyncCallResult::>::multi_decode_or_handle_err( + + let acr = AsyncCallResult::>::multi_decode_or_handle_err( &mut de, PanicErrorHandler, - ); + ) + .unwrap_infallible(); + match acr { AsyncCallResult::Ok(_) => { panic!("AsyncCallResult::Err expected"); diff --git a/framework/scenario/tests/managed_decimal_test.rs b/framework/scenario/tests/managed_decimal_test.rs index 3b185a8a56..cbe701c9cf 100644 --- a/framework/scenario/tests/managed_decimal_test.rs +++ b/framework/scenario/tests/managed_decimal_test.rs @@ -1,6 +1,3 @@ -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] - use multiversx_sc::{ codec::test_util::{check_dep_encode_decode, check_top_encode_decode}, types::{BigFloat, BigUint, ConstDecimals, ManagedDecimal, NumDecimals}, diff --git a/framework/scenario/tests/scenarios_self_test.rs b/framework/scenario/tests/scenarios_self_test.rs index df3c6e310e..b6bf9c1883 100644 --- a/framework/scenario/tests/scenarios_self_test.rs +++ b/framework/scenario/tests/scenarios_self_test.rs @@ -1,11 +1,9 @@ use multiversx_sc_scenario::*; -// These tests don't really test any contract, but the testing framework itslef. +// These tests don't really test any contract, but the testing framework itself. fn world() -> ScenarioWorld { - let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("framework/scenario"); - blockchain + ScenarioWorld::new() } /// Checks that externalSteps work fine. diff --git a/framework/snippets/Cargo.toml b/framework/snippets/Cargo.toml index 3eb1a578df..4d4b3d4917 100644 --- a/framework/snippets/Cargo.toml +++ b/framework/snippets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-snippets" -version = "0.47.5" +version = "0.50.3" edition = "2021" authors = ["MultiversX "] @@ -16,15 +16,22 @@ categories = ["cryptography::cryptocurrencies"] [dependencies] tokio = { version = "1.24", features = ["full"] } hex = "0.4" -base64 = "0.21.5" +base64 = "0.22" log = "0.4.17" env_logger = "0.11" futures = "0.3" [dependencies.multiversx-sc-scenario] -version = "=0.47.5" +version = "=0.50.3" path = "../scenario" +[dependencies.multiversx-chain-scenario-format] +version = "0.22.2" +path = "../../sdk/scenario-format" + [dependencies.multiversx-sdk] -version = "=0.3.2" +version = "=0.4.1" path = "../../sdk/core" + +[dev-dependencies] +serde_json = "1.0" diff --git a/framework/snippets/src/account_tool.rs b/framework/snippets/src/account_tool.rs new file mode 100644 index 0000000000..b10baf4a80 --- /dev/null +++ b/framework/snippets/src/account_tool.rs @@ -0,0 +1,102 @@ +use multiversx_chain_scenario_format::interpret_trait::IntoRaw; +use multiversx_sc_scenario::{ + imports::Bech32Address, + scenario_model::{Account, BytesKey, BytesValue, Scenario, SetStateStep, Step}, +}; +use multiversx_sdk::{ + data::{address::Address, esdt::EsdtBalance}, + gateway::GatewayProxy, +}; +use std::collections::{BTreeMap, HashMap}; + +/// Called directly from CLI, from `sc-meta`. +/// +/// Retrieves an account data via the API, +/// then formats it as a scenario set state step. +pub async fn print_account_as_scenario_set_state( + api_string: String, + address_bech32_string: String, +) { + let api = GatewayProxy::new(api_string); + let address = Bech32Address::from_bech32_string(address_bech32_string); + let set_state = retrieve_account_as_scenario_set_state(&api, &address).await; + let scenario = build_scenario(set_state); + println!("{}", scenario.into_raw().to_json_string()); +} + +fn build_scenario(set_state: SetStateStep) -> Scenario { + Scenario { + name: None, + comment: None, + check_gas: None, + steps: vec![Step::SetState(set_state)], + } +} + +pub async fn retrieve_account_as_scenario_set_state( + api: &GatewayProxy, + address: &Bech32Address, +) -> SetStateStep { + let sdk_address = Address::from_bech32_string(address.to_bech32_str()).unwrap(); + let sdk_account = api.get_account(&sdk_address).await.unwrap(); + + let account_esdt = api + .get_account_esdt_tokens(&sdk_address) + .await + .unwrap_or_else(|err| { + panic!("failed to retrieve ESDT tokens for address {address}: {err}") + }); + let account_esdt_roles = api + .get_account_esdt_roles(&sdk_address) + .await + .unwrap_or_else(|err| panic!("failed to retrieve ESDT roles for address {address}: {err}")); + let account_storage = api + .get_account_storage_keys(&sdk_address) + .await + .unwrap_or_else(|err| panic!("failed to retrieve storage for address {address}: {err}")); + + let account_state = set_account( + sdk_account, + account_storage, + account_esdt, + account_esdt_roles, + ); + + let set_state_step = SetStateStep::new(); + set_state_step.put_account(address, account_state) +} + +fn set_account( + account: multiversx_sdk::data::account::Account, + account_storage: HashMap, + account_esdt: HashMap, + account_esdt_roles: HashMap>, +) -> Account { + let mut account_state = Account::new() + .nonce(account.nonce) + .balance(account.balance.as_str()) + .code(account.code); + account_state.username = Some(format!("str:{}", account.username.as_str()).into()); + account_state.storage = convert_storage(account_storage); + + for (_, esdt_balance) in account_esdt.iter() { + let token_id_expr = format!("str:{}", esdt_balance.token_identifier); + account_state = + account_state.esdt_balance(token_id_expr.as_str(), esdt_balance.balance.as_str()); + } + + for (token_id, esdt_roles) in account_esdt_roles { + let token_id_expr = format!("str:{token_id}"); + account_state = account_state.esdt_roles(token_id_expr.as_str(), esdt_roles); + } + + account_state +} + +fn convert_storage(account_storage: HashMap) -> BTreeMap { + account_storage + .into_iter() + .filter(|(k, _)| !k.starts_with("454c524f4e44")) + .map(|(k, v)| (BytesKey::from(k.as_str()), BytesValue::from(v))) + .collect() +} diff --git a/framework/snippets/src/imports.rs b/framework/snippets/src/imports.rs new file mode 100644 index 0000000000..f2b0e6a5f9 --- /dev/null +++ b/framework/snippets/src/imports.rs @@ -0,0 +1,8 @@ +pub use crate::multiversx_sc_scenario::imports::*; + +pub use crate::{ + dns_address_for_name, test_wallets, Interactor, InteractorPrepareAsync, StepBuffer, +}; + +pub use env_logger; +pub use tokio; diff --git a/framework/snippets/src/interactor.rs b/framework/snippets/src/interactor.rs index 7034932d91..bb38873afe 100644 --- a/framework/snippets/src/interactor.rs +++ b/framework/snippets/src/interactor.rs @@ -1,32 +1,39 @@ use multiversx_sc_scenario::{ + imports::{Bech32Address, ScenarioRunner}, mandos_system::{run_list::ScenarioRunnerList, run_trace::ScenarioTraceFile}, multiversx_sc::types::Address, scenario_model::AddressValue, }; use multiversx_sdk::{ - blockchain::CommunicationProxy, data::{address::Address as ErdrsAddress, network_config::NetworkConfig}, + gateway::GatewayProxy, wallet::Wallet, }; -use std::{collections::HashMap, path::Path, time::Duration}; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, + time::Duration, +}; -use crate::Sender; +use crate::{account_tool::retrieve_account_as_scenario_set_state, Sender}; pub const INTERACTOR_SCENARIO_TRACE_PATH: &str = "interactor_trace.scen.json"; pub struct Interactor { - pub proxy: CommunicationProxy, + pub proxy: GatewayProxy, pub network_config: NetworkConfig, pub sender_map: HashMap, pub(crate) waiting_time_ms: u64, pub pre_runners: ScenarioRunnerList, pub post_runners: ScenarioRunnerList, + + pub current_dir: PathBuf, } impl Interactor { pub async fn new(gateway_url: &str) -> Self { - let proxy = CommunicationProxy::new(gateway_url.to_string()); + let proxy = GatewayProxy::new(gateway_url.to_string()); let network_config = proxy.get_network_config().await.unwrap(); Self { proxy, @@ -35,6 +42,7 @@ impl Interactor { waiting_time_ms: 0, pre_runners: ScenarioRunnerList::empty(), post_runners: ScenarioRunnerList::empty(), + current_dir: PathBuf::default(), } } @@ -60,6 +68,12 @@ impl Interactor { self.post_runners.push(ScenarioTraceFile::new(path)); self } + + pub async fn retrieve_account(&mut self, wallet_address: &Bech32Address) { + let set_state = retrieve_account_as_scenario_set_state(&self.proxy, wallet_address).await; + self.pre_runners.run_set_state_step(&set_state); + self.post_runners.run_set_state_step(&set_state); + } } pub(crate) fn mandos_to_erdrs_address(mandos_address: &AddressValue) -> ErdrsAddress { diff --git a/framework/snippets/src/interactor_retrieve.rs b/framework/snippets/src/interactor_retrieve.rs deleted file mode 100644 index c19392095a..0000000000 --- a/framework/snippets/src/interactor_retrieve.rs +++ /dev/null @@ -1,64 +0,0 @@ -use crate::Interactor; -use log::info; -use multiversx_sdk::data::transaction::TransactionOnNetwork; -use std::time::Duration; - -const TX_GET_RESULTS_NUM_RETRIES: usize = 8; -const EXTRA_WAITING_TIME_MS: Duration = Duration::from_millis(8000); -const WAITING_TIME_MS: Duration = Duration::from_secs(25); -const WAIT: u64 = 1000; - -impl Interactor { - /// Retrieves a transaction from the network. - pub(crate) async fn retrieve_tx_on_network(&self, tx_hash: String) -> TransactionOnNetwork { - let mut waiting_time_ms = 0; - let mut break_outer = false; - sleep(&mut waiting_time_ms, WAITING_TIME_MS).await; - - let tx = 'outer: loop { - let mut retries = TX_GET_RESULTS_NUM_RETRIES; - let mut wait = WAIT; - loop { - let tx_info_result = self.proxy.get_transaction_info_with_results(&tx_hash).await; - match tx_info_result { - Ok(tx) => { - if break_outer { - break 'outer tx; - } - - // reset waiting time - waiting_time_ms = WAITING_TIME_MS.as_millis() as u64; - - tokio::time::sleep(EXTRA_WAITING_TIME_MS).await; - break_outer = true; - - break; - }, - Err(err) => { - assert!( - retries > 0, - "still no answer after {TX_GET_RESULTS_NUM_RETRIES} retries" - ); - - info!( - "tx result fetch error after {} ms: {}", - self.waiting_time_ms, err - ); - retries -= 1; - sleep(&mut waiting_time_ms, Duration::from_millis(wait)).await; - wait *= 2; - }, - } - } - }; - - info!("tx with results: {:#?}", tx); - tx - } -} - -/// Sleeps for the given duration and adds the duration to the waiting time. -pub async fn sleep(waiting_time_ms: &mut u64, duration: Duration) { - *waiting_time_ms += duration.as_millis() as u64; - tokio::time::sleep(duration).await; -} diff --git a/framework/snippets/src/interactor_scenario.rs b/framework/snippets/src/interactor_scenario.rs new file mode 100644 index 0000000000..8449bf9edc --- /dev/null +++ b/framework/snippets/src/interactor_scenario.rs @@ -0,0 +1,5 @@ +mod interactor_sc_call; +mod interactor_sc_deploy; +mod interactor_sc_extra; +mod interactor_transfer; +mod interactor_vm_query; diff --git a/framework/snippets/src/interactor_sc_call.rs b/framework/snippets/src/interactor_scenario/interactor_sc_call.rs similarity index 85% rename from framework/snippets/src/interactor_sc_call.rs rename to framework/snippets/src/interactor_scenario/interactor_sc_call.rs index a0e0498ae9..6802304ae9 100644 --- a/framework/snippets/src/interactor_sc_call.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_call.rs @@ -1,10 +1,9 @@ -use crate::{address_h256_to_erdrs, mandos_to_erdrs_address, Interactor}; +use crate::{address_h256_to_erdrs, mandos_to_erdrs_address, network_response, Interactor}; use log::info; use multiversx_sc_scenario::{ api::StaticApi, - multiversx_sc::types::ContractCallWithEgld, scenario::ScenarioRunner, - scenario_model::{ScCallStep, SetStateStep, TxCall, TxResponse}, + scenario_model::{ScCallStep, SetStateStep, TxCall}, }; use multiversx_sdk::{data::transaction::Transaction, utils::base64_encode}; @@ -15,9 +14,9 @@ impl Interactor { { let sc_call_step = sc_call_step.as_mut(); let tx_hash = self.launch_sc_call(sc_call_step).await; - let tx = self.retrieve_tx_on_network(tx_hash.clone()).await; + let tx = self.proxy.retrieve_tx_on_network(tx_hash.clone()).await; - sc_call_step.save_response(TxResponse::from_network_tx(tx)); + sc_call_step.save_response(network_response::parse_tx_response(tx)); if let Some(token_identifier) = sc_call_step.response().new_issued_token_identifier.clone() { @@ -45,6 +44,7 @@ impl Interactor { tx_hash } + #[allow(deprecated)] // TODO pub(crate) fn tx_call_to_blockchain_tx(&self, tx_call: &TxCall) -> Transaction { let contract_call = tx_call.to_contract_call(); let contract_call_tx_data = contract_call_to_tx_data(&contract_call); @@ -70,7 +70,10 @@ impl Interactor { } } -fn contract_call_to_tx_data(contract_call: &ContractCallWithEgld) -> String { +#[allow(deprecated)] // TODO +fn contract_call_to_tx_data( + contract_call: &multiversx_sc_scenario::imports::ContractCallWithEgld, +) -> String { let mut result = String::from_utf8( contract_call .basic diff --git a/framework/snippets/src/interactor_sc_deploy.rs b/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs similarity index 81% rename from framework/snippets/src/interactor_sc_deploy.rs rename to framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs index 63e8ae80db..59de249e83 100644 --- a/framework/snippets/src/interactor_sc_deploy.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs @@ -1,9 +1,9 @@ -use crate::{mandos_to_erdrs_address, Interactor}; +use crate::{mandos_to_erdrs_address, network_response, Interactor}; use log::info; use multiversx_sc_scenario::{ - bech32, + imports::Bech32Address, mandos_system::ScenarioRunner, - scenario_model::{ScDeployStep, SetStateStep, TxResponse}, + scenario_model::{ScDeployStep, SetStateStep}, }; use multiversx_sdk::{ data::{address::Address as ErdrsAddress, transaction::Transaction}, @@ -53,25 +53,22 @@ impl Interactor { { let sc_deploy_step = sc_deploy_step.as_mut(); let tx_hash = self.launch_sc_deploy(sc_deploy_step).await; - let tx = self.retrieve_tx_on_network(tx_hash.clone()).await; + let tx = self.proxy.retrieve_tx_on_network(tx_hash.clone()).await; let addr = sc_deploy_step.tx.from.clone(); let nonce = tx.nonce; - sc_deploy_step.save_response(TxResponse::from_network_tx(tx)); + sc_deploy_step.save_response(network_response::parse_tx_response(tx)); let deploy_address = sc_deploy_step .response() .new_deployed_address .clone() .unwrap(); + let deploy_address_bech32 = Bech32Address::from(deploy_address); - let set_state_step = SetStateStep::new().new_address( - addr, - nonce, - format!("0x{}", hex::encode(&deploy_address)).as_str(), - ); + let set_state_step = SetStateStep::new().new_address(addr, nonce, &deploy_address_bech32); - println!("deploy address: {}", bech32::encode(&deploy_address)); + println!("deploy address: {deploy_address_bech32}"); self.pre_runners.run_set_state_step(&set_state_step); self.post_runners.run_set_state_step(&set_state_step); diff --git a/framework/snippets/src/interactor_sc_extra.rs b/framework/snippets/src/interactor_scenario/interactor_sc_extra.rs similarity index 71% rename from framework/snippets/src/interactor_sc_extra.rs rename to framework/snippets/src/interactor_scenario/interactor_sc_extra.rs index 177b38d4e1..44e5efa744 100644 --- a/framework/snippets/src/interactor_sc_extra.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_extra.rs @@ -1,9 +1,12 @@ +#![allow(deprecated)] + use crate::Interactor; use multiversx_sc_scenario::{ api::StaticApi, multiversx_sc::{ - codec::{CodecFrom, TopEncodeMulti}, - types::{Address, ContractCall}, + abi::TypeAbiFrom, + codec::{TopDecodeMulti, TopEncodeMulti}, + types::{Address, ContractCallBase}, }, scenario_model::{ ScCallStep, ScDeployStep, ScQueryStep, TxResponse, TypedResponse, TypedScCall, @@ -12,6 +15,10 @@ use multiversx_sc_scenario::{ }; impl Interactor { + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn sc_call_use_raw_response( &mut self, mut step: S, @@ -27,6 +34,10 @@ impl Interactor { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn sc_call_use_result( &mut self, step: TypedScCall, @@ -34,26 +45,34 @@ impl Interactor { ) -> &mut Self where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, F: FnOnce(TypedResponse), { use_result(self.sc_call_get_result(step).await); self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn sc_call_get_result( &mut self, mut step: TypedScCall, ) -> TypedResponse where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.sc_call(step.as_mut()).await; let response = unwrap_response(&step.as_mut().response); TypedResponse::from_raw(response) } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn sc_query_use_raw_response( &mut self, mut step: S, @@ -69,6 +88,10 @@ impl Interactor { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn sc_query_use_result( &mut self, step: TypedScQuery, @@ -76,30 +99,38 @@ impl Interactor { ) -> &mut Self where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, F: FnOnce(TypedResponse), { use_result(self.sc_query_get_result(step).await); self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn sc_query_get_result( &mut self, mut step: TypedScQuery, ) -> TypedResponse where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.sc_query(step.as_mut()).await; let response = unwrap_response(&step.sc_query_step.response); TypedResponse::from_raw(response) } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn quick_query(&mut self, contract_call: CC) -> RequestedResult where - CC: ContractCall, - RequestedResult: CodecFrom, + CC: ContractCallBase, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { let mut typed_sc_query = ScQueryStep::new().call(contract_call); self.sc_query(&mut typed_sc_query).await; @@ -108,6 +139,10 @@ impl Interactor { typed_response.result.unwrap() } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn sc_deploy_use_raw_response( &mut self, mut step: S, @@ -123,6 +158,10 @@ impl Interactor { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn sc_deploy_use_result( &mut self, step: TypedScDeploy, @@ -130,7 +169,7 @@ impl Interactor { ) -> &mut Self where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, F: FnOnce(Address, TypedResponse), { let (new_address, response) = self.sc_deploy_get_result(step).await; @@ -138,13 +177,17 @@ impl Interactor { self } + #[deprecated( + since = "0.49.0", + note = "Please use the unified transaction syntax instead." + )] pub async fn sc_deploy_get_result( &mut self, mut step: TypedScDeploy, ) -> (Address, TypedResponse) where OriginalResult: TopEncodeMulti, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.sc_deploy(step.as_mut()).await; let response = unwrap_response(&step.sc_deploy_step.response); diff --git a/framework/snippets/src/interactor_sc_transfer.rs b/framework/snippets/src/interactor_scenario/interactor_transfer.rs similarity index 92% rename from framework/snippets/src/interactor_sc_transfer.rs rename to framework/snippets/src/interactor_scenario/interactor_transfer.rs index 2e99372b0f..6557e4119f 100644 --- a/framework/snippets/src/interactor_sc_transfer.rs +++ b/framework/snippets/src/interactor_scenario/interactor_transfer.rs @@ -14,7 +14,7 @@ impl Interactor { println!("transfer tx hash: {tx_hash}"); info!("transfer tx hash: {}", tx_hash); - self.retrieve_tx_on_network(tx_hash.clone()).await; + self.proxy.retrieve_tx_on_network(tx_hash.clone()).await; self.post_runners.run_transfer_step(&transfer_step); diff --git a/framework/snippets/src/interactor_vm_query.rs b/framework/snippets/src/interactor_scenario/interactor_vm_query.rs similarity index 90% rename from framework/snippets/src/interactor_vm_query.rs rename to framework/snippets/src/interactor_scenario/interactor_vm_query.rs index d6a92aa450..aa9f87efb7 100644 --- a/framework/snippets/src/interactor_vm_query.rs +++ b/framework/snippets/src/interactor_scenario/interactor_vm_query.rs @@ -1,9 +1,11 @@ +#![allow(deprecated)] + use crate::{address_h256_to_erdrs, Interactor}; use log::info; use multiversx_sc_scenario::{ api::StaticApi, mandos_system::ScenarioRunner, - multiversx_sc::{codec::CodecFrom, types::ContractCall}, + multiversx_sc::{abi::TypeAbiFrom, codec::TopDecodeMulti, types::ContractCall}, scenario_model::{ScQueryStep, TxResponse}, }; use multiversx_sdk::{data::vm::VmValueRequest, utils::base64_decode}; @@ -51,7 +53,7 @@ impl Interactor { pub async fn vm_query(&mut self, contract_call: CC) -> RequestedResult where CC: ContractCall, - RequestedResult: CodecFrom, + RequestedResult: TopDecodeMulti + TypeAbiFrom, { self.quick_query(contract_call).await } diff --git a/framework/snippets/src/interactor_tx.rs b/framework/snippets/src/interactor_tx.rs new file mode 100644 index 0000000000..df84381dd8 --- /dev/null +++ b/framework/snippets/src/interactor_tx.rs @@ -0,0 +1,23 @@ +#![allow(unused_imports)] // TEMP + +mod interactor_exec_call; +mod interactor_exec_deploy; +mod interactor_exec_env; +mod interactor_exec_step; +mod interactor_exec_transf; +mod interactor_prepare_async; +mod interactor_query_call; +mod interactor_query_env; +mod interactor_query_step; + +pub use interactor_exec_env::InteractorEnvExec; +pub use interactor_exec_step::InteractorExecStep; +pub use interactor_prepare_async::InteractorPrepareAsync; +pub use interactor_query_env::InteractorEnvQuery; +pub use interactor_query_step::InteractorQueryStep; + +#[deprecated(since = "0.50.2", note = "Renamed to InteractorExecEnv")] +pub type InteractorExecEnv<'a> = InteractorEnvExec<'a>; + +#[deprecated(since = "0.50.2", note = "Renamed to InteractorEnvQuery")] +pub type InteractorQueryEnv<'a> = InteractorEnvQuery<'a>; diff --git a/framework/snippets/src/interactor_tx/interactor_exec_call.rs b/framework/snippets/src/interactor_tx/interactor_exec_call.rs new file mode 100644 index 0000000000..261ce44989 --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_exec_call.rs @@ -0,0 +1,76 @@ +use multiversx_sc_scenario::{ + api::StaticApi, + multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{ + FunctionCall, RHListExec, Tx, TxBaseWithEnv, TxFromSpecified, TxGas, TxPayment, + TxToSpecified, + }, + }, + scenario::tx_to_step::TxToStep, + scenario_model::{ScCallStep, TxResponse}, + ScenarioTxEnvData, +}; + +use crate::Interactor; + +use super::{InteractorEnvExec, InteractorExecStep, InteractorPrepareAsync}; + +impl<'w, From, To, Payment, Gas, RH> InteractorPrepareAsync + for Tx, From, To, Payment, Gas, FunctionCall, RH> +where + From: TxFromSpecified>, + To: TxToSpecified>, + Payment: TxPayment>, + Gas: TxGas>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Exec = InteractorExecStep<'w, ScCallStep, RH>; + + fn prepare_async(self) -> Self::Exec { + InteractorExecStep { + step_wrapper: self.tx_to_step(), + } + } +} + +impl<'w, RH> InteractorExecStep<'w, ScCallStep, RH> +where + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + pub async fn run(mut self) -> ::Unpacked { + self.step_wrapper + .env + .world + .sc_call(&mut self.step_wrapper.step) + .await; + self.step_wrapper.process_result() + } +} + +impl Interactor { + pub async fn chain_call(&mut self, f: F) -> &mut Self + where + From: TxFromSpecified, + To: TxToSpecified, + Payment: TxPayment, + Gas: TxGas, + RH: RHListExec, + F: FnOnce( + TxBaseWithEnv, + ) + -> Tx, RH>, + { + let env = self.new_env_data(); + let tx_base = TxBaseWithEnv::new_with_env(env); + let tx = f(tx_base); + + let mut step_wrapper = tx.tx_to_step(); + self.sc_call(&mut step_wrapper.step).await; + step_wrapper.process_result(); + + self + } +} diff --git a/framework/snippets/src/interactor_tx/interactor_exec_deploy.rs b/framework/snippets/src/interactor_tx/interactor_exec_deploy.rs new file mode 100644 index 0000000000..6070158258 --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_exec_deploy.rs @@ -0,0 +1,122 @@ +use multiversx_sc_scenario::{ + multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{ + Code, DeployCall, RHListExec, Tx, TxBaseWithEnv, TxCodeValue, TxFromSpecified, TxGas, + TxPayment, + }, + }, + scenario::tx_to_step::TxToStep, + scenario_model::{ScDeployStep, TxResponse}, + ScenarioTxEnvData, +}; + +use crate::Interactor; + +use super::{InteractorEnvExec, InteractorExecStep, InteractorPrepareAsync}; + +impl<'w, From, Payment, Gas, CodeValue, RH> InteractorPrepareAsync + for Tx< + InteractorEnvExec<'w>, + From, + (), + Payment, + Gas, + DeployCall, Code>, + RH, + > +where + From: TxFromSpecified>, + Payment: TxPayment>, + Gas: TxGas>, + CodeValue: TxCodeValue>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Exec = InteractorExecStep<'w, ScDeployStep, RH>; + + fn prepare_async(self) -> Self::Exec { + InteractorExecStep { + step_wrapper: self.tx_to_step(), + } + } +} + +impl<'w, RH> InteractorExecStep<'w, ScDeployStep, RH> +where + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + pub async fn run(mut self) -> ::Unpacked { + self.step_wrapper + .env + .world + .sc_deploy(&mut self.step_wrapper.step) + .await; + self.step_wrapper.process_result() + } +} + +impl Interactor { + pub async fn chain_deploy(&mut self, f: F) -> &mut Self + where + From: TxFromSpecified, + Payment: TxPayment, + Gas: TxGas, + CodeValue: TxCodeValue, + RH: RHListExec, + F: FnOnce( + TxBaseWithEnv, + ) -> Tx< + ScenarioTxEnvData, + From, + (), + Payment, + Gas, + DeployCall>, + RH, + >, + { + let env = self.new_env_data(); + let tx_base = TxBaseWithEnv::new_with_env(env); + let tx = f(tx_base); + + let mut step_wrapper = tx.tx_to_step(); + self.sc_deploy(&mut step_wrapper.step).await; + step_wrapper.process_result(); + + self + } + + pub async fn run_deploy( + &mut self, + f: F, + ) -> ::Unpacked + where + From: TxFromSpecified, + Payment: TxPayment, + Gas: TxGas, + CodeValue: TxCodeValue, + RH: RHListExec, + RH::ListReturns: NestedTupleFlatten, + F: FnOnce( + TxBaseWithEnv, + ) -> Tx< + ScenarioTxEnvData, + From, + (), + Payment, + Gas, + DeployCall>, + RH, + >, + { + let env = self.new_env_data(); + let tx_base = TxBaseWithEnv::new_with_env(env); + let tx = f(tx_base); + + let mut step_wrapper = tx.tx_to_step(); + self.sc_deploy(&mut step_wrapper.step).await; + step_wrapper.process_result() + } +} diff --git a/framework/snippets/src/interactor_tx/interactor_exec_env.rs b/framework/snippets/src/interactor_tx/interactor_exec_env.rs new file mode 100644 index 0000000000..6473c50a91 --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_exec_env.rs @@ -0,0 +1,46 @@ +use multiversx_sc_scenario::{ + api::StaticApi, + multiversx_sc::types::{ManagedAddress, ManagedBuffer, Tx, TxBaseWithEnv, TxEnv}, + scenario_model::TxExpect, + ScenarioTxEnv, ScenarioTxEnvData, +}; + +use crate::Interactor; + +impl Interactor { + pub fn tx(&mut self) -> TxBaseWithEnv> { + let data = self.new_env_data(); + let env = InteractorEnvExec { world: self, data }; + Tx::new_with_env(env) + } +} + +/// Environment for executing transactions. +pub struct InteractorEnvExec<'w> { + pub world: &'w mut Interactor, + pub data: ScenarioTxEnvData, +} + +impl<'w> TxEnv for InteractorEnvExec<'w> { + type Api = StaticApi; + + type RHExpect = TxExpect; + + fn resolve_sender_address(&self) -> ManagedAddress { + panic!("Explicit sender address expected") + } + + fn default_gas_annotation(&self) -> ManagedBuffer { + self.data.default_gas_annotation() + } + + fn default_gas_value(&self) -> u64 { + self.data.default_gas_value() + } +} + +impl<'w> ScenarioTxEnv for InteractorEnvExec<'w> { + fn env_data(&self) -> &ScenarioTxEnvData { + &self.data + } +} diff --git a/framework/snippets/src/interactor_tx/interactor_exec_step.rs b/framework/snippets/src/interactor_tx/interactor_exec_step.rs new file mode 100644 index 0000000000..1d4eabf54d --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_exec_step.rs @@ -0,0 +1,15 @@ +use multiversx_sc_scenario::{ + multiversx_sc::{tuple_util::NestedTupleFlatten, types::RHListExec}, + scenario::tx_to_step::StepWrapper, + scenario_model::TxResponse, +}; + +use super::InteractorEnvExec; + +pub struct InteractorExecStep<'w, Step, RH> +where + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + pub(crate) step_wrapper: StepWrapper, Step, RH>, +} diff --git a/framework/snippets/src/interactor_tx/interactor_exec_transf.rs b/framework/snippets/src/interactor_tx/interactor_exec_transf.rs new file mode 100644 index 0000000000..3ec04c0b05 --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_exec_transf.rs @@ -0,0 +1,34 @@ +use multiversx_sc_scenario::{ + multiversx_sc::types::{Tx, TxFromSpecified, TxGas, TxPayment, TxToSpecified}, + scenario::tx_to_step::TxToStep, + scenario_model::TransferStep, +}; + +use super::{InteractorEnvExec, InteractorExecStep, InteractorPrepareAsync}; + +impl<'w, From, To, Payment, Gas> InteractorPrepareAsync + for Tx, From, To, Payment, Gas, (), ()> +where + From: TxFromSpecified>, + To: TxToSpecified>, + Payment: TxPayment>, + Gas: TxGas>, +{ + type Exec = InteractorExecStep<'w, TransferStep, ()>; + + fn prepare_async(self) -> Self::Exec { + InteractorExecStep { + step_wrapper: self.tx_to_step(), + } + } +} + +impl<'w> InteractorExecStep<'w, TransferStep, ()> { + pub async fn run(self) { + self.step_wrapper + .env + .world + .transfer(self.step_wrapper.step) + .await; + } +} diff --git a/framework/snippets/src/interactor_tx/interactor_prepare_async.rs b/framework/snippets/src/interactor_tx/interactor_prepare_async.rs new file mode 100644 index 0000000000..43ca7c403c --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_prepare_async.rs @@ -0,0 +1,18 @@ +use multiversx_sc_scenario::ScenarioTxEnvData; + +use crate::Interactor; + +impl Interactor { + pub(crate) fn new_env_data(&self) -> ScenarioTxEnvData { + ScenarioTxEnvData { + context_path: self.current_dir.clone(), + tx_hash: None, + } + } +} + +pub trait InteractorPrepareAsync { + type Exec; + + fn prepare_async(self) -> Self::Exec; +} diff --git a/framework/snippets/src/interactor_tx/interactor_query_call.rs b/framework/snippets/src/interactor_tx/interactor_query_call.rs new file mode 100644 index 0000000000..5e35b5409b --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_query_call.rs @@ -0,0 +1,68 @@ +use multiversx_sc_scenario::{ + api::StaticApi, + multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{FunctionCall, RHListExec, Tx, TxBaseWithEnv, TxNoPayment, TxToSpecified}, + }, + scenario::tx_to_step::TxToQueryStep, + scenario_model::TxResponse, + ScenarioTxEnvData, +}; + +use crate::Interactor; + +use super::{InteractorEnvQuery, InteractorPrepareAsync, InteractorQueryStep}; + +impl<'w, To, Payment, RH> InteractorPrepareAsync + for Tx, (), To, Payment, (), FunctionCall, RH> +where + To: TxToSpecified>, + Payment: TxNoPayment>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Exec = InteractorQueryStep<'w, RH>; + + fn prepare_async(self) -> Self::Exec { + InteractorQueryStep { + step_wrapper: self.tx_to_query_step(), + } + } +} + +impl<'w, RH> InteractorQueryStep<'w, RH> +where + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + pub async fn run(mut self) -> ::Unpacked { + self.step_wrapper + .env + .world + .sc_query(&mut self.step_wrapper.step) + .await; + self.step_wrapper.process_result() + } +} + +impl Interactor { + pub async fn chain_query(&mut self, f: F) -> &mut Self + where + To: TxToSpecified, + Payment: TxNoPayment, + RH: RHListExec, + F: FnOnce( + TxBaseWithEnv, + ) + -> Tx, RH>, + { + let env = self.new_env_data(); + let tx_base = TxBaseWithEnv::new_with_env(env); + let tx = f(tx_base); + + let mut step_wrapper = tx.tx_to_query_step(); + self.sc_query(&mut step_wrapper.step).await; + step_wrapper.process_result(); + self + } +} diff --git a/framework/snippets/src/interactor_tx/interactor_query_env.rs b/framework/snippets/src/interactor_tx/interactor_query_env.rs new file mode 100644 index 0000000000..71dcd2f3b4 --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_query_env.rs @@ -0,0 +1,45 @@ +use multiversx_sc_scenario::{ + api::StaticApi, + multiversx_sc::types::{ManagedAddress, ManagedBuffer, Tx, TxBaseWithEnv, TxEnv}, + scenario_model::TxExpect, + ScenarioTxEnv, ScenarioTxEnvData, +}; + +use crate::Interactor; + +impl Interactor { + pub fn query(&mut self) -> TxBaseWithEnv> { + let data = self.new_env_data(); + let env = InteractorEnvQuery { world: self, data }; + Tx::new_with_env(env) + } +} + +pub struct InteractorEnvQuery<'w> { + pub world: &'w mut Interactor, + pub data: ScenarioTxEnvData, +} + +impl<'w> TxEnv for InteractorEnvQuery<'w> { + type Api = StaticApi; + + type RHExpect = TxExpect; + + fn resolve_sender_address(&self) -> ManagedAddress { + panic!("Explicit sender address expected") + } + + fn default_gas_annotation(&self) -> ManagedBuffer { + self.data.default_gas_annotation() + } + + fn default_gas_value(&self) -> u64 { + self.data.default_gas_value() + } +} + +impl<'w> ScenarioTxEnv for InteractorEnvQuery<'w> { + fn env_data(&self) -> &ScenarioTxEnvData { + &self.data + } +} diff --git a/framework/snippets/src/interactor_tx/interactor_query_step.rs b/framework/snippets/src/interactor_tx/interactor_query_step.rs new file mode 100644 index 0000000000..bbb7a0996b --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_query_step.rs @@ -0,0 +1,15 @@ +use multiversx_sc_scenario::{ + multiversx_sc::{tuple_util::NestedTupleFlatten, types::RHListExec}, + scenario::tx_to_step::StepWrapper, + scenario_model::{ScQueryStep, TxResponse}, +}; + +use super::InteractorEnvQuery; + +pub struct InteractorQueryStep<'w, RH> +where + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + pub(crate) step_wrapper: StepWrapper, ScQueryStep, RH>, +} diff --git a/framework/snippets/src/lib.rs b/framework/snippets/src/lib.rs index 2081c11a58..7d3b52c696 100644 --- a/framework/snippets/src/lib.rs +++ b/framework/snippets/src/lib.rs @@ -1,26 +1,25 @@ +pub mod account_tool; mod interactor; mod interactor_dns; -mod interactor_multi_sc_exec; -mod interactor_multi_sc_process; -mod interactor_retrieve; -mod interactor_sc_call; -mod interactor_sc_deploy; -mod interactor_sc_extra; -mod interactor_sc_transfer; +mod interactor_scenario; mod interactor_sender; -mod interactor_tx_spec; -mod interactor_vm_query; -mod step_buffer; +mod interactor_tx; +mod multi; +pub mod network_response; +pub mod test_wallets; pub use env_logger; pub use hex; pub use interactor::*; pub use interactor_dns::*; pub use interactor_sender::*; -pub use interactor_tx_spec::*; +pub use interactor_tx::*; pub use log; +pub use multi::*; pub use multiversx_sc_scenario::{self, multiversx_sc}; pub use multiversx_sdk as erdrs; // TODO: remove pub use multiversx_sdk as sdk; -pub use step_buffer::*; pub use tokio; + +/// Imports normally needed in interactors, grouped together. +pub mod imports; diff --git a/framework/snippets/src/multi.rs b/framework/snippets/src/multi.rs new file mode 100644 index 0000000000..973b159858 --- /dev/null +++ b/framework/snippets/src/multi.rs @@ -0,0 +1,9 @@ +mod homogenous_tx_buffer; +mod interactor_multi_sc_exec; +mod interactor_multi_sc_process; +mod interactor_step; +mod step_buffer; + +pub use homogenous_tx_buffer::HomogenousTxBuffer; +pub use interactor_step::InteractorStep; +pub use step_buffer::StepBuffer; diff --git a/framework/snippets/src/multi/homogenous_tx_buffer.rs b/framework/snippets/src/multi/homogenous_tx_buffer.rs new file mode 100644 index 0000000000..66f5dec79f --- /dev/null +++ b/framework/snippets/src/multi/homogenous_tx_buffer.rs @@ -0,0 +1,65 @@ +use multiversx_sc_scenario::{ + multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{RHListExec, TxBaseWithEnv}, + }, + scenario::tx_to_step::{StepWithResponse, StepWrapper, TxToStep}, + scenario_model::TxResponse, + ScenarioTxEnvData, +}; + +use crate::{Interactor, InteractorEnvExec, InteractorStep, StepBuffer}; + +pub struct HomogenousTxBuffer<'w, Step, RH> { + env: InteractorEnvExec<'w>, + steps: Vec>, +} + +impl Interactor { + /// Creates a buffer that can hold multiple transactions, and then execute them all at once. + /// + /// This buffer holds transactions of the same type (call/deploy) and with identical result handler types. + /// Therefore, after execution, all results will have the same type. + pub fn homogenous_call_buffer(&mut self) -> HomogenousTxBuffer<'_, Step, RH> { + let data = self.new_env_data(); + let env = InteractorEnvExec { world: self, data }; + HomogenousTxBuffer { + env, + steps: Vec::new(), + } + } +} + +impl<'w, Step, RH> HomogenousTxBuffer<'w, Step, RH> +where + Step: InteractorStep + StepWithResponse, + RH: RHListExec, + RH::ListReturns: NestedTupleFlatten, +{ + pub fn push_tx(&mut self, f: F) -> &mut Self + where + Tx: TxToStep, + F: FnOnce(TxBaseWithEnv) -> Tx, + { + let env = self.env.world.new_env_data(); + let tx_base = TxBaseWithEnv::new_with_env(env); + let tx = f(tx_base); + + self.steps.push(tx.tx_to_step()); + + self + } + + pub async fn run(mut self) -> Vec<::Unpacked> { + let mut step_buffer = StepBuffer::default(); + for step in &mut self.steps { + step_buffer.refs.push(&mut step.step); + } + self.env.world.multi_sc_exec(step_buffer).await; + + self.steps + .into_iter() + .map(|step| step.process_result()) + .collect() + } +} diff --git a/framework/snippets/src/interactor_multi_sc_exec.rs b/framework/snippets/src/multi/interactor_multi_sc_exec.rs similarity index 72% rename from framework/snippets/src/interactor_multi_sc_exec.rs rename to framework/snippets/src/multi/interactor_multi_sc_exec.rs index b8035fbae6..8ac6a4eba9 100644 --- a/framework/snippets/src/interactor_multi_sc_exec.rs +++ b/framework/snippets/src/multi/interactor_multi_sc_exec.rs @@ -1,9 +1,5 @@ -use crate::{ - interactor_multi_sc_process::{update_nonces_and_sign_tx, SenderSet, Txs}, - Interactor, StepBuffer, TransactionSpec, -}; - -use multiversx_sc_scenario::scenario_model::TxResponse; +use super::interactor_multi_sc_process::{update_nonces_and_sign_tx, SenderSet, Txs}; +use crate::{network_response, Interactor, InteractorStep, StepBuffer}; use multiversx_sdk::data::transaction::Transaction; impl Interactor { @@ -19,7 +15,9 @@ impl Interactor { let results = self.process_txs(txs).await; for (i, sc_call_step) in buffer.refs.iter_mut().enumerate() { - sc_call_step.set_response(TxResponse::from_network_tx(results.get(i).unwrap().clone())); + sc_call_step.set_response(network_response::parse_tx_response( + results.get(i).unwrap().clone(), + )); } for step in buffer.refs.iter_mut() { @@ -32,7 +30,7 @@ impl Interactor { for sc_call_step in &mut buffer.refs { let mut transaction = sc_call_step.to_transaction(self); - let sender_address = &sc_call_step.to_address().value; + let sender_address = &sc_call_step.sender_address().value; let sender = self .sender_map .get_mut(sender_address) @@ -45,11 +43,11 @@ impl Interactor { } } -fn retrieve_senders(sc_call_steps: &[&mut dyn TransactionSpec]) -> SenderSet { +fn retrieve_senders(sc_call_steps: &[&mut dyn InteractorStep]) -> SenderSet { let mut senders = SenderSet::new(); for sc_call_step in sc_call_steps { - let sender_address = &sc_call_step.to_address().value; + let sender_address = &sc_call_step.sender_address().value; senders.insert(sender_address.clone()); } senders diff --git a/framework/snippets/src/interactor_multi_sc_process.rs b/framework/snippets/src/multi/interactor_multi_sc_process.rs similarity index 95% rename from framework/snippets/src/interactor_multi_sc_process.rs rename to framework/snippets/src/multi/interactor_multi_sc_process.rs index f19dcfb171..3364a4d5ee 100644 --- a/framework/snippets/src/interactor_multi_sc_process.rs +++ b/framework/snippets/src/multi/interactor_multi_sc_process.rs @@ -31,7 +31,7 @@ impl Interactor { .expect("failed to send transaction"); println!("process tx hash: {tx_hash} with nonce: {}", tx.nonce); - futures.push(self.retrieve_tx_on_network(tx_hash.clone())); + futures.push(self.proxy.retrieve_tx_on_network(tx_hash.clone())); } join_all(futures).await diff --git a/framework/snippets/src/interactor_tx_spec.rs b/framework/snippets/src/multi/interactor_step.rs similarity index 79% rename from framework/snippets/src/interactor_tx_spec.rs rename to framework/snippets/src/multi/interactor_step.rs index 7463d37c5e..be172bbb82 100644 --- a/framework/snippets/src/interactor_tx_spec.rs +++ b/framework/snippets/src/multi/interactor_step.rs @@ -6,22 +6,23 @@ use multiversx_sdk::data::transaction::Transaction; use crate::Interactor; -pub trait TransactionSpec { +/// Describes a scenario step that can be executed in an interactor. +pub trait InteractorStep { fn to_transaction(&self, interactor: &Interactor) -> Transaction; - fn to_address(&self) -> &AddressValue; + fn sender_address(&self) -> &AddressValue; fn run_step(&mut self, step_runner: &mut dyn ScenarioRunner); fn set_response(&mut self, tx_response: TxResponse); } -impl TransactionSpec for ScCallStep { +impl InteractorStep for ScCallStep { fn to_transaction(&self, interactor: &Interactor) -> Transaction { interactor.tx_call_to_blockchain_tx(&self.tx) } - fn to_address(&self) -> &AddressValue { + fn sender_address(&self) -> &AddressValue { &self.tx.from } @@ -35,12 +36,12 @@ impl TransactionSpec for ScCallStep { } } -impl TransactionSpec for ScDeployStep { +impl InteractorStep for ScDeployStep { fn to_transaction(&self, interactor: &Interactor) -> Transaction { interactor.sc_deploy_to_blockchain_tx(self) } - fn to_address(&self) -> &AddressValue { + fn sender_address(&self) -> &AddressValue { &self.tx.from } diff --git a/framework/snippets/src/step_buffer.rs b/framework/snippets/src/multi/step_buffer.rs similarity index 89% rename from framework/snippets/src/step_buffer.rs rename to framework/snippets/src/multi/step_buffer.rs index f4956ff3a0..529b790ff5 100644 --- a/framework/snippets/src/step_buffer.rs +++ b/framework/snippets/src/multi/step_buffer.rs @@ -1,10 +1,10 @@ use multiversx_sc_scenario::scenario_model::{ScCallStep, ScDeployStep}; -use crate::TransactionSpec; +use crate::InteractorStep; #[derive(Default)] pub struct StepBuffer<'a> { - pub refs: Vec<&'a mut dyn TransactionSpec>, + pub refs: Vec<&'a mut dyn InteractorStep>, } impl<'a> StepBuffer<'a> { @@ -54,7 +54,7 @@ impl<'a> StepBuffer<'a> { buffer } - pub fn to_refs_vec(&'a self) -> Vec<&'a dyn TransactionSpec> { + pub fn to_refs_vec(&'a self) -> Vec<&'a dyn InteractorStep> { self.refs.iter().map(|r| &**r).collect() } } diff --git a/framework/snippets/src/network_response.rs b/framework/snippets/src/network_response.rs new file mode 100644 index 0000000000..f7f0b962df --- /dev/null +++ b/framework/snippets/src/network_response.rs @@ -0,0 +1,222 @@ +use multiversx_sc_scenario::{ + imports::{Address, ESDTSystemSCAddress}, + multiversx_chain_vm::crypto_functions::keccak256, + scenario_model::{TxResponse, TxResponseStatus}, +}; +use multiversx_sdk::{ + data::transaction::{ApiSmartContractResult, Events, TransactionOnNetwork}, + utils::base64_decode, +}; + +const SC_DEPLOY_PROCESSING_TYPE: &str = "SCDeployment"; +const LOG_IDENTIFIER_SIGNAL_ERROR: &str = "signalError"; + +/// Creates a [`TxResponse`] from a [`TransactionOnNetwork`]. +pub fn parse_tx_response(tx: TransactionOnNetwork) -> TxResponse { + let mut response = TxResponse { + api_scrs: tx.smart_contract_results.unwrap_or_default(), + api_logs: tx.logs, + ..Default::default() + }; + + response.tx_error = process_signal_error(&response); + if !response.tx_error.is_success() { + return response; + } + + process( + &mut response, + tx.sender.to_bytes(), + tx.nonce, + tx.processing_type_on_destination, + ); + + response +} + +fn process_signal_error(tx_response: &TxResponse) -> TxResponseStatus { + if let Some(event) = find_log(tx_response, LOG_IDENTIFIER_SIGNAL_ERROR) { + let topics = event.topics.as_ref(); + if let Some(error) = process_topics_error(topics) { + return TxResponseStatus::signal_error(&error); + } + + let error_raw = base64_decode(topics.unwrap().get(1).unwrap()); + let error = String::from_utf8(error_raw).unwrap(); + return TxResponseStatus::signal_error(&error); + } + + TxResponseStatus::default() +} + +fn process( + tx_response: &mut TxResponse, + sender_address: [u8; 32], + nonce: u64, + processing_type_on_destination: String, +) { + process_out(tx_response); + process_new_deployed_address( + tx_response, + sender_address, + nonce, + processing_type_on_destination, + ); + process_new_issued_token_identifier(tx_response); +} + +fn process_out(tx_response: &mut TxResponse) { + let out_scr = tx_response.api_scrs.iter().find(is_out_scr); + + if let Some(out_scr) = out_scr { + tx_response.out = decode_scr_data_or_panic(&out_scr.data); + } else if let Some(data) = process_out_from_log(tx_response) { + tx_response.out = data + } +} + +fn process_out_from_log(tx_response: &TxResponse) -> Option>> { + if let Some(logs) = &tx_response.api_logs { + logs.events.iter().rev().find_map(|event| { + if event.identifier == "writeLog" { + if let Some(data) = &event.data { + let decoded_data = String::from_utf8(base64_decode(data)).unwrap(); + + if decoded_data.starts_with('@') { + let out = decode_scr_data_or_panic(decoded_data.as_str()); + return Some(out); + } + } + } + + None + }) + } else { + None + } +} + +fn process_new_deployed_address( + tx_response: &mut TxResponse, + sender_address_bytes: [u8; 32], + nonce: u64, + processing_type_on_destination: String, +) { + if processing_type_on_destination != SC_DEPLOY_PROCESSING_TYPE { + return; + } + + let sender_nonce_bytes = nonce.to_le_bytes(); + let mut bytes_to_hash: Vec = Vec::new(); + bytes_to_hash.extend_from_slice(&sender_address_bytes); + bytes_to_hash.extend_from_slice(&sender_nonce_bytes); + + let address_keccak = keccak256(&bytes_to_hash); + + let mut address = [0u8; 32]; + + address[0..8].copy_from_slice(&[0u8; 8]); + address[8..10].copy_from_slice(&[5, 0]); + address[10..30].copy_from_slice(&address_keccak[10..30]); + address[30..32].copy_from_slice(&sender_address_bytes[30..32]); + + tx_response.new_deployed_address = Some(Address::from(address)); +} + +fn process_new_issued_token_identifier(tx_response: &mut TxResponse) { + for scr in tx_response.api_scrs.iter() { + if scr.sender.to_bech32_string().unwrap() != ESDTSystemSCAddress.to_bech32_string() { + continue; + } + + let Some(prev_tx) = tx_response + .api_scrs + .iter() + .find(|e| e.hash == scr.prev_tx_hash) + else { + continue; + }; + + let is_issue_fungible = prev_tx.data.starts_with("issue@"); + let is_issue_semi_fungible = prev_tx.data.starts_with("issueSemiFungible@"); + let is_issue_non_fungible = prev_tx.data.starts_with("issueNonFungible@"); + let is_register_meta_esdt = prev_tx.data.starts_with("registerMetaESDT@"); + let is_register_and_set_all_roles_esdt = + prev_tx.data.starts_with("registerAndSetAllRoles@"); + + if !is_issue_fungible + && !is_issue_semi_fungible + && !is_issue_non_fungible + && !is_register_meta_esdt + && !is_register_and_set_all_roles_esdt + { + continue; + } + + if scr.data.starts_with("ESDTTransfer@") { + let encoded_tid = scr.data.split('@').nth(1); + if encoded_tid.is_none() { + return; + } + + tx_response.new_issued_token_identifier = + Some(String::from_utf8(hex::decode(encoded_tid.unwrap()).unwrap()).unwrap()); + + break; + } else if scr.data.starts_with("@00@") { + let encoded_tid = scr.data.split('@').nth(2); + if encoded_tid.is_none() { + return; + } + + tx_response.new_issued_token_identifier = + Some(String::from_utf8(hex::decode(encoded_tid.unwrap()).unwrap()).unwrap()); + + break; + } + } +} + +fn find_log<'a>(tx_response: &'a TxResponse, log_identifier: &str) -> Option<&'a Events> { + if let Some(logs) = &tx_response.api_logs { + logs.events + .iter() + .find(|event| event.identifier == log_identifier) + } else { + None + } +} + +/// Checks for invalid topics. +pub fn process_topics_error(topics: Option<&Vec>) -> Option { + if topics.is_none() { + return Some("missing topics".to_string()); + } + + let topics = topics.unwrap(); + if topics.len() != 2 { + Some(format!( + "expected to have 2 topics, found {} instead", + topics.len() + )) + } else { + None + } +} + +/// Decodes the data of a smart contract result. +pub fn decode_scr_data_or_panic(data: &str) -> Vec> { + let mut split = data.split('@'); + let _ = split.next().expect("SCR data should start with '@'"); + let result_code = split.next().expect("missing result code"); + assert_eq!(result_code, "6f6b", "result code is not 'ok'"); + + split + .map(|encoded_arg| hex::decode(encoded_arg).expect("error hex-decoding result")) + .collect() +} + +/// Checks if the given smart contract result is an out smart contract result. +pub fn is_out_scr(scr: &&ApiSmartContractResult) -> bool { + scr.nonce != 0 && scr.data.starts_with('@') +} diff --git a/framework/scenario/src/test_wallets/mod.rs b/framework/snippets/src/test_wallets.rs similarity index 60% rename from framework/scenario/src/test_wallets/mod.rs rename to framework/snippets/src/test_wallets.rs index 437f5c829f..341f93ef29 100644 --- a/framework/scenario/src/test_wallets/mod.rs +++ b/framework/snippets/src/test_wallets.rs @@ -6,60 +6,60 @@ fn test_wallet(pem_file_contents: &str) -> Wallet { /// Test wallet. Do not use on mainnet. pub fn alice() -> Wallet { - test_wallet(include_str!("alice.pem")) + test_wallet(include_str!("test_wallets/alice.pem")) } /// Test wallet. Do not use on mainnet. pub fn bob() -> Wallet { - test_wallet(include_str!("bob.pem")) + test_wallet(include_str!("test_wallets/bob.pem")) } /// Test wallet. Do not use on mainnet. pub fn carol() -> Wallet { - test_wallet(include_str!("carol.pem")) + test_wallet(include_str!("test_wallets/carol.pem")) } /// Test wallet. Do not use on mainnet. pub fn dan() -> Wallet { - test_wallet(include_str!("dan.pem")) + test_wallet(include_str!("test_wallets/dan.pem")) } /// Test wallet. Do not use on mainnet. pub fn eve() -> Wallet { - test_wallet(include_str!("eve.pem")) + test_wallet(include_str!("test_wallets/eve.pem")) } /// Test wallet. Do not use on mainnet. pub fn frank() -> Wallet { - test_wallet(include_str!("frank.pem")) + test_wallet(include_str!("test_wallets/frank.pem")) } /// Test wallet. Do not use on mainnet. pub fn grace() -> Wallet { - test_wallet(include_str!("grace.pem")) + test_wallet(include_str!("test_wallets/grace.pem")) } /// Test wallet. Do not use on mainnet. pub fn heidi() -> Wallet { - test_wallet(include_str!("heidi.pem")) + test_wallet(include_str!("test_wallets/heidi.pem")) } /// Test wallet. Do not use on mainnet. pub fn ivan() -> Wallet { - test_wallet(include_str!("ivan.pem")) + test_wallet(include_str!("test_wallets/ivan.pem")) } /// Test wallet. Do not use on mainnet. pub fn judy() -> Wallet { - test_wallet(include_str!("judy.pem")) + test_wallet(include_str!("test_wallets/judy.pem")) } /// Test wallet. Do not use on mainnet. pub fn mallory() -> Wallet { - test_wallet(include_str!("mallory.pem")) + test_wallet(include_str!("test_wallets/mallory.pem")) } /// Test wallet. Do not use on mainnet. pub fn mike() -> Wallet { - test_wallet(include_str!("mike.pem")) + test_wallet(include_str!("test_wallets/mike.pem")) } diff --git a/framework/scenario/src/test_wallets/alice.pem b/framework/snippets/src/test_wallets/alice.pem similarity index 100% rename from framework/scenario/src/test_wallets/alice.pem rename to framework/snippets/src/test_wallets/alice.pem diff --git a/framework/scenario/src/test_wallets/bob.pem b/framework/snippets/src/test_wallets/bob.pem similarity index 100% rename from framework/scenario/src/test_wallets/bob.pem rename to framework/snippets/src/test_wallets/bob.pem diff --git a/framework/scenario/src/test_wallets/carol.pem b/framework/snippets/src/test_wallets/carol.pem similarity index 100% rename from framework/scenario/src/test_wallets/carol.pem rename to framework/snippets/src/test_wallets/carol.pem diff --git a/framework/scenario/src/test_wallets/dan.pem b/framework/snippets/src/test_wallets/dan.pem similarity index 100% rename from framework/scenario/src/test_wallets/dan.pem rename to framework/snippets/src/test_wallets/dan.pem diff --git a/framework/scenario/src/test_wallets/eve.pem b/framework/snippets/src/test_wallets/eve.pem similarity index 100% rename from framework/scenario/src/test_wallets/eve.pem rename to framework/snippets/src/test_wallets/eve.pem diff --git a/framework/scenario/src/test_wallets/frank.pem b/framework/snippets/src/test_wallets/frank.pem similarity index 100% rename from framework/scenario/src/test_wallets/frank.pem rename to framework/snippets/src/test_wallets/frank.pem diff --git a/framework/scenario/src/test_wallets/grace.pem b/framework/snippets/src/test_wallets/grace.pem similarity index 100% rename from framework/scenario/src/test_wallets/grace.pem rename to framework/snippets/src/test_wallets/grace.pem diff --git a/framework/scenario/src/test_wallets/heidi.pem b/framework/snippets/src/test_wallets/heidi.pem similarity index 100% rename from framework/scenario/src/test_wallets/heidi.pem rename to framework/snippets/src/test_wallets/heidi.pem diff --git a/framework/scenario/src/test_wallets/ivan.pem b/framework/snippets/src/test_wallets/ivan.pem similarity index 100% rename from framework/scenario/src/test_wallets/ivan.pem rename to framework/snippets/src/test_wallets/ivan.pem diff --git a/framework/scenario/src/test_wallets/judy.pem b/framework/snippets/src/test_wallets/judy.pem similarity index 100% rename from framework/scenario/src/test_wallets/judy.pem rename to framework/snippets/src/test_wallets/judy.pem diff --git a/framework/scenario/src/test_wallets/mallory.pem b/framework/snippets/src/test_wallets/mallory.pem similarity index 100% rename from framework/scenario/src/test_wallets/mallory.pem rename to framework/snippets/src/test_wallets/mallory.pem diff --git a/framework/scenario/src/test_wallets/mike.pem b/framework/snippets/src/test_wallets/mike.pem similarity index 100% rename from framework/scenario/src/test_wallets/mike.pem rename to framework/snippets/src/test_wallets/mike.pem diff --git a/framework/snippets/tests/test_tx_deployed_address.rs b/framework/snippets/tests/test_tx_deployed_address.rs new file mode 100644 index 0000000000..377a0e779f --- /dev/null +++ b/framework/snippets/tests/test_tx_deployed_address.rs @@ -0,0 +1,133 @@ +use multiversx_sc_scenario::imports::Address; +use multiversx_sc_snippets::network_response; +use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; + +#[test] +fn test_deployed_address() { + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCDeployment", + "processingTypeOnDestination": "SCDeployment", + "hash": "07a176d1734d1901d396be344f97e1d80f076269e9559f9b2110f6f11c4f74de", + "nonce": 427, + "round": 2190715, + "epoch": 887, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6gq4hu", + "sender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "gasPrice": 1000000000, + "gasLimit": 600000000, + "data": "MDA2MTczNmQwMTAwMDAwMDAxOTgwMTE5NjAwMjdmN2YwMDYwMDE3ZjAxN2Y2MDAwMDA2MDAwMDE3ZjYwMDI3ZjdmMDE3ZjYwMDM3ZjdmN2YwMDYwMDE3ZjAwNjAwNDdmN2Y3ZjdmMDA2MDA1N2Y3ZjdmN2Y3ZjAwNjAwMzdmN2Y3ZjAxN2Y2MDA0N2Y3ZjdmN2YwMTdmNjAwMjdmN2UwMDYwMDE3ZjAxN2U2MDAyN2Y3ZjAxN2U2MDA1N2Y3ZjdlN2Y3ZjAxN2Y2MDA2N2U3ZjdmN2Y3ZjdmMDE3ZjYwMDE3ZTAwNjAwMDAxN2U2MDAxN2UwMTdmNjAwNDdmN2Y3ZTdmMDA2MDA1N2U3ZjdmN2Y3ZjAxN2Y2MDA0N2Y3ZjdmN2UwMDYwMDE3ZTAxN2U2MDA0N2Y3ZTdmN2YwMDYwMDI3ZTdmMDAwMmMxMDcyOTAzNjU2ZTc2MTI2ZDYxNmU2MTY3NjU2NDUzNjk2NzZlNjE2YzQ1NzI3MjZmNzIwMDA2MDM2NTZlNzYwZTYyNjk2NzQ5NmU3NDUzNjU3NDQ5NmU3NDM2MzQwMDBiMDM2NTZlNzYwOTYyNjk2NzQ5NmU3NDQxNjQ2NDAwMDUwMzY1NmU3NjBiNzM2OTY3NmU2MTZjNDU3MjcyNmY3MjAwMDAwMzY1NmU3NjBhNmQ0Mjc1NjY2NjY1NzI0ZTY1NzcwMDAzMDM2NTZlNzYwZDZkNDI3NTY2NjY2NTcyNDE3MDcwNjU2ZTY0MDAwNDAzNjU2ZTc2MDk2ZDQyNzU2NjY2NjU3MjQ1NzEwMDA0MDM2NTZlNzYwZDZkNDI3NTY2NjY2NTcyNDY2OTZlNjk3MzY4MDAwMTAzNjU2ZTc2MjI2ZDYxNmU2MTY3NjU2NDRkNzU2Yzc0Njk1NDcyNjE2ZTczNjY2NTcyNDU1MzQ0NTQ0ZTQ2NTQ0NTc4NjU2Mzc1NzQ2NTAwMGUwMzY1NmU3NjFiNmQ2MTZlNjE2NzY1NjQ0NTc4NjU2Mzc1NzQ2NTRmNmU0NDY1NzM3NDQzNmY2ZTc0NjU3ODc0MDAwZjAzNjU2ZTc2MGQ2ZDYxNmU2MTY3NjU2NDQzNjE2YzZjNjU3MjAwMDYwMzY1NmU3NjEwNmQ2MTZlNjE2NzY1NjQ1MzQzNDE2NDY0NzI2NTczNzMwMDA2MDM2NTZlNzYxMzZkNjE2ZTYxNjc2NTY0NGY3NzZlNjU3MjQxNjQ2NDcyNjU3MzczMDAwNjAzNjU2ZTc2MWM2ZDYxNmU2MTY3NjU2NDQ3NjU3NDRkNzU2Yzc0Njk0NTUzNDQ1NDQzNjE2YzZjNTY2MTZjNzU2NTAwMDYwMzY1NmU3NjEyNmQ0Mjc1NjY2NjY1NzI0NzY1NzQ0MTcyNjc3NTZkNjU2ZTc0MDAwNDAzNjU2ZTc2MTI2ZDQyNzU2NjY2NjU3MjQxNzA3MDY1NmU2NDQyNzk3NDY1NzMwMDA5MDM2NTZlNzYxOTYyNjk2NzQ5NmU3NDQ3NjU3NDU1NmU3MzY5Njc2ZTY1NjQ0MTcyNjc3NTZkNjU2ZTc0MDAwMDAzNjU2ZTc2MWI3MzZkNjE2YzZjNDk2ZTc0NDc2NTc0NTU2ZTczNjk2NzZlNjU2NDQxNzI2Nzc1NmQ2NTZlNzQwMDBjMDM2NTZlNzYxMDZkNDI3NTY2NjY2NTcyNDc2NTc0NGM2NTZlNjc3NDY4MDAwMTAzNjU2ZTc2MGY2NzY1NzQ0ZTc1NmQ0MTcyNjc3NTZkNjU2ZTc0NzMwMDAzMDM2NTZlNzYxNjczNmQ2MTZjNmM0OTZlNzQ0NjY5NmU2OTczNjg1NTZlNzM2OTY3NmU2NTY0MDAxMDAzNjU2ZTc2MDk2MjY5Njc0OTZlNzQ1Mzc1NjIwMDA1MDM2NTZlNzYwYTY3NjU3NDQ3NjE3MzRjNjU2Njc0MDAxMTAzNjU2ZTc2MGY2MzZjNjU2MTZlNTI2NTc0NzU3MjZlNDQ2MTc0NjEwMDAyMDM2NTZlNzYwZjZkNDI3NTY2NjY2NTcyNTM2NTc0NDI3OTc0NjU3MzAwMDkwMzY1NmU3NjA5NjI2OTY3NDk2ZTc0NDM2ZDcwMDAwNDAzNjU2ZTc2MGE2MjY5Njc0OTZlNzQ1NDQ0Njk3NjAwMDUwMzY1NmU3NjA5NjI2OTY3NDk2ZTc0NGQ3NTZjMDAwNTAzNjU2ZTc2MTk2ZDQyNzU2NjY2NjU3MjQ2NzI2ZjZkNDI2OTY3NDk2ZTc0NTU2ZTczNjk2NzZlNjU2NDAwMDQwMzY1NmU3NjE3NmQ0Mjc1NjY2NjY1NzI1NDZmNDI2OTY3NDk2ZTc0NTU2ZTczNjk2NzZlNjU2NDAwMDQwMzY1NmU3NjA5NjI2OTY3NDk2ZTc0NTA2Zjc3MDAwNTAzNjU2ZTc2MTQ2ZDQyNzU2NjY2NjU3MjQzNmY3MDc5NDI3OTc0NjU1MzZjNjk2MzY1MDAwYTAzNjU2ZTc2MTI2ZDQyNzU2NjY2NjU3MjUzNzQ2ZjcyNjE2NzY1NGM2ZjYxNjQwMDA0MDM2NTZlNzYxMzZkNDI3NTY2NjY2NTcyNTM3NDZmNzI2MTY3NjU1Mzc0NmY3MjY1MDAwNDAzNjU2ZTc2MGU2MzY4NjU2MzZiNGU2ZjUwNjE3OTZkNjU2ZTc0MDAwMjAzNjU2ZTc2MTc2ZDYxNmU2MTY3NjU2NDQ3NjU3NDQyNjE2MzZiNTQ3MjYxNmU3MzY2NjU3MjczMDAwMDAzNjU2ZTc2MGY2ZDYxNmU2MTY3NjU2NDU3NzI2OTc0NjU0YzZmNjcwMDAwMDM2NTZlNzYxNDYyNjk2NzQ5NmU3NDQ2Njk2ZTY5NzM2ODU1NmU3MzY5Njc2ZTY1NjQwMDA2MDM2NTZlNzYwNjY2Njk2ZTY5NzM2ODAwMDAwMzY1NmU3NjBhNjI2OTY3NDk2ZTc0NTM2OTY3NmUwMDAxMDM2NTZlNzYxMzZkNDI3NTY2NjY2NTcyNDc2NTc0NDI3OTc0NjU1MzZjNjk2MzY1MDAwYTAzZDMwMWQxMDEwMTAzMDgwMjAxMTIwMTA0MDAwMTA3MDYwNjA2MDAwNDAxMDkwMTAwMDEwMDAwMDAwMDEzMDMwMDE0MDMwMzAzMDIwMzAxMDcwNDAwMDMwOTAxMDkwOTA5MDAwNzA3MDEwMDA2MDYwMTA2MDYwYzA1MDEwODA1MDAwMTBiMDAwODA3MTUwNzA4MDgwMDBhMDAxNjAxMDEwNjAxMDAwMDAwMDUwMDAwMDEwMzAwMDYwMTAwMTcwNTA1MGEwNzA0MDAwNDBhMDAwNDA0MDQwMDA0MDQwNDA0MDQwMTAxMDAwNDBkMDcwNzA3MDgwYTAwMDUwMTAxMDUwNTA2MDEwMTAwMGIwYjAxMDEwMTAxMDEwNTBkMDEwNTAwMDAwMDA1MDUwMDAwMDAwMDAwMGMwNzA3MDcwNzAwMDAwODE4MDMwMzAzMDAwMzAzMDAwMTA0MDcwMzAzMDMwMzAxMDEwMzAzMDMwMzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwODA4MDUwMzAxMDAwMzA2MTYwMzdmMDE0MTgwODAwODBiN2YwMDQxZTlkYjA4MGI3ZjAwNDFmMGRiMDgwYjA3YzcwNTIwMDY2ZDY1NmQ2ZjcyNzkwMjAwMDQ2OTZlNjk3NDAwZGIwMTA3NzU3MDY3NzI2MTY0NjUwMGRjMDEwNzY0NjU3MDZmNzM2OTc0MDBkZDAxMDg3NzY5NzQ2ODY0NzI2MTc3MDBkZTAxMDg2MzZmNmQ3MDZmNzU2ZTY0MDBkZjAxMGU2NzY1NzQ1NDZmNzQ2MTZjNDE3MzczNjU3NDczMDBlMDAxMGY2NzY1NzQ1NjYxNzU2Yzc0NDE2NDY0NzI2NTczNzMwMGUxMDExNzY3NjU3NDQxNzM3MzY1NzQ1NDZmNmI2NTZlNDk2NDY1NmU3NDY5NjY2OTY1NzIwMGUyMDExZDY3NjU3NDRkNmY2ZTY1Nzk0ZDYxNzI2YjY1NzQ1NDZmNmI2NTZlNDk2NDY1NmU3NDY5NjY2OTY1NzIwMGUzMDEyMjY3NjU3NDRkNmY2ZTY1Nzk0ZDYxNzI2YjY1NzQ1NTZlNjQ2NTcyNmM3OTY5NmU2NzQ5NjQ2NTZlNzQ2OTY2Njk2NTcyMDBlNDAxMWY2NzY1NzQ0MjZmNmY3Mzc0NjU3MjUzNzQ2MTZiNjU2NDU0NmY2YjY1NmU0OTY0NjU2ZTc0Njk2NjY5NjU3MjAwZTUwMTE0Njc2NTc0NDM2ZjZlNzQ3MjZmNmM2YzY1NzI0MTY0NjQ3MjY1NzM3MzAwZTYwMTE1Njc2NTc0NGQ2ZjZlNjU3OTRkNjE3MjZiNjU3NDQxNjQ2NDcyNjU3MzczMDBlNzAxMWQ2NzY1NzQ1NzcyNjE3MDcwNjU2NDQ1Njc2YzY0NDM2ZjZlNzQ3MjYxNjM3NDQxNjQ2NDcyNjU3MzczMDBlODAxMWQ2NzY1NzQ1NzcyNjE3MDcwNjU2NDQ1Njc2YzY0NTQ2ZjZiNjU2ZTQ5NjQ2NTZlNzQ2OTY2Njk2NTcyMDBlOTAxMTE2NzY1NzQ0MjZmNmY3Mzc0NjU3MjQxNjQ2NDcyNjU3MzczMDBlYTAxMTk2NzY1NzQ0MzZmNmQ3MDZmNzU2ZTY0NTg0NTc4NjM2ODYxNmU2NzY1NTM3NzYxNzA3MzAwZWIwMTE3Njc2NTc0NDM2ZjZkNzA2Zjc1NmU2NDQxNzM2ODczNzc2MTcwNTM3NzYxNzA3MzAwZWMwMTE2Njc2NTc0NDM2ZjZkNzA2Zjc1NmU2NDQ2NjU2NTczNTA2NTcyNjM2NTZlNzQwMGVkMDExOTY3NjU3NDUwNjU3MjY2NmY3MjZkNjE2ZTYzNjU0NjY1NjU3MzUwNjU3MjYzNjU2ZTc0MDBlZTAxMGU3Mzc0NjE2YjY1NDk2ZTQyNmY2ZjczNzQ2NTcyMDBlZjAxMWI3MjY1NjI2MTZjNjE2ZTYzNjU1MDZmNzI3NDY2NmY2YzY5NmY0OTZlNDI2ZjZmNzM3NDY1NzIwMGYwMDExMjc1NmU3Mzc0NjE2YjY1NDY3MjZmNmQ0MjZmNmY3Mzc0NjU3MjAwZjEwMTE4NjM2YzYxNjk2ZDRkNzU2Yzc0Njk3MDZjNjU0NjcyNmY2ZDQyNmY2ZjczNzQ2NTcyMDBmMjAxMTk3MzY1NzQ1MDY1NzI2NjZmNzI2ZDYxNmU2MzY1NDY2NTY1NzM1MDY1NzI2MzY1NmU3NDAwZjMwMTE2NzM2NTc0NDM2ZjZkNzA2Zjc1NmU2NDQ2NjU2NTczNTA2NTcyNjM2NTZlNzQwMGY0MDExMDczNjU3NDQzNmY2ZDcwNmY3NTZlNjQ1Mzc3NjE3MDczMDBmNTAxMGQ2NzY1NzQ0ZTYxNzQ3NTcyNjE2YzQxNTA1OTAwZjYwMTA4NjM2MTZjNmM0MjYxNjM2YjAwZjcwMTBhNWY1ZjY0NjE3NDYxNWY2NTZlNjQwMzAxMGI1ZjVmNjg2NTYxNzA1ZjYyNjE3MzY1MDMwMjBhOWFhOTAxZDEwMTE2MDEwMTdmMTAyYTIyMDE0MjAwMTAwMTIwMDEyMDAxMjAwMDEwMDIyMDAxMGIxOTAxMDE3ZjQxYzg4ZDA4NDFjODhkMDgyODAyMDA0MTAxNmIyMjAwMzYwMjAwMjAwMDBiMmUwMDAyNDAyMDAxMjAwMjRkMDQ0MDIwMDIyMDA0NGQwZDAxMTAyYzAwMGIxMDJjMDAwYjIwMDAyMDAyMjAwMTZiMzYwMjA0MjAwMDIwMDEyMDAzNmEzNjAyMDAwYjBiMDA0MWI4OGQwODQxMGUxMDAzMDAwYjEzMDEwMTdmMTAyYTIyMDEyMDAwYWQ0MmZmMDE4MzEwMDEyMDAxMGIyMTAxMDE3ZjEwMmEyMTAxMjAwMDQyMDA1MzA0NDA0MWIyODUwODQxMTExMDAzMDAwYjIwMDEyMDAwMTAwMTIwMDEwYjBmMDEwMTdmMTAwNDIyMDEyMDAwMTAwNTFhMjAwMTBiMGIwMDIwMDAyMDAxMTAwNjQxMDA0YTBiMmQwMTAxN2YyMzAwNDEyMDZiMjIwMjI0MDAyMDAyMjAwMDEwMzI0MWMwODAwODQxMDgxMDMzMjAwMjIwMDEzNjAyMTgyMDAyMTAzNDIwMDI0MTIwNmEyNDAwMGIxOTAwMjAwMDQxZmVmZmZmZmYwNzQ2MDQ0MDQxYzg4MDA4NDExOTEwMDMwMDBiMjAwMDBiMmEwMDIwMDIyMDAzMTA0ZDIxMDIxMDQzMjEwMzIwMDA0MjdmMzcwMzA4MjAwMDIwMDMzNjAyMDQyMDAwMjAwMjM2MDIwMDIwMDAyMDAxMzYwMjEwMGI3ZDAxMDM3ZjIzMDA0MTEwNmIyMjAxMjQwMDIwMDAyOTAzMDgxMDcxMjAwMDI4MDIxMDIwMDAyODAyMTgyMDAwMjgwMjAwMjAwMDI4MDIwNDEwNDUyMTAyMTAxNzQxMDAyMTAwMjAwMjEwMTIyMTAzMjAwMTQxMDAzNjAyMGMyMDAxMjAwMjM2MDIwNDIwMDEyMDAzNDEwMjc2MjIwMjM2MDIwODAzNDAyMDAwMjAwMjRmNDUwNDQwMjAwMTQxMDQ2YTEwNzUxYTIwMDEyODAyMDgyMTAyMjAwMTI4MDIwYzIxMDAwYzAxMGIwYjIwMDE0MTEwNmEyNDAwMGIzNjAxMDI3ZjIzMDA0MTEwNmIyMjAxMjQwMDIwMDE0MTA4NmExMDM2MjAwMTI4MDIwODIxMDIyMDAwMjAwMTJkMDAwYzQxMDE3MTNhMDAwNDIwMDAyMDAyMzYwMjAwMjAwMTQxMTA2YTI0MDAwYjZkMDEwMjdmMjMwMDQxMTA2YjIyMDEyNDAwMjAwMDAyN2Y0MWUwZGIwODJkMDAwMDIyMDI0NTA0NDA0MWUwZGIwODQxMDEzYTAwMDA0MWRjZGIwODQxMDAzNjAyMDAyMDAxNDEwODZhNDEwMDEwOWYwMTIwMDEyODAyMDgyMDAxMjgwMjBjNDFiODhkMDg0MTAwMTA1NzEwNDMwYzAxMGI0MWI4OGQwODQxMDAxMDRkMGIzNjAyMDAyMDAwMjAwMjQxMDE3MzNhMDAwNDIwMDE0MTEwNmEyNDAwMGIwYjAwMjAwMDIwMDExMDM4MTAwNzFhMGI0OTAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDIyMDAxM2EwMDBjMjAwMjIwMDAzNjAyMDgyMDAyNDEwODZhMTBhNTAxMjAwMjI4MDIwODIwMDIyZDAwMGMwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAyNDExMDZhMjQwMDBiMGUwMDIwMDA0MThhODUwODQxMGIxMDNhMTAzYjBiMTMwMDIwMDAyMDAwMjAwMTIwMDIxMDUyMjAwMTIwMDIxMDg1MDEwYjBkMDAyMDAwMTAyYTIyMDAxMDFkMWEyMDAwMGIwYTAwMjAwMDEwM2QyMDAxMTAzZTBiMGYwMTAxN2YxMDJhMjIwMTIwMDAxMDFjMWEyMDAxMGI1MTAxMDI3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDIyMDAwMTAxMjIyMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIwYzIwMDEyMDAyNDEwYzZhNDEwNDEwYTMwMTIwMDEyMDAwMTBiZDAxMjAwMjQxMTA2YTI0MDAwYjBhMDAyMDAwMTAzZDIwMDExMDQwMGI1MTAxMDI3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDIyMDAwMTAxMjIyMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIwYzIwMDEyMDAyNDEwYzZhNDEwNDEwMGYxYTIwMDEyMDAwMTA4YjAxMjAwMjQxMTA2YTI0MDAwYjA5MDAyMDAwMjAwMTEwMDMwMDBiNTAwMTA0N2YxMDQzMjEwNjEwNDMyMTA3MjMwMDQxMTA2YjIyMDQyNDAwMTA0MzIxMDUyMDAxMTAyZjIxMDEyMDA0MjAwMzEwMjkzNjAyMGMyMDA0MjAwMjM3MDMwMDIwMDQyMDAxMzYwMjA4MjAwNTIwMDQxMDQ0MjAwMDIwMDU0MjAwMjAwNjIwMDcxMDA4MWEyMDA0NDExMDZhMjQwMDBiMTMwMTAxN2YxMDJhMjIwMDQxYjg4ZDA4NDEwMDEwMTgxYTIwMDAwYmQyMDEwMjAyN2YwMTdlMjMwMDQxMTA2YjIyMDMyNDAwMjAwMzIwMDEyODAyMDgyMjAyNDExODc0MjAwMjQxODBmZTAzNzE0MTA4NzQ3MjIwMDI0MTA4NzY0MTgwZmUwMzcxMjAwMjQxMTg3NjcyNzIzNjAyMDAyMDAzMjAwMTI4MDIwYzIyMDI0MTE4NzQyMDAyNDE4MGZlMDM3MTQxMDg3NDcyMjAwMjQxMDg3NjQxODBmZTAzNzEyMDAyNDExODc2NzI3MjM2MDIwYzIwMDMyMDAxMjkwMzAwMjIwNDQyMzg4NjIwMDQ0MjgwZmUwMzgzNDIyODg2ODQyMDA0NDI4MDgwZmMwNzgzNDIxODg2MjAwNDQyODA4MDgwZjgwZjgzNDIwODg2ODQ4NDIwMDQ0MjA4ODg0MjgwODA4MGY4MGY4MzIwMDQ0MjE4ODg0MjgwODBmYzA3ODM4NDIwMDQ0MjI4ODg0MjgwZmUwMzgzMjAwNDQyMzg4ODg0ODQ4NDM3MDIwNDIwMDAyMDAzNDExMDEwMGYxYTIwMDM0MTEwNmEyNDAwMGIxNTAwMjAwMDIwMDEyMDAyMjAwMzIwMDQxMDJhMjIwMTEwMDkxYTIwMDEwYjBjMDEwMTdmMTAyYTIyMDAxMDBhMjAwMDBiMGMwMTAxN2YxMDJhMjIwMDEwMGIyMDAwMGIwYzAxMDE3ZjEwMmEyMjAwMTAwYzIwMDAwYjE1MDAxMDQ4MTA0NjEwMzAwNDQwMGYwYjQxOTI4ZDA4NDEyNDEwMDMwMDBiMmIwMTAxN2Y0MWU4ZGIwODJkMDAwMDIyMDAwNDQwNDE2YjQxZmZmZmZmZmYwNzIwMDAxYjBmMGI0MWU4ZGIwODQxMDEzYTAwMDA0MTZiMTAwZDQxNmIwYjBkMDAyMDAwMTAyYTIyMDAxMDBlMWEyMDAwMGIyZTAxMDE3ZjQxZDU4MzA4NDExNzEwNGQyMjA0MjAwMDIwMDExMDBmMWEyMDA0NDFlYzgzMDg0MTAzMTAwZjFhMjAwNDIwMDIyMDAzMTAwZjFhMjAwNDEwMDAwMDBiMTEwMTAxN2YxMDJhMjIwMjIwMDAyMDAxMTAxODFhMjAwMjBiNDYwMTAxN2YyMzAwNDExMDZiMjIwMjI0MDAyMDAyMjAwMTQxMTg3NDIwMDE0MTgwZmUwMzcxNDEwODc0NzIyMDAxNDEwODc2NDE4MGZlMDM3MTIwMDE0MTE4NzY3MjcyMzYwMjBjMjAwMDIwMDI0MTBjNmE0MTA0MTAwZjFhMjAwMjQxMTA2YTI0MDAwYjBlMDEwMTdmNDEwMDEwMmEyMjAwMTAxMDIwMDAwYjFmMDAyMDAwMTA0YjIyMDAxMDEyNDEyMDQ3MDQ0MDIwMDEyMDAyNDFiMDg2MDg0MTEwMTA0YzAwMGIyMDAwMGJkOTAzMDEwOTdmMjMwMDQxNDA2YTIyMDEyNDAwMjAwMDEwNGIyMTAyMTA0MzIxMDYyMDAyMTAxMjIxMDAyMDAxNDEyNDZhNDEwMDNhMDAwMDIwMDE0MTIwNmEyMDAwMzYwMjAwMjAwMTIwMDIzNjAyMWMyMDAxMjAwMDM2MDIxODIwMDE0MTAwMzYwMjE0NDEwMDIxMDIwMzdmMjAwMDIwMDI0NjA0N2YyMDAxMmQwMDI0MDQ0MDQxZGNkYjA4NDEwMDM2MDIwMDQxZTBkYjA4NDEwMDNhMDAwMDBiMjAwMTQxNDA2YjI0MDAyMDA2MDUyMDAxNDExNDZhMjIwMDQxOTc4NzA4NDExNjEwM2EyMTA0MjAwMDQxOTc4NzA4NDExNjEwNTIyMTAwMTA0MzIxMDMwMzQwMjAwMDA0NDAyMDAxNDExNDZhMjIwNTQxOTc4NzA4NDExNjEwNTIyMTA3MjAwNTQxOTc4NzA4NDExNjEwNTMyMTA4MjAwNTQxOTc4NzA4NDExNjEwM2EyMTA5NDEwMDIxMDIwMjQwMDI0MDAyNDAyMDA1NDE5Nzg3MDg0MTE2MTA1NDQxZmYwMTcxMGUwMjAyMDEwMDBiNDE5Nzg3MDg0MTE2NDFlZDg2MDg0MTBkMTA0YzAwMGI0MTAxMjEwMjBiMjAwMTIwMDIzYTAwMzQyMDAxMjAwOTM2MDIzMDIwMDEyMDA4MzYwMjJjMjAwMTIwMDczNjAyMjgyMDAzMjAwMTQxMjg2YTEwNTUyMDAwNDEwMTZiMjEwMDBjMDEwYjBiMjAwMTQyMDAzNzAzMjgyMDAxMjAwNDQxMTg3NDIwMDQ0MTgwZmUwMzcxNDEwODc0NzIyMDA0NDEwODc2NDE4MGZlMDM3MTIwMDQ0MTE4NzY3MjcyMzYwMjNjMjAwMTQxMDg2YTIwMDE0MTI4NmEyMjAwNDEwMDQxMDQxMDU2MjAwMTI4MDIwODIwMDEyODAyMGMyMDAxNDEzYzZhMjIwMjQxMDQxMDU3MjAwMTIwMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIzYzIwMDEyMDAwNDEwNDQxMDgxMDU2MjAwMTI4MDIwMDIwMDEyODAyMDQyMDAyNDEwNDEwNTcyMDA2MjAwMDQxMDgxMDBmMWEyMDAxMjgwMjE0MjEwMjIwMDEyODAyMTgyMTAwMGMwMTBiMGIwYjM3MDIwMTdmMDE3ZTIzMDA0MTEwNmIyMjAzMjQwMDIwMDM0MTAwMzYwMjBjMjAwMDIwMDM0MTBjNmEyMjAwNDEwNDIwMDEyMDAyMTBjNTAxMjAwMDQxMDQxMGIxMDEyMDAzNDExMDZhMjQwMGE3MGIwZDAwMjAwMDQxMjAyMDAxMjAwMjEwODUwMTBiMzAwMTAxN2YyMzAwNDExMDZiMjIwMzI0MDAyMDAzNDEwMDNhMDAwZjIwMDAyMDAzNDEwZjZhNDEwMTIwMDEyMDAyMTBjNTAxMjAwMzJkMDAwZjIwMDM0MTEwNmEyNDAwMGJmNjAyMDEwNTdmMjMwMDQxZDAwMDZiMjIwMjI0MDAyMDAyNDIwMDM3MDAzNTIwMDI0MjAwMzcwMzMwMjAwMjIwMDEyODAyMDAyMjAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyNDAyMDAyNDEyODZhMjAwMjQxMzA2YTIyMDU0MTAwNDEwNDEwOWIwMTIwMDIyODAyMjgyMDAyMjgwMjJjMjAwMjQxNDA2YjIyMDQ0MTA0MTA1NzIwMDI0MWM4MDA2YTQxMDAzYTAwMDAyMDAyNDIwMDM3MDM0MDIwMDIyMDAxMjgwMjA0MjIwMzQxMTg3NDIwMDM0MTgwZmUwMzcxNDEwODc0NzIyMDAzNDEwODc2NDE4MGZlMDM3MTIwMDM0MTE4NzY3MjcyMzYwMjRjMjAwMjQxMjA2YTIwMDQ0MTAwNDEwNDEwOWMwMTIwMDIyODAyMjAyMDAyMjgwMjI0MjAwMjQxY2MwMDZhMjIwNjQxMDQxMDU3MjAwMjIwMDE0MTA4NmEyODAyMDAyMjAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyNGMyMDAyNDExODZhMjAwNDQxMDQ0MTA4MTA5YzAxMjAwMjI4MDIxODIwMDIyODAyMWMyMDA2NDEwNDEwNTcyMDAyMjAwMTQxMGM2YTJkMDAwMDNhMDA0YzIwMDI0MTEwNmEyMDA0NDEwODQxMDkxMDljMDEyMDAyMjgwMjEwMjAwMjI4MDIxNDIwMDY0MTAxMTA1NzIwMDI0MTA4NmEyMDA1NDEwNDQxMGQxMDliMDEyMDAyMjgwMjA4MjAwMjI4MDIwYzIwMDQ0MTA5MTA1NzIwMDAyMDA1NDEwZDEwMGYxYTIwMDI0MWQwMDA2YTI0MDAwYjBmMDAyMDAwMjAwMTIwMDIyMDAzNDEwODEwZjkwMTBiYjUwMjAxMDY3ZjIwMDEyMDAzNDYwNDQwMjAwMTIyMDM0MTEwNGYwNDQwMjAwMDQxMDAyMDAwNmI0MTAzNzEyMjA0NmEyMTA1MjAwNDA0NDAyMDAyMjEwMTAzNDAyMDAwMjAwMTJkMDAwMDNhMDAwMDIwMDE0MTAxNmEyMTAxMjAwMDQxMDE2YTIyMDAyMDA1NDkwZDAwMGIwYjIwMDUyMDAzMjAwNDZiMjIwMzQxN2M3MTIyMDY2YTIxMDAwMjQwMjAwMjIwMDQ2YTIyMDQ0MTAzNzEwNDQwMjAwNjQxMDA0YzBkMDEyMDA0NDEwMzc0MjIwMTQxMTg3MTIxMDcyMDA0NDE3YzcxMjIwODQxMDQ2YTIxMDI0MTAwMjAwMTZiNDExODcxMjEwOTIwMDgyODAyMDAyMTAxMDM0MDIwMDUyMDAxMjAwNzc2MjAwMjI4MDIwMDIyMDEyMDA5NzQ3MjM2MDIwMDIwMDI0MTA0NmEyMTAyMjAwNTQxMDQ2YTIyMDUyMDAwNDkwZDAwMGIwYzAxMGIyMDA2NDEwMDRjMGQwMDIwMDQyMTAyMDM0MDIwMDUyMDAyMjgwMjAwMzYwMjAwMjAwMjQxMDQ2YTIxMDIyMDA1NDEwNDZhMjIwNTIwMDA0OTBkMDAwYjBiMjAwMzQxMDM3MTIxMDMyMDA0MjAwNjZhMjEwMjBiMjAwMzA0NDAyMDAwMjAwMzZhMjEwMTAzNDAyMDAwMjAwMjJkMDAwMDNhMDAwMDIwMDI0MTAxNmEyMTAyMjAwMDQxMDE2YTIyMDAyMDAxNDkwZDAwMGIwYjBmMGIxMDJjMDAwYmEyMDMwMTA3N2YyMzAwNDE0MDZhMjIwMTI0MDAyMDAwMTA0YjIxMDIxMDQzMjEwNTIwMDIxMDEyMjEwMDIwMDE0MTJjNmE0MTAwM2EwMDAwMjAwMTQxMjg2YTIwMDAzNjAyMDAyMDAxMjAwMjM2MDIyNDIwMDEyMDAwMzYwMjIwMjAwMTQxMDAzNjAyMWM0MTAwMjEwMjAzN2YyMDAwMjAwMjQ2MDQ3ZjIwMDEyZDAwMmMwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAxNDE0MDZiMjQwMDIwMDUwNTIwMDE0MTFjNmEyMjAwNDFhZDg3MDg0MTE4MTAzYTIxMDMyMDAwNDFhZDg3MDg0MTE4MTA1MjIxMDAxMDQzMjEwMjAzNDAyMDAwMDQ0MDIwMDE0MTFjNmEyMjA0NDFhZDg3MDg0MTE4MTA1MjIxMDYyMDA0NDFhZDg3MDg0MTE4MTA1MzIxMDcyMDA0NDFhZDg3MDg0MTE4MTAzYTIxMDQyMDAxMjAwNjM2MDIzODIwMDEyMDA0MzYwMjM0MjAwMTIwMDczNjAyMzAyMDAyMjAwMTQxMzA2YTEwNTkyMDAwNDEwMTZiMjEwMDBjMDEwYjBiMjAwMTQyMDAzNzAzMzAyMDAxMjAwMzQxMTg3NDIwMDM0MTgwZmUwMzcxNDEwODc0NzIyMDAzNDEwODc2NDE4MGZlMDM3MTIwMDM0MTE4NzY3MjcyMzYwMjNjMjAwMTQxMTA2YTIwMDE0MTMwNmEyMjAwNDEwMDQxMDQxMDU2MjAwMTI4MDIxMDIwMDEyODAyMTQyMDAxNDEzYzZhMjIwMzQxMDQxMDU3MjAwMTIwMDI0MTE4NzQyMDAyNDE4MGZlMDM3MTQxMDg3NDcyMjAwMjQxMDg3NjQxODBmZTAzNzEyMDAyNDExODc2NzI3MjM2MDIzYzIwMDE0MTA4NmEyMDAwNDEwNDQxMDgxMDU2MjAwMTI4MDIwODIwMDEyODAyMGMyMDAzNDEwNDEwNTcyMDA1MjAwMDQxMDgxMDBmMWEyMDAxMjgwMjFjMjEwMjIwMDEyODAyMjAyMTAwMGMwMTBiMGIwYmI4MDIwMTA0N2YyMzAwNDE0MDZhMjIwMjI0MDAyMDAyNDEyODZhNDEwMDM2MDIwMDIwMDI0MjAwMzcwMzIwMjAwMjIwMDEyODAyMDgyMjAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyMzAyMDAyNDExODZhMjAwMjQxMjA2YTIyMDU0MTAwNDEwNDEwOWEwMTIwMDIyODAyMTgyMDAyMjgwMjFjMjAwMjQxMzA2YTIyMDQ0MTA0MTA1NzIwMDI0MjAwMzcwMzMwMjAwMjIwMDEyODAyMDAyMjAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyM2MyMDAyNDExMDZhMjAwNDQxMDA0MTA0MTA1NjIwMDIyODAyMTAyMDAyMjgwMjE0MjAwMjQxM2M2YTIyMDM0MTA0MTA1NzIwMDIyMDAxMjgwMjA0MjIwMTQxMTg3NDIwMDE0MTgwZmUwMzcxNDEwODc0NzIyMDAxNDEwODc2NDE4MGZlMDM3MTIwMDE0MTE4NzY3MjcyMzYwMjNjMjAwMjQxMDg2YTIwMDQ0MTA0NDEwODEwNTYyMDAyMjgwMjA4MjAwMjI4MDIwYzIwMDM0MTA0MTA1NzIwMDIyMDA1NDEwNDQxMGMxMDlhMDEyMDAyMjgwMjAwMjAwMjI4MDIwNDIwMDQ0MTA4MTA1NzIwMDAyMDA1NDEwYzEwMGYxYTIwMDI0MTQwNmIyNDAwMGIxNDAwMTAxMzIwMDA0NjA0NDAwZjBiNDE5Mjg0MDg0MTE5MTAwMzAwMGIwOTAwMjAwMDEwNWMxMDA3MWEwYjFkMDAyMDAwMTBhNzAxMjIwMDEwMTI0MTIwNDcwNDQwNDFiMDg2MDg0MTEwMTA4ODAxMDAwYjIwMDAwYjBhMDAyMDAwMTBhNzAxMTAwNzFhMGIwODAwMjAwMDEwNWYxMDE0MGI2MTAyMDI3ZjAxN2UyMzAwNDExMDZiMjIwMTI0MDAyMDAxNDIwMDM3MDMwODIwMDAxMGE3MDEyMjAwMTAxMjIyMDI0MTA5NGYwNDQwNDE5NTg1MDg0MTBlMTA4ODAxMDAwYjIwMDEyMDAxNDEwODZhMjAwMjEwYjAwMTIwMDA0MTAwMjAwMTI4MDIwMDIyMDAyMDAxMjgwMjA0MjIwMjEwOGEwMTFhMjAwMDIwMDIxMGIxMDEyMDAxNDExMDZhMjQwMDBiMWYwMDIwMDAyMDAxMjAwMjEwMTUyMDAwMTA2MTQxZmYwMTcxMDQ0MDBmMGI0MWFiODQwODQxMzAxMDAzMDAwYjE1MDA0MTAyNDEwMTIwMDAxMDI3MjIwMDFiNDEwMDIwMDA0MTAwNGUxYjBiZjgwMTAxMDQ3ZjIzMDA0MWQwMDA2YjIyMDUyNDAwMjAwNTIwMDQzNjAyMjgyMDA1NDEyMDZhNDFkYjg0MDg0MTE0MTA2MzIwMDUyODAyMjAyMTA3MjAwNTI4MDIyNDIyMDYyMDAzMTA2NDIwMDQxMDY1MjEwMzEwNDMyMjA4MjAwM2FkMTA2NjIwMDYyMDA4MTA0ZTIwMDUyMDA0MTAxMjM2MDIzNDIwMDU0MTAwMzYwMjMwMjAwNTIwMDU0MTI4NmEzNjAyMmMwMzQwMjAwNTQxMzg2YTIwMDU0MTJjNmExMDY3MjAwNTI5MDMzODUwMDQ0MDIwMDUyMDA3MjAwNjIwMDEyMDAyMTA2ODIwMDUyODAyMDQyMTAxMjAwMDIwMDUyODAyMDAzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MWQwMDA2YTI0MDAwNTIwMDUyODAyNGMyMTAzMjAwNTQxMTg2YTIwMDcyMDA2MjAwNTI4MDI0ODEwNjkyMDA1NDExMDZhMjAwNTI4MDIxODIwMDUyODAyMWMyMDA1MjkwMzQwMTA2YTIwMDU0MTA4NmEyMDA1MjgwMjEwMjAwNTI4MDIxNDIwMDMxMDZiMjAwNTI4MDIwYzIxMDYyMDA1MjgwMjA4MjEwNzBjMDEwYjBiMGIxODAwMjAwMTIwMDIxMDRkMjEwMTIwMDAxMDQzMzYwMjA0MjAwMDIwMDEzNjAyMDAwYjEwMDAxMDQzMWEyMDAwMjAwMTI4MDIwMDEwMmYxMDRlMGIwOTAwMjAwMDEwMTI0MTA0NzYwYjM4MDEwMTdmMjMwMDQxMTA2YjIyMDIyNDAwMjAwMjQyMDAzNzAzMDgyMDAyMjAwMTQxMDAyMDAyNDEwODZhMTA4MjAxMjAwMDIwMDIyODAyMDAyMDAyMjgwMjA0MTAxODFhMjAwMjQxMTA2YTI0MDAwYmE3MDEwMjA1N2YwMTdlMjMwMDQxMjA2YjIyMDIyNDAwMjAwMDIwMDEyODAyMDQyMjA0NDExMDZhMjIwNTIwMDEyODAyMDg0ZDA0N2UyMDAxMjgwMjAwMjAwMjQxMTA2YTQyMDAzNzAzMDAyMDAyNDIwMDM3MDMwODI4MDIwMDIwMDQyMDAyNDEwODZhMjIwMzQxMTAxMDZmMWEyMDAyNDEwMDM2MDIxYzIwMDMyMDAyNDExYzZhMjIwNjEwOTgwMTIxMDQyMDAzMjAwNjEwOTkwMTIxMDcyMDAwNDExNDZhMjAwMjQxMDg2YTIwMDI0MTFjNmExMDk4MDEzNjAyMDAyMDAwNDExMDZhMjAwNDM2MDIwMDIwMDAyMDA3MzcwMzA4MjAwMTIwMDUzNjAyMDQ0MjAxMDU0MjAwMGIzNzAzMDAyMDAyNDEyMDZhMjQwMDBiOTEwMTAxMDM3ZjIzMDA0MTEwNmIyMjA1MjQwMDAyNDAyMDAzMTAxMjQ1MGQwMDIwMDIyMDAzMTA2ZTIwMDQxMDEyMjEwNjQxMDAyMTAzMDM0MDIwMDM0MTA0NmEyMjA3MjAwNjRiMGQwMTIwMDU0MTAwMzYwMjBjMjAwNDIwMDMyMDA1NDEwYzZhNDEwNDEwNmYxYTIwMDIyMDA1MjgwMjBjMjIwMzQxMTg3NDIwMDM0MTgwZmUwMzcxNDEwODc0NzIyMDAzNDEwODc2NDE4MGZlMDM3MTIwMDM0MTE4NzY3MjcyMTA2ZTIwMDcyMTAzMGMwMDBiMDAwYjIwMDAyMDAyMzYwMjA0MjAwMDIwMDEzNjAyMDAyMDA1NDExMDZhMjQwMDBiMTYwMDIwMDIyMDAzMTA2ZTIwMDAyMDAyMzYwMjA0MjAwMDIwMDEzNjAyMDAwYjIwMDEwMTdmMTA0MzIyMDQyMDAzMTA2NjIwMDIyMDA0MTA0ZTIwMDAyMDAyMzYwMjA0MjAwMDIwMDEzNjAyMDAwYjE2MDAyMDAzMjAwMjEwNzAyMDAwMjAwMjM2MDIwNDIwMDAyMDAxMzYwMjAwMGJhMzAxMDEwMjdmMjMwMDQxMzA2YjIyMDUyNDAwMjAwNTQxMjg2YTQxZWY4NDA4NDEwZjEwNjMyMDA1NDEyMDZhMjAwNTI4MDIyODIwMDUyODAyMmMyMDA0MjgwMjA4MTA2OTIwMDU0MTE4NmEyMDA1MjgwMjIwMjAwNTI4MDIyNDIwMDQyOTAzMDAxMDZhMjAwNTQxMTA2YTIwMDUyODAyMTgyMDA1MjgwMjFjMjAwNDI4MDIwYzEwNmIyMDA1MjgwMjEwMjEwNDIwMDUyODAyMTQyMTA2MTA0MzFhMjAwNjIwMDMxMDJmMTA0ZTIwMDU0MTA4NmEyMDA0MjAwNjIwMDEyMDAyMTA2ODIwMDUyODAyMGMyMTAxMjAwMDIwMDUyODAyMDgzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MTMwNmEyNDAwMGI3MTAxMDE3ZjIzMDA0MTIwNmIyMjA1MjQwMDIwMDU0MTE4NmE0MWZlODQwODQxMGMxMDYzMjAwNTQxMTA2YTIwMDUyODAyMTgyMDA1MjgwMjFjMjAwMzEwNjkyMDA1NDEwODZhMjAwNTI4MDIxMDIwMDUyODAyMTQyMDA0MTA2YjIwMDUyMDA1MjgwMjA4MjAwNTI4MDIwYzIwMDEyMDAyMTA2ODIwMDUyODAyMDQyMTAxMjAwMDIwMDUyODAyMDAzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MTIwNmEyNDAwMGIwZDAwMTA0MzFhMjAwMDIwMDExMDJmMTA0ZTBiMGQwMDIwMDAyMDAxMjAwMjIwMDMxMDhhMDEwYjBkMDAxMDQzMWEyMDAxMjAwMDEwM2QxMDRlMGIwZjAwMjAwMDQyN2Y1MTA0N2UxMDE2MDUyMDAwMGIwYjMwMDEwMTdlMjAwMDI5MDMwODIyMDE0MjdmNTEwNDdlMTAxNjA1MjAwMTBiMjAwMDI4MDIxMDIwMDAyODAyMTgyMDAwMjgwMjAwMjAwMDI4MDIwNDEwNDUxMDE3MTA3MzBiM2IwMTAyN2YyMzAwNDExMDZiMjIwMTI0MDAyMDAwMTAxMjIxMDIyMDAxNDEwMDM2MDIwYzIwMDEyMDAwMzYwMjA0MjAwMTIwMDI0MTAyNzYzNjAyMDgyMDAxNDEwNDZhMTA3NTEwM2IyMDAxNDExMDZhMjQwMDBiMjQwMDIwMDAyOTAzMDgxMDcxMjAwMDI4MDIxMDIwMDAyODAyMTgyMDAwMjgwMjAwMjAwMDI4MDIwNDEwNDUxMDE3MTAxMjFhMGI3ZDAxMDM3ZjIzMDA0MTEwNmIyMjAxMjQwMDIwMDAyODAyMDgyMTAzMjAwMTQxMDAzNjAyMGMyMDAwMjgwMjAwMjAwMzQxMDI3NDIwMDE0MTBjNmE0MTA0MTA2ZjQ1MDQ0MDIwMDEyODAyMGMyMTAyMjAwMDIwMDM0MTAxNmEzNjAyMDgyMDAyNDExODc0MjAwMjQxODBmZTAzNzE0MTA4NzQ3MjIwMDI0MTA4NzY0MTgwZmUwMzcxMjAwMjQxMTg3NjcyNzIxMDJmMjAwMTQxMTA2YTI0MDAwZjBiNDE4YTg1MDg0MTBiNDFlZjgzMDg0MTExMTA0YzAwMGI5MDAyMDIwMjdmMDE3ZTIzMDA0MWQwMDA2YjIyMDIyNDAwMjAwMTI5MDMwODIyMDQ0MjdmNTEwNDdlMTAxNjA1MjAwNDBiMjAwMTI4MDIxMDIwMDEyODAyMTgyMDAxMjgwMjAwMjAwMTI4MDIwNDEwNDUyMTAxMTAxNzIwMDExMDEyMjEwMzIwMDI0MTAwMzYwMjE0MjAwMjIwMDEzNjAyMGMyMDAyMjAwMzQxMDI3NjM2MDIxMDIwMDI0MTBjNmExMDc1MjIwMzEwMTIyMTAxMjAwMjQxM2M2YTQxMDAzYTAwMDAyMDAyNDEzODZhMjAwMTM2MDIwMDIwMDIyMDAzMzYwMjM0MjAwMjIwMDEzNjAyMzAyMDAyNDEwMDM2MDIyYzIwMDI0MTQwNmIyMDAyNDEyYzZhMTA3NzIwMDIyODAyMzAyMDAyMjgwMjJjNDYwNDQwMjAwMjQxMjA2YTIyMDEyMDAyNDFjODAwNmEyOTAzMDAzNzAzMDAyMDAyMjAwMjI5MDM0MDM3MDMxODIwMDIyZDAwM2MwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAwMjAwMjI5MDMxODM3MDMwMDIwMDA0MTA4NmEyMDAxMjkwMzAwMzcwMzAwMjAwMjQxZDAwMDZhMjQwMDBmMGI0MThhODUwODQxMGI0MTk1ODUwODQxMGUxMDRjMDAwYjMwMDIwMTdmMDE3ZTIwMDE0MThhODUwODQxMGIxMDNhMjEwMjIwMDExMGJlMDEyMTAzMjAwMDIwMDExMDM5MzYwMjBjMjAwMDIwMDIzNjAyMDgyMDAwMjAwMzM3MDMwMDBiMTAwMDEwNDMxYTIwMDAyMDAxMjgwMjAwMTAzZDEwNGUwYjBlMDAyMDAxNDUwNDQwMjAwMjIwMDAxMDcwMGIwYjgxMDEwMTA1N2YyMzAwNDExMDZiMjIwMzI0MDAxMDQzMTAyZjIxMDQyMDAxMjgwMjAwMTAxMjIxMDUwMzQwMjAwNTIwMDI0MTA0NmEyMjA2NGYwNDQwMjAwMzQxMDAzNjAyMGMyMDAxMjgwMjAwMjAwMjIwMDM0MTBjNmE0MTA0MTA2ZjFhMjAwMzI4MDIwYzIyMDI0MTE4NzQyMDAyNDE4MGZlMDM3MTQxMDg3NDcyMjAwMjQxMDg3NjQxODBmZTAzNzEyMDAyNDExODc2NzI3MjIwMDQxMDNmMjAwNjIxMDIwYzAxMGIwYjIwMDAyMDA0MTA0ZTIwMDM0MTEwNmEyNDAwMGI4MjAxMDEwNTdmMjMwMDQxMTA2YjIyMDMyNDAwMTA0MzEwMmYyMTA0MjAwMTI4MDIwMDEwMTIyMTA1MDM0MDIwMDUyMDAyNDEwNDZhMjIwNjRmMDQ0MDIwMDM0MTAwMzYwMjBjMjAwMTI4MDIwMDIwMDIyMDAzNDEwYzZhNDEwNDEwNmYxYTIwMDQyMDAzMjgwMjBjMjIwMjQxMTg3NDIwMDI0MTgwZmUwMzcxNDEwODc0NzIyMDAyNDEwODc2NDE4MGZlMDM3MTIwMDI0MTE4NzY3MjcyMTAwNTFhMjAwNjIxMDIwYzAxMGIwYjIwMDAyMDA0MTA0ZTIwMDM0MTEwNmEyNDAwMGI0ZDAxMDI3ZjIzMDA0MTIwNmIyMjAxMjQwMDEwN2QyMTAyMjAwMTQxMTA2YTIwMDA0MTEwNmEyOTAzMDAzNzAzMDAyMDAxNDEwODZhMjAwMDQxMDg2YTI5MDMwMDM3MDMwMDIwMDEyMDAyMzYwMjE4MjAwMTIwMDAyOTAzMDAzNzAzMDAyMDAxMTA3MjIwMDE0MTIwNmEyNDAwMGIwZTAxMDE3ZjEwMmEyMjAwNDIwMDEwMDEyMDAwMGI0ZjAxMDI3ZjIzMDA0MTIwNmIyMjAyMjQwMDEwN2QyMTAzMjAwMjQxMTA2YTIwMDE0MTEwNmEyOTAzMDAzNzAzMDAyMDAyNDEwODZhMjAwMTQxMDg2YTI5MDMwMDM3MDMwMDIwMDIyMDAzMzYwMjE4MjAwMjIwMDEyOTAzMDAzNzAzMDAyMDAwMjAwMjEwNzYyMDAyNDEyMDZhMjQwMDBiNGQwMTAyN2YyMzAwNDEyMDZiMjIwMTI0MDAxMDdkMjEwMjIwMDE0MTEwNmEyMDAwNDExMDZhMjkwMzAwMzcwMzAwMjAwMTQxMDg2YTIwMDA0MTA4NmEyOTAzMDAzNzAzMDAyMDAxMjAwMjM2MDIxODIwMDEyMDAwMjkwMzAwMzcwMzAwMjAwMTEwMzQyMDAxNDEyMDZhMjQwMDBiNzYwMjA1N2YwMTdlMjMwMDQxMTA2YjIyMDEyNDAwMTA3ZDIxMDIyMDAwMjgwMjEwMjEwMzIwMDAyODAyMDQyMTA0MjAwMDI4MDIwMDIxMDUyMDAwMjkwMzA4MjIwNjQyN2Y1MTA0N2UxMDE2MDUyMDA2MGIyMDAzMjAwMjIwMDUyMDA0MTA0NTIxMDAxMDE3MjAwMDEwMTIyMTAyMjAwMTQxMDAzNjAyMGMyMDAxMjAwMDM2MDIwNDIwMDEyMDAyNDEwMjc2MzYwMjA4MjAwMTQxMDQ2YTEwNzUxMDJmMjAwMTQxMTA2YTI0MDAwYjQ3MDEwMjdmMjMwMDQxMTA2YjIyMDIyNDAwMTA0MzIxMDMyMDAyNDIwMDM3MDMwODIwMDIyMDAxYWQ0MmZmMDE4MzQxMDEyMDAyNDEwODZhMTA4MjAxMjAwMzIwMDIyODAyMDAyMDAyMjgwMjA0MTAxODFhMjAwMDIwMDMxMDRlMjAwMjQxMTA2YTI0MDAwYjhmMDIwMjA0N2YwMTdlMjAwMzIwMDE0MjM4ODYyMDAxNDI4MGZlMDM4MzQyMjg4Njg0MjAwMTQyODA4MGZjMDc4MzQyMTg4NjIwMDE0MjgwODA4MGY4MGY4MzQyMDg4Njg0ODQyMDAxNDIwODg4NDI4MDgwODBmODBmODMyMDAxNDIxODg4NDI4MDgwZmMwNzgzODQyMDAxNDIzODg4MjIwODIwMDE0MjI4ODg0MjgwZmUwMzgzODQ4NDg0MzcwMDAwMDI0MDIwMDE1MDA0NDA0MWI4OGQwODIxMDMwYzAxMGIyMDAyMDQ0MDIwMDE0MjdmNTEwNDQwMjAwMzQxMDc2YTIxMDM0MTAxMjEwNDBjMDIwYjIwMDhhN2MwMjIwNTQxMDc3NTIxMDYyMDA1NDEwMDQ4MjEwNTBiMjAwNjQxZmYwMTcxMjEwNjAzNDAwMjQwMDI0MDIwMDQ0MTA4NDcwNDQwMjAwMzIwMDQ2YTJkMDAwMDIyMDcyMDA2NDYwZDAyMjAwMjQ1MjAwNzQxMDc3NjIwMDU0NjcyNDUwNDQwMjAwNDQxMDE2YjIyMDQ0MTA5NGYwZDAyMGIyMDAzMjAwNDZhMjEwMzQxMDgyMDA0NmIyMTA0MGMwNDBiMTAyYzAwMGIxMDJjMDAwYjIwMDQ0MTAxNmEyMTA0MGMwMDBiMDAwYjIwMDAyMDA0MzYwMjA0MjAwMDIwMDMzNjAyMDAwYmEzMDEwMjAzN2YwMTdlMjMwMDQxMTA2YjIyMDMyNDAwMDI3ZjIwMDIyOTAzMDA1MDA0NDAyMDAxMjgwMjEwMjEwNDIwMDMyMDAxMjgwMjAwMjAwMTI4MDIwNDIwMDIyODAyMDgyMDAyMjgwMjBjMTA2ZDIwMDMyODAyMDAyMTA1MjAwMzI4MDIwNDBjMDEwYjEwNDcyMTA0MjAwMzQxMDg2YTIwMDEyODAyMDAyMDAxMjgwMjA0MjAwMTI4MDIxMDIwMDIxMDZjMjAwMzI4MDIwODIxMDUyMDAzMjgwMjBjMGIyMTAyMjAwMTI5MDMwODIxMDYyMDAwMTA3ZDM2MDIxODIwMDAyMDA0MzYwMjEwMjAwMDIwMDYzNzAzMDgyMDAwMjAwMjM2MDIwNDIwMDAyMDA1MzYwMjAwMjAwMzQxMTA2YTI0MDAwYjNmMDEwMTdmMTA0MzIxMDMyMDAwMjAwMTI5MDMwMDM3MDMwMDIwMDA0MTEwNmEyMDAxNDExMDZhMjkwMzAwMzcwMzAwMjAwMDQxMDg2YTIwMDE0MTA4NmEyOTAzMDAzNzAzMDAyMDAzMjAwMjEwNDQyMDAwMjAwMzM2MDIxODBiNTIwMTAyN2YyMzAwNDExMDZiMjIwNDI0MDAyMDA0NDEwODZhMjAwMDI4MDIwODIwMDAyODAyMDAyMjA1MjAwMTEwODYwMTIwMDQyODAyMDg0MTAxNDYwNDQwMjAwNDI4MDIwYzIwMDAyMDAxMjAwNTZhMzYwMjAwMjAwNDQxMTA2YTI0MDAwZjBiMjAwMjIwMDM0MWEzODUwODQxMGYxMDRjMDAwYjFmMDAyMDAxMjAwMjIwMDMxMDA0MjIwMTEwMWYyMTAyMjAwMDIwMDEzNjAyMDQyMDAwMjAwMjQ1MzYwMjAwMGI0ZjAxMDM3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDI0MTA4NmEyMDAwMjgwMjA4MjAwMDI4MDIwMDIyMDMyMDAxMTA4NjAxMjAwMjI4MDIwODQxMDE0NjA0NDAyMDAyMjgwMjBjMjAwMDIwMDEyMDAzNmEzNjAyMDAyMDAyNDExMDZhMjQwMDBmMGI0MWEzODUwODQxMGYxMDg4MDEwMDBiMWEwMTAxN2Y0MWYxODUwODQxMTYxMDRkMjIwMjIwMDAyMDAxMTAwZjFhMjAwMjEwMDAwMDBiMTUwMDQxN2YyMDAwMjAwMTEwMTkyMjAwNDEwMDQ3MjAwMDQxMDA0ODFiMGIwZjAwMjAwMDIwMDEyMDAzMjAwMjEwMjg0MTAwNDcwYjA5MDAyMDAwMjAwMTEwMDUxYTBiMGMwMDIwMDAyMDAwMjAwMTEwMDIyMDAwMGIwYzAwMjAwMDIwMDAyMDAxMTAxYTIwMDAwYjBjMDAyMDAwMjAwMDIwMDExMDFiMjAwMDBiMGEwMDIwMDAyMDAwMjAwMTEwMDIwYjBjMDAyMDAwMjAwMDIwMDExMDYwMjAwMDBiMTAwMTAxN2YxMDJhMjIwMjIwMDAyMDAxMTAwMjIwMDIwYjEwMDEwMTdmMTAyYTIyMDIyMDAwMjAwMTEwMWIyMDAyMGIxMDAxMDE3ZjEwMmEyMjAyMjAwMDIwMDExMDYwMjAwMjBiMTkwMTAxN2YxMDJhMjEwMjQxNzIyMDAxYWQxMDAxMjAwMjIwMDA0MTcyMTAxZTIwMDIwYjBlMDEwMTdmMTA0MzIyMDEyMDAwMTA0NDIwMDEwYjRjMDEwMjdmMjMwMDQxMTA2YjIyMDEyNDAwMTA0MzIxMDIyMDAxMjAwMDQxMTg3NDIwMDA0MTgwZmUwMzcxNDEwODc0NzIyMDAwNDEwODc2NDE4MGZlMDM3MTIwMDA0MTE4NzY3MjcyMzYwMjBjMjAwMjIwMDE0MTBjNmE0MTA0MTAwZjFhMjAwMTQxMTA2YTI0MDAyMDAyMGI4NDAxMDIwNDdmMDE3ZTIzMDA0MTIwNmIyMjAyMjQwMDIwMDI0MTEwNmE0MjAwMzcwMzAwMjAwMjQyMDAzNzAzMDgyMDAxNDEwMDIwMDI0MTA4NmEyMjAzNDExMDEwNmYyMDAyNDEwMDM2MDIxYzIwMDMyMDAyNDExYzZhMjIwNDEwOTgwMTIxMDUyMDAzMjAwNDEwOTkwMTIxMDYyMDAyNDEwODZhMjAwMjQxMWM2YTEwOTgwMTIxMDMwNDQwNDFjMzg1MDg0MTFkMTAwMzAwMGIyMDAwMjAwMzM2MDIwYzIwMDAyMDA1MzYwMjA4MjAwMDIwMDYzNzAzMDAyMDAyNDEyMDZhMjQwMDBiNzQwMTAxN2YyMzAwNDExMDZiMjIwMjI0MDAyMDAyNDEwMDM2MDIwYzIwMDIyMDAwNDExMDIwMDEyODAyMDAyMjAwMjAwMDQxMDQ2YTIyMDAxMDlkMDEyMDAyNDEwYzZhNDEwNDIwMDIyODAyMDAyMDAyMjgwMjA0MTA1NzIwMDEyMDAwMzYwMjAwMjAwMjI4MDIwYzIxMDAyMDAyNDExMDZhMjQwMDIwMDA0MTE4NzQyMDAwNDE4MGZlMDM3MTQxMDg3NDcyMjAwMDQxMDg3NjQxODBmZTAzNzEyMDAwNDExODc2NzI3MjBiYTgwMTAyMDE3ZTAxN2YyMzAwNDExMDZiMjIwMzI0MDAyMDAzNDIwMDM3MDMwODIwMDMyMDAwNDExMDIwMDEyODAyMDAyMjAwMjAwMDQxMDg2YTIyMDAxMDlkMDEyMDAzNDEwODZhNDEwODIwMDMyODAyMDAyMDAzMjgwMjA0MTA1NzIwMDEyMDAwMzYwMjAwMjAwMzI5MDMwODIxMDIyMDAzNDExMDZhMjQwMDIwMDI0MjM4ODYyMDAyNDI4MGZlMDM4MzQyMjg4Njg0MjAwMjQyODA4MGZjMDc4MzQyMTg4NjIwMDI0MjgwODA4MGY4MGY4MzQyMDg4Njg0ODQyMDAyNDIwODg4NDI4MDgwODBmODBmODMyMDAyNDIxODg4NDI4MDgwZmMwNzgzODQyMDAyNDIyODg4NDI4MGZlMDM4MzIwMDI0MjM4ODg4NDg0ODQwYjBmMDAyMDAwMjAwMTIwMDIyMDAzNDEwYzEwZjkwMTBiMGYwMDIwMDAyMDAxMjAwMjIwMDM0MTBkMTBmOTAxMGIwZjAwMjAwMDIwMDEyMDAyMjAwMzQxMDkxMGY5MDEwYjJmMDAwMjQwMjAwMzIwMDQ0ZDA0NDAyMDAyMjAwNDQ5MGQwMTIwMDAyMDA0MjAwMzZiMzYwMjA0MjAwMDIwMDEyMDAzNmEzNjAyMDAwZjBiMTAyYzAwMGIxMDJjMDAwYmI0MDEwMTAzN2YyMzAwNDExMDZiMjIwNDI0MDAwMjdmMDI0MDIwMDAyZDAwMDg0NTA0NDAyMDAwMjgwMjAwMjIwNTEwMTIyMjA2NDE5MGNlMDA0YjBkMDE0MWUwZGIwODJkMDAwMDBkMDE0MWRjZGIwODIwMDYzNjAyMDA0MWUwZGIwODQxMDEzYTAwMDAyMDA0NDEwODZhMjAwNjEwOWYwMTIwMDU0MTAwMjAwNDI4MDIwODIwMDQyODAyMGMxMDZmMWEyMDAwNDEwMTNhMDAwODBiNDEwMTIwMDEyMDAzNmEyMjAwNDFkY2RiMDgyODAyMDA0YjBkMDExYTIwMDQyMDAxMjAwMDEwYTAwMTIwMDIyMDAzMjAwNDI4MDIwMDIwMDQyODAyMDQxMDU3NDEwMDBjMDEwYjIwMDA0MTAwM2EwMDA4MjAwNTIwMDEyMDAyMjAwMzEwNmYwYjIwMDQ0MTEwNmEyNDAwMGIzZTAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDI0MTA4NmE0MWNjOGQwODQxOTBjZTAwMjAwMTEwZDAwMTIwMDIyODAyMGMyMTAxMjAwMDIwMDIyODAyMDgzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDI0MTEwNmEyNDAwMGIzMjAwMDI0MDIwMDEyMDAyNGQwNDQwMjAwMjQxOTBjZTAwNGQwZDAxMTAyYzAwMGIxMDJjMDAwYjIwMDAyMDAyMjAwMTZiMzYwMjA0MjAwMDIwMDE0MWNjOGQwODZhMzYwMjAwMGIxOTAwMjAwMDQxZmVmZmZmZmYwNzQ2MDQ0MDQxZTA4NTA4NDEwZDEwMDMwMDBiMjAwMDBiNGQwMTAxN2YyMzAwNDExMDZiMjIwMTI0MDAyMDAwMTAxMjQxMDQ0NjA0NDAyMDAxNDEwMDM2MDIwYzIwMDA0MTAwMjAwMTQxMGM2YTQxMDQxMDhhMDExYTQxZmVmZmZmZmYwNzIwMDAyMDAxMjgwMjBjNDFjNThlYjFhMjA0NDYxYjIxMDAwYjIwMDE0MTEwNmEyNDAwMjAwMDBiODAwMTAxMDI3ZjIzMDA0MTEwNmIyMjAzMjQwMDAyNDAwMjQwMjAwMDJkMDAwNDA0NDA0MTkwY2UwMDQxZGNkYjA4MjgwMjAwMjIwNDZiMjAwMjQ5MGQwMTIwMDM0MTA4NmEyMDA0MjAwMjIwMDQ2YTIyMDAxMGE0MDEyMDAzMjgwMjA4MjAwMzI4MDIwYzIwMDEyMDAyMTA1NzQxZGNkYjA4MjAwMDM2MDIwMDBjMDIwYjIwMDAyODAyMDAyMDAxMjAwMjEwMGYxYTBjMDEwYjIwMDAxMGE1MDEyMDAwMjgwMjAwMjAwMTIwMDIxMDBmMWEwYjIwMDM0MTEwNmEyNDAwMGIzZjAxMDE3ZjIzMDA0MTEwNmIyMjAzMjQwMDIwMDM0MTA4NmEyMDAxMjAwMjQxY2M4ZDA4NDE5MGNlMDAxMDJiMjAwMzI4MDIwYzIxMDEyMDAwMjAwMzI4MDIwODM2MDIwMDIwMDAyMDAxMzYwMjA0MjAwMzQxMTA2YTI0MDAwYjU4MDEwMjdmMjMwMDQxMTA2YjIyMDEyNDAwMjAwMDJkMDAwNDIwMDA0MTAwM2EwMDA0MDQ0MDIwMDE0MTA4NmE0MTAwNDFkY2RiMDgyODAyMDAxMGEwMDEyMDAwMjgwMjAwMjAwMTI4MDIwODIwMDEyODAyMGMxMDBmMWE0MWRjZGIwODQxMDAzNjAyMDA0MWUwZGIwODQxMDAzYTAwMDAwYjIwMDE0MTEwNmEyNDAwMGIwZDAwMjAwMDQxNjcxMDIwMWE0MTY3MTAxMjBiMGQwMDIwMDAxMDJhMjIwMDEwMjAxYTIwMDAwYjEyMDAyMDAwMTBhNjAxNDUwNDQwMjAwMDIwMDExMDIxMWEwYjBiMTIwMDIwMDAxMGE2MDE0NTA0NDAyMDAwMjAwMTEwYWEwMTBiMGIzODAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDI0MjAwMzcwMzA4MjAwMjIwMDE0MTAwMjAwMjQxMDg2YTEwODIwMTIwMDAyMDAyMjgwMjAwMjAwMjI4MDIwNDEwYjgwMTIwMDI0MTEwNmEyNDAwMGIwYTAwMjAwMDEwYTcwMTEwYTIwMTBiYjkwMTAxMDQ3ZjIzMDA0MTIwNmIyMjAxMjQwMDIwMDAxMGE3MDEyMTAyMTA0MzIxMDQyMDAyMTAxMjIxMDAyMDAxNDExMDZhNDEwMDNhMDAwMDIwMDE0MTBjNmEyMDAwMzYwMjAwMjAwMTIwMDIzNjAyMDgyMDAxMjAwMDM2MDIwNDIwMDE0MTAwMzYwMjAwMDM3ZjIwMDAyMDAzNDYwNDdmMjAwMTJkMDAxMDA0NDA0MWRjZGIwODQxMDAzNjAyMDA0MWUwZGIwODQxMDAzYTAwMDAwYjIwMDE0MTIwNmEyNDAwMjAwNDA1MjAwMTEwYWQwMTIxMDAyMDAxMTBhZTAxMjEwMjIwMDExMGFmMDEyMTAzMjAwMTIwMDAzNjAyMWMyMDAxMjAwMzM2MDIxODIwMDEyMDAyMzYwMjE0MjAwNDIwMDE0MTE0NmExMDU5MjAwMTI4MDIwMDIxMDMyMDAxMjgwMjA0MjEwMDBjMDEwYjBiMGIzMzAyMDE3ZjAxN2UyMzAwNDExMDZiMjIwMTI0MDAyMDAxNDEwMDM2MDIwYzIwMDAyMDAxNDEwYzZhMjIwMDQxMDQxMGIzMDEyMDAwNDEwNDEwYjEwMTIwMDE0MTEwNmEyNDAwYTcwYjA5MDAyMDAwNDEyMDEwODcwMTBiMGMwMDIwMDAyMDAwMTBhZDAxMTA4NzAxMGIzYTAxMDE3ZjIzMDA0MTEwNmIyMjAzMjQwMDIwMDM0MTA4NmEyMDAxNDEwODIwMDIxMGQwMDEyMDAzMjgwMjBjMjEwMTIwMDAyMDAzMjgwMjA4MzYwMjAwMjAwMDIwMDEzNjAyMDQyMDAzNDExMDZhMjQwMDBiMzQwMTAxN2UwMjQwMjAwMTQ1MGQwMDAzNDAyMDAxNDUwZDAxMjAwMTQxMDE2YjIxMDEyMDAwMzEwMDAwMjAwMjQyMDg4Njg0MjEwMjIwMDA0MTAxNmEyMTAwMGMwMDBiMDAwYjIwMDIwYmZkMDEwMTA2N2YyMzAwNDEzMDZiMjIwMTI0MDAyMDAwMTBhNzAxMjEwMjEwNDMyMTA0MjAwMjEwMTIyMTAwMjAwMTQxMTg2YTQxMDAzYTAwMDAyMDAxNDExNDZhMjAwMDM2MDIwMDIwMDEyMDAyMzYwMjEwMjAwMTIwMDAzNjAyMGMyMDAxNDEwMDM2MDIwODAzN2YyMDAwMjAwMzQ2MDQ3ZjIwMDEyZDAwMTgwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAxNDEzMDZhMjQwMDIwMDQwNTIwMDE0MTA4NmEyMjAyMTBhZDAxMjEwMzIwMDIxMGFlMDEyMTA1MjAwMjEwYWYwMTIxMDY0MTAwMjEwMDIwMDE0MTAwM2EwMDJmMjAwMjIwMDE0MTJmNmE0MTAxMTBiMzAxMDI0MDAyNDAwMjQwMjAwMTJkMDAyZjBlMDIwMjAxMDAwYjQxZWQ4NjA4NDEwZDEwODgwMTAwMGI0MTAxMjEwMDBiMjAwMTIwMDAzYTAwMjgyMDAxMjAwNjM2MDIyNDIwMDEyMDA1MzYwMjIwMjAwMTIwMDMzNjAyMWMyMDA0MjAwMTQxMWM2YTEwNTUyMDAxMjgwMjA4MjEwMzIwMDEyODAyMGMyMTAwMGMwMTBiMGIwYjJkMDAyMDAwNDEwODZhMjAwMDI4MDIwMDIwMDEyMDAyMTA5ZTAxMDQ0MDQxYTM4NTA4NDEwZjEwODgwMTAwMGIyMDAwMjAwMDI4MDIwMDIwMDI2YTM2MDIwMDBiODcwMTAxMDE3ZjIzMDA0MTMwNmIyMjAyMjQwMDIwMDIyMDAxMzYwMjA4MjAwMjEwMzUyMDAyMjAwMjJkMDAwNDNhMDAxMDIwMDIyMDAyMjgwMjAwMzYwMjBjMjAwMjIwMDExMDEyMzYwMjFjMjAwMjQxMDAzNjAyMTgyMDAyMjAwMjQxMDg2YTM2MDIxNDAzNDAyMDAyNDEyMDZhMjAwMjQxMTQ2YTEwYjUwMTIwMDIyZDAwMmM0MTAyNDY0NTA0NDAyMDAyNDEyMDZhMjAwMjQxMGM2YTEwYjYwMTBjMDEwYjBiMjAwMDIwMDIyODAyMGMyMDAyMmQwMDEwMTBiNzAxMjAwMjQxMzA2YTI0MDAwYmM1MDMwMTA3N2YyMzAwNDFkMDAwNmIyMjAyMjQwMDAyNDAyMDAxMjgwMjA0MjIwNDQxMGQ2YTIyMDgyMDAxMjgwMjA4NGQwNDQwMjAwMTI4MDIwMDIwMDI0MjAwMzcwMDM1MjAwMjQyMDAzNzAzMzAyODAyMDAyMDA0MjAwMjQxMzA2YTIyMDM0MTBkMTA2ZjFhMjAwMjQxMDAzNjAyNDAyMDAyNDEyODZhMjAwMzQxMDA0MTA0MTBiZjAxMjAwMjQxNDA2YjIyMDU0MTA0MjAwMjI4MDIyODIwMDIyODAyMmMxMDU3MjAwMjI4MDI0MDIxMDQyMDAyNDFjODAwNmE0MTAwM2EwMDAwMjAwMjQyMDAzNzAzNDAyMDAyNDEyMDZhMjAwMzQxMDQ0MTBkMTBiZjAxMjAwNTQxMDkyMDAyMjgwMjIwMjAwMjI4MDIyNDEwNTcyMDAyNDEwMDM2MDI0YzIwMDI0MTE4NmEyMDA1NDEwMDQxMDQxMGMwMDEyMDAyNDFjYzAwNmEyMjA3NDEwNDIwMDIyODAyMTgyMDAyMjgwMjFjMTA1NzIwMDIyODAyNGMyMTAzMjAwMjQxMDAzNjAyNGMyMDAyNDExMDZhMjAwNTQxMDQ0MTA4MTBjMDAxMjAwNzQxMDQyMDAyMjgwMjEwMjAwMjI4MDIxNDEwNTcyMDAyMjgwMjRjMjEwNjIwMDI0MTAwM2EwMDRjMjAwMjQxMDg2YTIwMDU0MTA4NDEwOTEwYzAwMTIwMDc0MTAxMjAwMjI4MDIwODIwMDIyODAyMGMxMDU3MjAwMDIwMDIyZDAwNGM0MTAwNDczYTAwMGMyMDAwMjAwNjQxMTg3NDIwMDY0MTgwZmUwMzcxNDEwODc0NzIyMDA2NDEwODc2NDE4MGZlMDM3MTIwMDY0MTE4NzY3MjcyMzYwMjA4MjAwMDIwMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIwNDIwMDAyMDA0NDExODc0MjAwNDQxODBmZTAzNzE0MTA4NzQ3MjIwMDQ0MTA4NzY0MTgwZmUwMzcxMjAwNDQxMTg3NjcyNzIzNjAyMDAyMDAxMjAwODM2MDIwNDBjMDEwYjIwMDA0MTAyM2EwMDBjMGIyMDAyNDFkMDAwNmEyNDAwMGI0ZDAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDAyODAyMDAyMDAxMTBiYzAxMjAwMTIwMDAyODAyMDQxMGJkMDEyMDAwNDEwODZhMjgwMjAwMjAwMTEwM2UyMDAyMjAwMDQxMGM2YTJkMDAwMDNhMDAwZjIwMDEyMDAyNDEwZjZhNDEwMTEwYTMwMTIwMDI0MTEwNmEyNDAwMGIwZDAwMjAwMDIwMDEyMDAyMTAzODEwMjExYTBiMGQwMDIwMDAyMDAxMjAwMjEwNGQxMDIxMWEwYjg3MDEwMTAxN2YyMzAwNDEzMDZiMjIwMjI0MDAyMDAyMjAwMTM2MDIwODIwMDIxMDM1MjAwMjIwMDIyZDAwMDQzYTAwMTAyMDAyMjAwMjI4MDIwMDM2MDIwYzIwMDIyMDAxMTAxMjM2MDIxYzIwMDI0MTAwMzYwMjE4MjAwMjIwMDI0MTA4NmEzNjAyMTQyMDAyNDEyNDZhMjEwMTAzNDAyMDAyNDEyMDZhMjAwMjQxMTQ2YTEwYmEwMTIwMDIyODAyMjAwNDQwMjAwMTIwMDI0MTBjNmExMGJiMDEwYzAxMGIwYjIwMDAyMDAyMjgwMjBjMjAwMjJkMDAxMDEwYjcwMTIwMDI0MTMwNmEyNDAwMGI4OTAzMDEwNjdmMjMwMDQxNDA2YTIyMDIyNDAwMjAwMDIwMDEyODAyMDQyMjAzNDEwYzZhMjIwNjIwMDEyODAyMDg0ZDA0N2YyMDAxMjgwMjAwMjAwMjQxMjg2YTQxMDAzNjAyMDAyMDAyNDIwMDM3MDMyMDI4MDIwMDIwMDMyMDAyNDEyMDZhMjIwMzQxMGMxMDZmMWEyMDAyNDEwMDM2MDIzMDIwMDI0MTE4NmEyMDAzNDEwMDQxMDQxMGMxMDEyMDAyNDEzMDZhMjIwNTQxMDQyMDAyMjgwMjE4MjAwMjI4MDIxYzEwNTcyMDAyMjgwMjMwMjEwNDIwMDI0MjAwMzcwMzMwMjAwMjQxMTA2YTIwMDM0MTA0NDEwYzEwYzEwMTIwMDU0MTA4MjAwMjI4MDIxMDIwMDIyODAyMTQxMDU3MjAwMjQxMDAzNjAyM2MyMDAyNDEwODZhMjAwNTQxMDA0MTA0MTBjMjAxMjAwMjQxM2M2YTIyMDc0MTA0MjAwMjI4MDIwODIwMDIyODAyMGMxMDU3MjAwMjI4MDIzYzIxMDMyMDAyNDEwMDM2MDIzYzIwMDIyMDA1NDEwNDQxMDgxMGMyMDEyMDA3NDEwNDIwMDIyODAyMDAyMDAyMjgwMjA0MTA1NzIwMDIyODAyM2MyMTA1MjAwMDQxMGM2YTIwMDQ0MTE4NzQyMDA0NDE4MGZlMDM3MTQxMDg3NDcyMjAwNDQxMDg3NjQxODBmZTAzNzEyMDA0NDExODc2NzI3MjM2MDIwMDIwMDAyMDAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIzNjAyMDQyMDAxMjAwNjM2MDIwNDIwMDA0MTA4NmEyMDA1NDExODc0MjAwNTQxODBmZTAzNzE0MTA4NzQ3MjIwMDU0MTA4NzY0MTgwZmUwMzcxMjAwNTQxMTg3NjcyNzIzNjAyMDA0MTAxMDU0MTAwMGIzNjAyMDAyMDAyNDE0MDZiMjQwMDBiMWYwMDIwMDAyODAyMDgyMDAxMTBiYzAxMjAwMTIwMDAyODAyMDAxMGJkMDEyMDAwMjgwMjA0MjAwMTEwM2UwYjQ2MDEwMTdmMjMwMDQxMTA2YjIyMDIyNDAwMjAwMjIwMDA0MTE4NzQyMDAwNDE4MGZlMDM3MTQxMDg3NDcyMjAwMDQxMDg3NjQxODBmZTAzNzEyMDAwNDExODc2NzI3MjM2MDIwYzIwMDEyMDAyNDEwYzZhNDEwNDEwYTMwMTIwMDI0MTEwNmEyNDAwMGI4MTAxMDEwMzdmMjMwMDQxMTA2YjIyMDIyNDAwMDI0MDAyNDAyMDAwMmQwMDA0MDQ0MDIwMDExMDEyMjIwNDQxOTBjZTAwNDFkY2RiMDgyODAyMDAyMjAzNmI0YjBkMDEyMDAyNDEwODZhMjAwMzIwMDMyMDA0NmEyMjAwMTBhNDAxMjAwMTQxMDAyMDAyMjgwMjA4MjAwMjI4MDIwYzEwNmYxYTQxZGNkYjA4MjAwMDM2MDIwMDBjMDIwYjIwMDAyODAyMDAyMDAxMTA4YjAxMGMwMTBiMjAwMDEwYTUwMTIwMDAyODAyMDAyMDAxMTA4YjAxMGIyMDAyNDExMDZhMjQwMDBiMzgwMjAxN2YwMTdlMjMwMDQxMTA2YjIyMDEyNDAwMjAwMTQyMDAzNzAzMDgyMDAwMjAwMTQxMDg2YTIyMDA0MTA4NDE4YTg1MDg0MTBiMTBjNTAxMjAwMDQxMDgxMGIxMDEyMDAxNDExMDZhMjQwMDBiMGYwMDIwMDAyMDAxMjAwMjIwMDM0MTBkMTBmODAxMGIwZjAwMjAwMDIwMDEyMDAyMjAwMzQxMDkxMGY4MDEwYjBmMDAyMDAwMjAwMTIwMDIyMDAzNDEwYzEwZjgwMTBiMGYwMDIwMDAyMDAxMjAwMjIwMDM0MTA4MTBmODAxMGI4MDAyMDEwNTdmMjMwMDQxMjA2YjIyMDIyNDAwMjAwMDIwMDEyODAyMDQyMjAzNDEwODZhMjIwNTIwMDEyODAyMDg0ZDA0N2YyMDAxMjgwMjAwMjAwMjQyMDAzNzAzMTAyODAyMDAyMDAzMjAwMjQxMTA2YTIyMDM0MTA4MTA2ZjFhMjAwMjQxMDAzNjAyMWMyMDAyNDEwODZhMjAwMzQxMDA0MTA0MTBjMjAxMjAwMjQxMWM2YTIyMDY0MTA0MjAwMjI4MDIwODIwMDIyODAyMGMxMDU3MjAwMjI4MDIxYzIxMDQyMDAyNDEwMDM2MDIxYzIwMDIyMDAzNDEwNDQxMDgxMGMyMDEyMDA2NDEwNDIwMDIyODAyMDAyMDAyMjgwMjA0MTA1NzIwMDIyODAyMWMyMTAzMjAwMDIwMDQ0MTE4NzQyMDA0NDE4MGZlMDM3MTQxMDg3NDcyMjAwNDQxMDg3NjQxODBmZTAzNzEyMDA0NDExODc2NzI3MjM2MDIwNDIwMDEyMDA1MzYwMjA0MjAwMDQxMDg2YTIwMDM0MTE4NzQyMDAzNDE4MGZlMDM3MTQxMDg3NDcyMjAwMzQxMDg3NjQxODBmZTAzNzEyMDAzNDExODc2NzI3MjM2MDIwMDQxMDEwNTQxMDAwYjM2MDIwMDIwMDI0MTIwNmEyNDAwMGI4YTAxMDEwNDdmMjMwMDQxMTA2YjIyMDMyNDAwMjAwMTI4MDIwNDIyMDI0MTA0NmEyMjA0MjAwMTI4MDIwODRiMDQ3ZjQxMDAwNTIwMDEyODAyMDAyMDAzNDEwMDM2MDIwYzI4MDIwMDIwMDIyMDAzNDEwYzZhNDEwNDEwNmYxYTIwMDMyODAyMGMyMTAyMjAwMTIwMDQzNjAyMDQyMDAyNDExODc0MjAwMjQxODBmZTAzNzE0MTA4NzQ3MjIwMDI0MTA4NzY0MTgwZmUwMzcxMjAwMjQxMTg3NjcyNzIyMTAyNDEwMTBiMjEwMTIwMDAyMDAyMzYwMjA0MjAwMDIwMDEzNjAyMDAyMDAzNDExMDZhMjQwMDBiMzAwMDIwMDA0MTA4NmEyMDAwMjgwMjAwMjAwMTIwMDIxMDllMDEwNDQwMjAwMzIwMDQ0MWEzODUwODQxMGYxMDRjMDAwYjIwMDAyMDAwMjgwMjAwMjAwMjZhMzYwMjAwMGI3ODAxMDE3ZjIzMDA0MTEwNmIyMjAyMjQwMDIwMDIyMDAwNDIzODg2MjAwMDQyODBmZTAzODM0MjI4ODY4NDIwMDA0MjgwODBmYzA3ODM0MjE4ODYyMDAwNDI4MDgwODBmODBmODM0MjA4ODY4NDg0MjAwMDQyMDg4ODQyODA4MDgwZjgwZjgzMjAwMDQyMTg4ODQyODA4MGZjMDc4Mzg0MjAwMDQyMjg4ODQyODBmZTAzODMyMDAwNDIzODg4ODQ4NDg0MzcwMzA4MjAwMTIwMDI0MTA4NmE0MTA4MTBhMzAxMjAwMjQxMTA2YTI0MDAwYmQ2MDEwMTA2N2YyMzAwNDE0MDZhMjIwMDI0MDAxMGM4MDExMDVjMjEwMTIwMDAxMGM5MDExMDVjMzYwMjA4MjAwMDEwNDczNjAyMGMyMDAwNDEyODZhMjIwMjIwMDExMDMyNDFmNzgwMDg0MTEwMTAzMzIwMDAyODAyMmMyMjAxMjAwMDQxMDg2YTEwNjQyMDAxMjAwMDQxMGM2YTEwNjQyMDAwNDEyMDZhMjIwMTIwMDA0MTM4NmEyMjAzMjkwMzAwMzcwMzAwMjAwMDQxMTg2YTIyMDQyMDAwNDEzMDZhMjIwNTI5MDMwMDM3MDMwMDIwMDAyMDAwMjkwMzI4MzcwMzEwMjAwMDIwMDA0MTEwNmExMDdjMzYwMjA0MjAwMjEwYzkwMTEwNWMxMDMyNDFmNTgxMDg0MTE4MTAzMzIwMDAyODAyMmMyMDAwNDEwNDZhMTA3ODIwMDEyMDAzMjkwMzAwMzcwMzAwMjAwNDIwMDUyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDMyODM3MDMxMDIwMDA0MTEwNmExMDdjMjAwMDQxNDA2YjI0MDAwYjBhMDA0MTk1ODgwODQxMTIxMDRkMGIwYTAwNDE4MTg4MDg0MTE0MTA0ZDBiYTkwMzAyMDU3ZjAxN2UyMzAwNDE4MDAxNmIyMjAyMjQwMDEwY2IwMTEwYWIwMTIxMDMyMDAxMjgwMjBjMjEwNDIwMDEyOTAzMDAyMTA3MjAwMTI4MDIwODIxMDEwMjQwMjAwMzQxZmVmZmZmZmYwNzQ2MDQ0MDIwMDE0MWZlZmZmZmZmMDc0NjBkMDEyMDAxMTBhMTAxMjEwMTIwMDIyMDA0MzYwMjE0MjAwMjIwMDczNzAzMDgyMDAyMjAwMTM2MDIxMDEwY2MwMTEwNWMyMTAzMjAwNDEwMjkyMTA0MjAwMjQxZTAwMDZhMjIwMTIwMDMxMDMyNDFhMTgwMDg0MTBhMTAzMzIwMDI0MTQwNmIyMjAzMjAwMTIwMDI0MTA4NmExMDg0MDEyMDAxMjAwMzEwY2QwMTIwMDExMDM0NDIwMDIxMDc0MWZlZmZmZmZmMDcyMTAxMGIyMDAyNDFlMDAwNmEyMDAwMTAzMjQxYzA4MTA4NDExMjEwMzMyMDAyMjgwMjY0MWEyMDAyNDEyODZhMjIwMDIwMDI0MWYwMDA2YTIyMDUyOTAzMDAzNzAzMDAyMDAyNDEyMDZhMjIwMzIwMDI0MWU4MDA2YTIyMDYyOTAzMDAzNzAzMDAyMDAyMjAwMjI5MDM2MDM3MDMxODAyNDAyMDAxNDFmZWZmZmZmZjA3NDcwNDQwMjAwNTIwMDAyOTAzMDAzNzAzMDAyMDA2MjAwMzI5MDMwMDM3MDMwMDIwMDIyMDAyMjkwMzE4MzcwMzYwMjAwMjEwN2QzNjAyNzgyMDAxMTBhMTAxMjEwMDIwMDIyMDA0MzYwMjNjMjAwMjIwMDczNzAzMzAyMDAyMjAwMDM2MDIzODIwMDI0MTQwNmIyMDAyNDFlMDAwNmEyMDAyNDEzMDZhMTA4MzAxMGMwMTBiMjAwMjQxZDAwMDZhMjAwMDI5MDMwMDM3MDMwMDIwMDI0MWM4MDA2YTIwMDMyOTAzMDAzNzAzMDAyMDAyMjAwMjI5MDMxODM3MDM0MDIwMDIyMDA0MzYwMjU4MGIyMDAyNDFlMDAwNmEyMDAyNDE0MDZiMTA3NjIwMDI0MTgwMDE2YTI0MDAwZjBiNDFjYTg4MDg0MTFmMTA0MTAwMGIwYTAwNDFlODhjMDg0MTIyMTA0ZDBiMGEwMDQxZmE4NjA4NDExZDEwNGQwYmZmMDIwMjAzN2YwMjdlMjMwMDQxZDAwMDZiMjIwMjI0MDAyMDAyNDEzMDZhMjIwNDIwMDE0MTEwNmEyOTAzMDAzNzAzMDAyMDAyNDEyODZhMjIwMzIwMDE0MTA4NmEyOTAzMDAzNzAzMDAyMDAyMjAwMTI5MDMwMDM3MDMyMDIwMDIxMDdkMzYwMjM4MDI0MDAyNDAwMjQwMDI0MDIwMDEyODAyMTgyMjAxMTA2NTBlMDIwMTAyMDAwYjEwNDcyMTAzMjAwMjQxMDg2YTIwMDIyODAyMjAyMDAyMjgwMjI0MjAwNDIwMDExMDYyMjAwMjI5MDMwODIxMDUyMDAyMjkwMzI4MjEwNjIwMDAxMDdkMzYwMjE4MjAwMDIwMDMzNjAyMTAyMDAwMjAwNjM3MDMwODIwMDAyMDA1MzcwMzAwMGMwMjBiMjAwMDIwMDIyOTAzMjAzNzAzMDAyMDAwNDExODZhMjAwMjQxMzg2YTI5MDMwMDM3MDMwMDIwMDA0MTEwNmEyMDA0MjkwMzAwMzcwMzAwMjAwMDQxMDg2YTIwMDMyOTAzMDAzNzAzMDAwYzAxMGIyMDAyNDE0MDZiMjAwMTEwOTcwMTAyN2YyMDAyMjkwMzQwNTAwNDQwMjAwMjI4MDIzMDIxMDEyMDAyNDExMDZhMjAwMjI4MDIyMDIwMDIyODAyMjQyMDAyMjgwMjQ4MjAwMjI4MDI0YzEwNmQyMDAyMjgwMjEwMjEwMzIwMDIyODAyMTQwYzAxMGIxMDQ3MjEwMTIwMDI0MTE4NmEyMDAyMjgwMjIwMjAwMjI4MDIyNDIwMDIyODAyMzAyMDAyNDE0MDZiMTA2YzIwMDIyODAyMTgyMTAzMjAwMjI4MDIxYzBiMjEwNDIwMDIyOTAzMjgyMTA1MjAwMDEwN2QzNjAyMTgyMDAwMjAwMTM2MDIxMDIwMDAyMDA1MzcwMzA4MjAwMDIwMDQzNjAyMDQyMDAwMjAwMzM2MDIwMDBiMjAwMjQxZDAwMDZhMjQwMDBiMGQwMDIwMDAxMDYxNDFmZjAxNzE0MTAxNGIwYjE3MDAyMDAwMjgwMjAwMjAwMTI4MDIwMDEwODkwMTQxZmYwMTcxNDFmZjAxNDYwYjNiMDEwMTdmMjMwMDQxMTA2YjIyMDQyNDAwMjAwNDQxMDg2YTQxMDAyMDAzMjAwMTIwMDIxMDJiMjAwNDI4MDIwYzIxMDEyMDAwMjAwNDI4MDIwODM2MDIwMDIwMDAyMDAxMzYwMjA0MjAwNDQxMTA2YTI0MDAwYjBhMDA0MWJkODgwODQxMGQxMDRkMGIwYTAwNDFmMjg3MDg0MTBmMTA0ZDBiMGEwMDQxZGQ4NzA4NDExNTEwNGQwYjBhMDA0MWE3ODgwODQxMTYxMDRkMGIxOTAxMDE3ZjQxOTc4NzA4NDExNjEwNGQyMTAxMjAwMDI4MDIwMDIwMDExMDQwMjAwMTBiMTkwMTAxN2Y0MWFkODcwODQxMTgxMDRkMjEwMTIwMDAyODAyMDAyMDAxMTA0MDIwMDEwYjBhMDA0MWM1ODcwODQxMTgxMDRkMGIwYTAwNDE4ZjhjMDg0MTFkMTA0ZDBiMGEwMDQxYWM4YzA4NDExZDEwNGQwYjBhMDA0MWM5OGMwODQxMWYxMDRkMGJhNzA1MDIwZDdmMDI3ZTIzMDA0MTQwNmEyMjAwMjQwMDEwMjI0MTBhMTA1YTQxMDA0MWJkODgwODQxMGQxMDUwMjEwOTQxMDExMDRiMjEwMjQxMDI0MTk1ODgwODQxMTIxMDUwMjEwYTQxMDM0MTgxODgwODQxMTQxMDUwMjEwNTQxMDQ0MWYyODcwODQxMGYxMDUwMjEwNjQxMDUxMDExMjEwZDQxMDYxMDExMjEwZTQxMDcxMDU4MjEwNzQxMDgxMDUxMjEwODQxMDk0MWZhODYwODQxMWQxMDUwMjEwNDIwMDAyMDA4MzYwMjEwMjAwMDIwMDczNjAyMGMyMDA1MTAyZjEwMzIyMTAxNDFlNjgxMDg0MTBmMTA0ZDIxMDMxMDQzMjEwYjEwN2QyMTBjMTAxNjIwMDEyMDBjMjAwMzIwMGIxMDQ1MjEwMTEwMTcyMDAxMTAxMjIxMDMyMDAwNDEwMDM2MDIzMDIwMDAyMDAxMzYwMjI4MjAwMDIwMDM0MTAyNzYzNjAyMmMyMDAwNDEyODZhMjIwMzEwNzUxMDJmMTBhMjAxMjEwMTIwMDMyMDA0MTAyZjEwMmYxMDMyNDFhYjgwMDg0MTE1MTAzMzIwMDMxMDgwMDEyMTAzMDI0MDAyNDAyMDAxNDFmZWZmZmZmZjA3NDcwNDQwMjAwMTEwMmYxMGExMDEyMDAyMTAzMDBkMDE0MWU5ODgwODQxZDEwMDEwNDEwMDBiMjAwMjIwMDMxMDMwNDUwZDAxMGIxMGNjMDEyMDA0MTBhODAxMTBkOTAxMjAwMzEwYTgwMTAyNDAxMGNiMDEyMjA0MTBhNjAxMGQwMDIwMDE0MWZlZmZmZmZmMDc0NzA0NDAyMDA0MjAwMTEwMjExYTBjMDEwYjIwMDQ0MWVkODUwODQxMDQxMGI4MDEwYjEwZDEwMTIwMDkxMGE4MDExMGQ0MDEyMDAyMTBhODAxMTBjODAxMjAwYTEwYTgwMTEwYzkwMTIwMDUxMDJmMTBhODAxMTBkODAxMjAwMDQxMjg2YTIyMDEyMDA1MTAzMjQxYjY4MTA4NDEwYTEwMzMyMDAxMTA4MDAxMTBhODAxMTBkMjAxMjAwNjEwMmYxMGE4MDExMGRhMDEyMDAxMjAwNjEwMzI0MTg2ODMwODQxMGYxMDMzMjAwMTEwODAwMTEwYTgwMTIwMDAyMDA3MTAxMjM2MDIxYzIwMDA0MTAwMzYwMjE4MjAwMDIwMDA0MTBjNmEzNjAyMTQwMzQwMDI0MDIwMDA0MTI4NmEyMDAwNDExNDZhMTBjMzAxMjAwMDI4MDIyODQ1MDQ0MDIwMDAyMDA4MTAxMjM2MDIxYzIwMDA0MTAwMzYwMjE4MjAwMDIwMDA0MTEwNmEzNjAyMTQwMzQwMjAwMDQxMjg2YTIwMDA0MTE0NmExMGMzMDEyMDAwMjgwMjI4NDUwZDAyMjAwMDIwMDAyODAyMzAyMjAxMzYwMjI0MjAwMDIwMDAyODAyMmMzNjAyMjAyMDAwNDEyMDZhMTBkNTAxMjIwMjEwYTYwMTBkMDAyMDAyMjAwMTEwYjQwMTBjMDAwYjAwMGIyMDAwMjAwMDI4MDIzMDIyMDEzNjAyMjQyMDAwMjAwMDI4MDIyYzM2MDIyMDIwMDA0MTIwNmExMGQ2MDEyMjAyMTBhNjAxMGQwMTIwMDIyMDAxMTBiOTAxMGMwMTBiMGIxMGQzMDEyMDBkMTBhOTAxMTBkNzAxMjAwZTEwYTkwMTIwMDA0MTQwNmIyNDAwMGYwYjQxYmE4OTA4NDFjODAwMTA0MTAwMGIwODAwMTAyMjQxMDAxMDVhMGJjNzAxMDEwNTdmMjMwMDQxMzA2YjIyMDAyNDAwNDEwMDEwNWEwMjQwMDI0MDEwNDYxMGQxMDExMDVjMTAzMDA0NDAxMDQ2MTBkMTAxMTA1YzEwMzA0NTBkMDEyMDAwMTA0YTIyMDEzNjAyMDgxMGQ0MDExMGE3MDEyMTAyMTBjOTAxMTA1YzIxMDMyMDAwMjAwMTEwMTIzNjAyMTQyMDAwNDEwMDM2MDIxMDIwMDAyMDAwNDEwODZhMzYwMjBjMjAwMDQxMjA2YTIxMDEwMzQwMDI0MDIwMDA0MTE4NmEyMDAwNDEwYzZhMTA2NzIwMDAyOTAzMTg1MDBkMDAyMDAwMjgwMjJjMjAwMDI4MDIyODIwMDIxMDMwNDUwZDA0MTBjZTAxNDUwZDA0MjAwMzEwMmYyMDAxMTBjYTAxMGMwMTBiMGIyMDAwNDEzMDZhMjQwMDBmMGI0MTgyOGEwODQxMTYxMDQxMDAwYjQxODI4YTA4NDExNjEwNDEwMDBiNDE5ODhhMDg0MTBkMTA0MTAwMGJjNzA3MDIwOTdmMDE3ZTIzMDA0MTgwMDE2YjIyMDAyNDAwMTAyMjQxMDExMDVhMjAwMDEwNGYzNjAyMmMxMGQxMDExMDVjMjEwMTAyNDAwMjQwMDI0MDEwNDYyMjA3MjAwMTEwMzAwNDQwMjAwMDEwYzkwMTEwNWMyMjAxMzYwMjM0MjAwMDQxZTAwMDZhMjIwMjIwMDExMDJmMTAzMjQxOGQ4MjA4NDExODEwMzMyMDAwMjgwMjY0MjAwMDQxMmM2YTEwNzgyMDAwNDFkODAwNmEyMjAxMjAwMDQxZjAwMDZhMjIwNjI5MDMwMDM3MDMwMDIwMDA0MWQwMDA2YTIyMDMyMDAwNDFlODAwNmEyMjA0MjkwMzAwMzcwMzAwMjAwMDIwMDAyOTAzNjAzNzAzNDgyMDAwNDFjODAwNmEyMjA1MTA3YzIxMDgyMDAyMTBjODAxMTA1YzEwMzI0MWUxODAwODQxMGExMDMzMjAwMDI4MDI2NDIyMDIyMDAwNDEzNDZhMTA2NDIwMDI0MTAwMjAwODEwNzkyMDAxMjAwNjI5MDMwMDM3MDMwMDIwMDMyMDA0MjkwMzAwMzcwMzAwMjAwMDIwMDAyOTAzNjAzNzAzNDgyMDAwNDEzODZhMjAwNTEwN2UyMDAwMjgwMjQ0MTBjZTAxNDUwZDAxMjAwMDI4MDIzNDEwMzIyMTAxNDFhNTgyMDg0MTA2MTA0ZDIxMDQxMDQzMjIwMzQxMDEyMDAwMTA3OTEwNDMyMjAyMjAwMDQxMzg2YTEwNDQyMDAwMjAwMTM2MDI3MDIwMDA0MjdmMzcwMzY4MjAwMDIwMDMzNjAyNjQyMDAwMjAwNDM2MDI2MDIwMDAxMDdkMjIwNTM2MDI3ODAyNDAwMjQwMDI0MDAyNDAyMDAyMTA2NTBlMDIwMjAwMDEwYjIwMDA0MWM4MDA2YTIwMDIxMDk3MDEwMjdmMjAwMDI5MDM0ODUwMDQ0MDIwMDA0MTE4NmEyMDA0MjAwMzIwMDAyODAyNTAyMDAwMjgwMjU0MTA2ZDIwMDAyODAyMTgyMTA0MjAwMDI4MDIxYzBjMDEwYjEwNDcyMDAwNDEyMDZhMjAwNDIwMDMyMDAxMjAwMDQxYzgwMDZhMTA2YzIwMDAyODAyMjAyMTA0MjEwMTIwMDAyODAyMjQwYjIxMDMxMDdkMjEwNTBjMDEwYjEwNDcyMTAxMjAwMDQxMTA2YTIwMDQyMDAzMjAwNjIwMDIxMDYyMjAwMDI5MDM2ODIxMDkyMDAwMjgwMjE0MjEwMzIwMDAyODAyMTAyMTA0MTA3ZDIxMDUyMDA5NDI3ZjUyMGQwMTBiMTAxNjIxMDkwYjIwMDkyMDAxMjAwNTIwMDQyMDAzMTA0NTIxMDExMDE3MjAwMTEwMTIyMTAyMjAwMDQxMDAzNjAyNTAyMDAwMjAwMTM2MDI0ODIwMDAyMDAyNDEwMjc2MzYwMjRjMjAwMDQxYzgwMDZhMTA3NTIyMDIxMDEyMjEwMTIwMDA0MWYwMDA2YTQxMDAzYTAwMDAyMDAwNDFlYzAwNmEyMDAxMzYwMjAwMjAwMDIwMDIzNjAyNjgyMDAwMjAwMTM2MDI2NDIwMDA0MTAwMzYwMjYwMjAwMDQxZTAwMDZhMjIwMTQxOGE4NTA4NDEwYjEwM2ExMGEyMDEyMTAyMjAwMTEwYmUwMTIxMDkyMDAxMTAzOTIxMDEyMDAwMjgwMjY0MjAwMDI4MDI2MDQ3MGQwMjIwMDAyZDAwNzAwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIwMjQwMjAwMjQxZmVmZmZmZmYwNzQ3MDQ0MDIwMDIxMGExMDEyMTAzMGMwMTBiMTBkOTAxMTBhNzAxMjEwMzEwY2MwMTEwNWMyMDAxMTAyOTEwMzE0MjAwMjEwOTBiMjAwMTEwY2UwMTQ1MGQwMzIwMDcyMDAzMjAwOTIwMDExMDQyMjAwMDIwMDEzNjAyNmMyMDAwMjAwMzM2MDI2ODIwMDAyMDA5MzcwMzYwMjAwMDIwMDA0MWUwMDA2YTEwOTUwMTIyMDEzNjAyMzAyMDAwNDEwODZhMTAzNTIwMDAyMDAwMmQwMDBjM2EwMDNjMjAwMDIwMDAyODAyMDgzNjAyMzgyMDAwMjAwMTEwMTIzNjAyNTAyMDAwNDEwMDM2MDI0YzIwMDAyMDAwNDEzMDZhMzYwMjQ4MDM0MDIwMDA0MWUwMDA2YTIwMDA0MWM4MDA2YTEwNjcyMDAwMjkwMzYwNTA0NTA0NDAyMDAwMjgwMjc0MjAwMDI4MDI3MDIwMDA0MTM4NmEyMjAxMTAzZTIwMDAyOTAzNjgyMDAxMTBjNjAxMjAwMTEwM2MwYzAxMGIwYjIwMDAyODAyMzgyMDAwMmQwMDNjMTAzNzIwMDA0MTgwMDE2YTI0MDAwZjBiNDE4MjhhMDg0MTE2MTA0MTAwMGI0MWU3OGEwODQxMWYxMDQxMDAwYjQxOGE4NTA4NDEwYjQxOTU4NTA4NDEwZTEwNGMwMDBiNDE4NjhiMDg0MTFhMTA0MTAwMGJmMzFkMDIxNjdmMDI3ZTIzMDA0MWEwMDI2YjIyMDAyNDAwMTAyMjQxMDAxMDVhMTBjODAxMTA1YzIxMDEyMDAwMTBjOTAxMTA1YzIyMTQxMDJmMTA5NjAxMzYwMmYwMDEyMDAwMTA0MzM2MDJhMDAxMjAwMDQxODAwMjZhMjIwOTIwMDExMDMyNDFlYjgwMDg0MTBjMTAzMzIwMDAyODAyODQwMjIyMDE0MTAwMTA4MTAxMjAwMTQxMDExMDgxMDEyMDAxNDEwMDEwODEwMTIwMDEyMDAwNDFmMDAxNmEyMjExMTA3YjIwMDEyMDAwNDFhMDAxNmEyMjA3MTA3YjIwMDA0MWUwMDE2YTIyMDUyMDAwNDE5MDAyNmEyMjA0MjkwMzAwMzcwMzAwMjAwMDQxZDgwMTZhMjIwMjIwMDA0MTg4MDI2YTIyMDMyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDEyMDAwNDFkMDAxNmEyMjA2MTA3ZjEwZDIwMTEwNWMyMTAxMjAwMDIwMTQxMDJmMTA5NjAxMzYwMmYwMDEyMDAwMTA0MzM2MDJhMDAxMjAwOTIwMDExMDMyNDFlYjgwMDg0MTBjMTAzMzIwMDAyODAyODQwMjIyMDE0MTAwMTA4MTAxMjAwMTIwMTExMDdiMjAwMTIwMDcxMDdiMjAwMTQxMDEyMDAwMTA3OTIwMDUyMDA0MjkwMzAwMzcwMzAwMjAwMjIwMDMyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDEyMDA2MTA3ZjEwMmEyMjAzMTAyYTIyMDYxMDIzMjAwNjEwY2UwMTA0NDAxMGNjMDExMDVjMjAwNjEwMjkxMDMxMTBkOTAxMTBhNzAxMjEwMTIwMDAyMDA2MzYwMjhjMDIyMDAwNDIwMDM3MDM4MDAyMjAwMDIwMDEzNjAyODgwMjIwMDMyMDAwNDE4MDAyNmExMDQ0MGIyMDAwMjAwMzM2MDI5MDAxMDI0MDAyNDAwMjQwMjAwMzEwNjUwNDQwMTBkNDAxMTBhNzAxMjEwZTEwN2QyMTBkMjAwMDIwMDAyODAyOTAwMTEwMTIzNjAyOWMwMTIwMDA0MTAwMzYwMjk4MDEyMDAwMjAwMDQxOTAwMTZhMzYwMjk0MDEyMDAwNDE5MDAyNmEyMTBhMjAwMDQxYzAwMTZhMjEwZjIwMDA0MWE4MDE2YTIxMTUwMzQwMjAwMDQxYTAwMTZhMjAwMDQxOTQwMTZhMTA2NzIwMDAyOTAzYTAwMTUwMDQ0MDQyODA4MDkwYmJiYWQ2YWRmMDBkMTAyZTIxMDEyMDBkMTBkMzAxMTA1ZjEwMmUxMDkyMDEyMDAxMTA4ZDAxMjIwNTIwMGQxMGQ3MDExMDVmMTAyZTEwOTIwMTIwMDExMDhkMDEyMjA2MTA5MTAxMjAwZDEwODkwMTQxZmYwMTcxNDEwMjQ5MGQwNTIwMGQyMDA1MTA5MzAxMjAwNjEwOTAwMTIxMDIyMDBlMTAyZjIxMDEyMDAwMjAwMjEwMjkzNjAyOGMwMjIwMDA0MjAwMzcwMzgwMDIyMDAwMjAwMTM2MDI4ODAyMjAxNDIwMDA0MTgwMDI2YTEwY2EwMTIwMGUxMDJmMjEwMTIwMDUxMGNlMDEwNDQwMTA0NjIwMDE0MjAwMjAwNTEwNDIwYjIwMDYxMGNlMDEwNDQwMTA0ODIwMGU0MjAwMjAwNjEwNDIwYjEwNDMyMTA0MTA0MzEwMmYyMTA2MjAwMTQxZmVmZmZmZmYwNzQ2MGQwMzIwMDEyMDA2MTA0MDBjMDQwYjIwMGYyMDE1NDEwODZhMjkwMzAwMzcwMzAwMjAwMDIwMTUyOTAzMDAzNzAzYjgwMTIwMGYxMGQ2MDExMGFjMDEyMTEyMjAwZjEwZDUwMTEwYjIwMTIxMTMyMDBmMjgwMjAwMjEwYzIwMDAyODAyYzQwMTIxMDQyMDAwMjkwM2I4MDEyMTE2MjAxMjEwMTIyMTAxMjAxMzEwMTI0MTBkNmUyMDAxNDEwYzZlNmEyMTExNDEwMDIxMDEwMzQwMDI0MDAyNDAyMDAxMjAxMTQ3MDQ0MDIwMDE0MTAxNmEyMTA2NDEwMDIxMDIyMDEyMTAxMjIxMDUwMjQwMDI0MDAzNDAyMDAyNDEwYzZhMjIwMzIwMDU0YjBkMDEyMDAwNDE4ODAyNmEyMjA5NDEwMDM2MDIwMDIwMDA0MjAwMzcwMzgwMDIyMDEyMjAwMjIwMDA0MTgwMDI2YTIyMDI0MTBjMTA4YTAxMWEyMDAwNDEwMDM2MDJkMDAxMjAwMDQxODgwMTZhMjAwMjQxMDA0MTA0MTBjMTAxMjAwMDQxZDAwMTZhMjIwNzQxMDQyMDAwMjgwMjg4MDEyMDAwMjgwMjhjMDExMDU3MjAwMDI4MDJkMDAxMjEwODIwMDA0MjAwMzcwM2QwMDEyMDAwNDE4MDAxNmEyMDAyNDEwNDQxMGMxMGMxMDEyMDA3NDEwODIwMDAyODAyODAwMTIwMDAyODAyODQwMTEwNTcyMDAwNDEwMDM2MDJmMDAxMjAwMDQxZjgwMDZhMjAwNzQxMDA0MTA0MTBjMjAxMjAwMDQxZjAwMTZhMjIwMjQxMDQyMDAwMjgwMjc4MjAwMDI4MDI3YzEwNTcyMDAwMjgwMmYwMDEyMTBiMjAwMDQxMDAzNjAyZjAwMTIwMDA0MWYwMDA2YTIwMDc0MTA0NDEwODEwYzIwMTIwMDI0MTA0MjAwMDI4MDI3MDIwMDAyODAyNzQxMDU3MjAwMzIxMDIyMDA4NDExODc0MjAwODQxODBmZTAzNzE0MTA4NzQ3MjIwMDg0MTA4NzY0MTgwZmUwMzcxMjAwODQxMTg3NjcyNzIyMDAxNDcwZDAwMGIyMDAwMjgwMmYwMDEyMTAzMjAwYjQxMTg3NDIwMGI0MTgwZmUwMzcxNDEwODc0NzIyMDBiNDEwODc2NDE4MGZlMDM3MTIwMGI0MTE4NzY3MjcyMTAyZjIxMDEyMDAzNDExODc0MjAwMzQxODBmZTAzNzE0MTA4NzQ3MjIwMDM0MTA4NzY0MTgwZmUwMzcxMjAwMzQxMTg3NjcyNzIyMjA3MTAyZjIxMDU0MTAxMTAyZDIwMDA0MTgwMDI2YTIyMDMyMDAxMTAzMjQxZDk4NjA4NDExNDEwMzMyMDAwMjgwMjg0MDIyMjAxMjAwNTEwNmUyMDAxMTA3MDIwMDA0MWUwMDE2YTIyMDIyMDBhMjkwMzAwMzcwMzAwMjAwMDQxZDgwMTZhMjIwMTIwMDkyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDExMDQzMjEwNTIwMDAyMDA0MzYwMjhjMDIyMDAwMjAwYzM2MDI4ODAyMjAwMDIwMTYzNzAzODAwMjIwMDUyMDAzMTA0NDIwMGEyMDAyMjkwMzAwMzcwMzAwMjAwOTIwMDEyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDNkMDAxMzcwMzgwMDIyMDAwMTA3ZDM2MDI5ODAyMDI0MDAyNDAwMjQwMDI0MDIwMDUxMDY1MGUwMjAxMDIwMDBiMTA0NzIxMDEyMDAwNDFlODAwNmEyMDAwMjgwMjgwMDIyMDAwMjgwMjg0MDIyMDBhMjAwNTEwNjIyMDAwMjkwMzY4MjExNzIwMDAyOTAzODgwMjIxMTYyMDAwMTA3ZDM2MDJlODAxMjAwMDIwMDEzNjAyZTAwMTIwMDAyMDE2MzcwM2Q4MDEyMDAwMjAxNzM3MDNkMDAxMGMwMjBiMjAwMDQxZTgwMTZhMjAwMDQxOTgwMjZhMjkwMzAwMzcwMzAwMjAwMjIwMGEyOTAzMDAzNzAzMDAyMDAxMjAwOTI5MDMwMDM3MDMwMDIwMDAyMDAwMjkwMzgwMDIzNzAzZDAwMTBjMDEwYjIwMDA0MWYwMDE2YTIyMDEyMDA1MTA5NzAxMjAwMDQxZDAwMTZhMjAwMDQxODAwMjZhMjAwMTEwODMwMTBiMjAwMDQxODAwMjZhMjAwMDQxZDAwMTZhMTA3NjIwMDAyODAyODgwMjIyMGMyMDA3MTAzMDQ1MGQwMTIwMDAyODAyOGMwMjIxMDQyMDAwMjkwMzgwMDIyMTE2MjAwNjIxMDEwYzA1MGI0MTAwMjEwMjIwMTMxMDEyMjEwNTAzNDAyMDAyNDEwZDZhMjIwMzIwMDU0YjBkMDMyMDAwNDIwMDM3MDA4NTAyMjAwMDQyMDAzNzAzODAwMjIwMTMyMDAyMjAwMDQxODAwMjZhMjIwMjQxMGQxMDhhMDExYTIwMDA0MTAwMzYwMmQwMDEyMDAwNDFlMDAwNmEyMDAyNDEwMDQxMDQxMGJmMDEyMDAwNDFkMDAxNmEyMjA4NDEwNDIwMDAyODAyNjAyMDAwMjgwMjY0MTA1NzIwMDAyODAyZDAwMTIxMDkyMDAwNDFkODAxNmEyMjBiNDEwMDNhMDAwMDIwMDA0MjAwMzcwM2QwMDEyMDAwNDFkODAwNmEyMDAyNDEwNDQxMGQxMGJmMDEyMDA4NDEwOTIwMDAyODAyNTgyMDAwMjgwMjVjMTA1NzIwMDA0MTAwMzYwMmYwMDEyMDAwNDFkMDAwNmEyMDA4NDEwMDQxMDQxMGMwMDEyMDAwNDFmMDAxNmEyMjAyNDEwNDIwMDAyODAyNTAyMDAwMjgwMjU0MTA1NzIwMDAyODAyZjAwMTIxMTAyMDAwNDEwMDM2MDJmMDAxMjAwMDQxYzgwMDZhMjAwODQxMDQ0MTA4MTBjMDAxMjAwMjQxMDQyMDAwMjgwMjQ4MjAwMDI4MDI0YzEwNTcyMDAwMjgwMmYwMDEyMTA3MjAwMDQxMDAzYTAwZjAwMTIwMDA0MTQwNmIyMDA4NDEwODQxMDkxMGMwMDEyMDAyNDEwMTIwMDAyODAyNDAyMDAwMjgwMjQ0MTA1NzIwMDMyMTAyMjAwOTQxMTg3NDIwMDk0MTgwZmUwMzcxNDEwODc0NzIyMDA5NDEwODc2NDE4MGZlMDM3MTIwMDk0MTE4NzY3MjcyMjAwMTQ3MGQwMDBiMjAwMDJkMDBmMDAxMjAwNzQxMTg3NDIwMDc0MTgwZmUwMzcxNDEwODc0NzIyMDA3NDEwODc2NDE4MGZlMDM3MTIwMDc0MTE4NzY3MjcyMjEwODIwMGMxMDJmMjEwOTIwMDQxMDI5MjEwNzIwMTA0MTE4NzQyMDEwNDE4MGZlMDM3MTQxMDg3NDcyMjAxMDQxMDg3NjQxODBmZTAzNzEyMDEwNDExODc2NzI3MjEwMmYyMTA1NDUwNDQwNDEwMTEwMmQyMDAwNDE4MDAyNmEyMjAxMjAwNTEwMzI0MWE4ODYwODQxMDgxMDMzMjAwMDI4MDI4NDAyMTA3MDIwMDA0MWUwMDE2YTIyMDIyMDBhMjkwMzAwMzcwMzAwMjAwYjIwMDA0MTg4MDI2YTIyMDMyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDExMDQzMjEwNDIwMDAyMDA3MzYwMjhjMDIyMDAwMjAwOTM2MDI4ODAyMjAwMDIwMTYzNzAzODAwMjIwMDQyMDAxMTA0NDIwMGEyMDAyMjkwMzAwMzcwMzAwMjAwMzIwMGIyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDNkMDAxMzcwMzgwMDIyMDAwMTA3ZDM2MDI5ODAyMDI0MDAyNDAwMjQwMDI0MDIwMDQxMDY1MGUwMjAxMDIwMDBiMTA0NzIxMDEyMDAwNDExMDZhMjAwMDI4MDI4MDAyMjAwMDI4MDI4NDAyMjAwYTIwMDQxMDYyMjAwMDI5MDMxMDIxMTcyMDAwMjkwMzg4MDIyMTE2MjAwMDEwN2QzNjAyZTgwMTIwMDAyMDAxMzYwMmUwMDEyMDAwMjAxNjM3MDNkODAxMjAwMDIwMTczNzAzZDAwMTBjMDIwYjIwMDA0MWU4MDE2YTIwMDA0MTk4MDI2YTI5MDMwMDM3MDMwMDIwMDIyMDBhMjkwMzAwMzcwMzAwMjAwYjIwMDMyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDM4MDAyMzcwM2QwMDEwYzAxMGIyMDAwNDFmMDAxNmEyMDA0MTA5NzAxMDI3ZjIwMDAyOTAzZjAwMTUwMDQ0MDIwMDAyODAyOTAwMjIxMDMyMDAwNDExODZhMjAwMDI4MDI4MDAyMjAwMDI4MDI4NDAyMjAwMDI4MDJmODAxMjAwMDI4MDJmYzAxMTA2ZDIwMDAyODAyMWMyMTAyMjAwMDI4MDIxODBjMDEwYjEwNDcyMTAzMjAwMDQxMjA2YTIwMDAyODAyODAwMjIwMDAyODAyODQwMjIwMDAyODAyOTAwMjIwMDA0MWYwMDE2YTEwNmMyMDAwMjgwMjI0MjEwMjIwMDAyODAyMjAwYjIxMDEyMDAwMjkwMzg4MDIyMTE2MjAwMDEwN2QzNjAyZTgwMTIwMDAyMDAzMzYwMmUwMDEyMDAwMjAxNjM3MDNkODAxMjAwMDIwMDIzNjAyZDQwMTIwMDAyMDAxMzYwMmQwMDEwYjIwMDA0MWQwMDE2YTEwNzIyMTAzMjAwODEwMmYyMTAxMjAwMDIwMDMzNjAyOGMwMjIwMDA0MjAwMzcwMzgwMDIyMDAwMjAwMTM2MDI4ODAyMjAwMDQxODAwMjZhMTA5NTAxMjEwMTBjMDQwYjIwMDgxMDJmMjEwNDQxMDExMDJkMjAwNTEwMzIyMTAzNDFhODg2MDg0MTA4MTA0ZDIxMDExMDQzMjIwNTIwMDQxMDZlMjAwNTEwNzAxMDQzMjEwNDIwMDAyMDA3MzYwMjhjMDIyMDAwMjAwOTM2MDI4ODAyMjAwMDIwMTYzNzAzODAwMjIwMDQyMDAwNDE4MDAyNmExMDQ0MjAwMDIwMDMzNjAyOTAwMjIwMDA0MjdmMzcwMzg4MDIyMDAwMjAwNTM2MDI4NDAyMjAwMDIwMDEzNjAyODAwMjIwMDAxMDdkMzYwMjk4MDIwMjdmMDI3ZTAyNDAwMjQwMDI0MDIwMDQxMDY1MGUwMjAxMDIwMDBiMTA0NzIxMDIyMDAwNDEyODZhMjAwMDI4MDI4MDAyMjAwMDI4MDI4NDAyMjAwYTIwMDQxMDYyMjAwMDI4MDIyYzIxMDMyMDAwMjgwMjI4MjEwMTIwMDAyOTAzODgwMjBjMDIwYjIwMDAyODAyOTAwMjIxMDIyMDAwMjkwMzg4MDIyMTE2MjAwMDI4MDI4NDAyMjEwMzIwMDAyODAyODAwMjIxMDEyMDAwMjgwMjk4MDIwYzAyMGIyMDAwNDFkMDAxNmEyMDA0MTA5NzAxMDI3ZjIwMDAyOTAzZDAwMTUwMDQ0MDIwMDAyODAyOTAwMjIxMDIyMDAwNDEzMDZhMjAwMDI4MDI4MDAyMjAwMDI4MDI4NDAyMjAwMDI4MDJkODAxMjAwMDI4MDJkYzAxMTA2ZDIwMDAyODAyMzQyMTAzMjAwMDI4MDIzMDBjMDEwYjEwNDcyMTAyMjAwMDQxMzg2YTIwMDAyODAyODAwMjIwMDAyODAyODQwMjIwMDAyODAyOTAwMjIwMDA0MWQwMDE2YTEwNmMyMDAwMjgwMjNjMjEwMzIwMDAyODAyMzgwYjIxMDEyMDAwMjkwMzg4MDIwYjIxMTYxMDdkMGIyMTA0MjAxNjQyN2Y1MTA0N2UxMDE2MDUyMDE2MGIyMDAyMjAwNDIwMDEyMDAzMTA0NTIxMDMxMDE3NDEwMDIxMDIyMDAzMTAxMjIxMDEyMDAwNDEwMDM2MDJmODAxMjAwMDIwMDMzNjAyZjAwMTIwMDAyMDAxNDEwMjc2MzYwMmY0MDEyMDAwNDFmMDAxNmExMDc1MTAyZjIxMDQxMDQzMjEwMTIwMDQxMDEyMjEwMzIwMDA0MTAwM2EwMDkwMDIyMDAwMjAwMzM2MDI4YzAyMjAwMDIwMDQzNjAyODgwMjIwMDAyMDAzMzYwMjg0MDIyMDAwNDEwMDM2MDI4MDAyMDM0MDIwMDIyMDAzNDYwNDQwMjAwMDJkMDA5MDAyNDUwZDA1NDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGMwNTA1MjAwMDQxZDAwMTZhMjIwMzIwMDA0MTgwMDI2YTEwNzcyMDAxMjAwMzEwNDQyMDAwMjgwMjgwMDIyMTAyMjAwMDI4MDI4NDAyMjEwMzBjMDEwYjAwMGIwMDBiNDFjMDg2MDg0MTE5MTA0MTAwMGIyMDBjMjAwZTEwMzAwNDQwMjAwZDIwMDQxMDhmMDEwYzA0MGI0MWQ0OGEwODQxMTMxMDQxMDAwYjIwMDA0MTA4NmExMDM2MjAwMDIwMDAyZDAwMGMzYTAwODQwMjIwMDAyMDAwMjgwMjA4MzYwMjgwMDIyMDAwNDE4MDAyNmEyMjA2NDE4MDgwMDg0MTIxMTBhMzAxMjMwMDQxNDA2YTIyMDMyNDAwMjAwMzQxMDAyMDAzNmI0MTAzNzEyMjA0NmEyMTA3MjAwNDA0NDAyMDAzMjEwMjAzNDAyMDAyNDEwMDNhMDAwMDIwMDI0MTAxNmEyMjAyMjAwNzQ5MGQwMDBiMGIyMDA3NDFjMDAwMjAwNDZiMjIwNTQxN2M3MTIyMDQ2YTIxMDIyMDA0NDEwMDRhMDQ0MDAzNDAyMDA3NDEwMDM2MDIwMDIwMDc0MTA0NmEyMjA3MjAwMjQ5MGQwMDBiMGIyMDA1NDEwMzcxMjIwNDA0NDAyMDAyMjAwNDZhMjEwNDAzNDAyMDAyNDEwMDNhMDAwMDIwMDI0MTAxNmEyMjAyMjAwNDQ5MGQwMDBiMGIyMDA2MjAwMzAyN2YyMDAxMDQ0MDIwMDFhZDIxMTY0MTNmMjEwMTAyNDAwMzQwMjAxNjUwMGQwMTIwMDE0MTNmNGQwNDQwMjAwMTIwMDM2YTIwMTYyMDE2NDIwYTgwMjIxNjQyMGE3ZTdkYTc0MTMwNzIzYTAwMDAyMDAxNDEwMTZiMjEwMTBjMDEwYjBiMTAyYzAwMGIyMDAxNDEwMTZhMGMwMTBiMjAwMzQxMzAzYTAwM2Y0MTNmMGIyMjAxNmE0MWMwMDAyMDAxNmIxMGEzMDEyMDAzNDE0MDZiMjQwMDIwMDAyODAyODAwMjIwMDAyZDAwODQwMjEwMzgxMDAwMDAwYjIwMDAyMDAxMzYwMmNjMDExMDdkMjEwMjEwN2QyMTA0MjAwMDIwMDExMDEyMzYwMmQ4MDEyMDAwNDEwMDM2MDJkNDAxMjAwMDIwMDA0MWNjMDE2YTM2MDJkMDAxMDI0MDAzNDAwMjQwMjAwMDQxODAwMjZhMjAwMDQxZDAwMTZhMTA2NzIwMDAyOTAzODAwMjUwMGQwMDIwMDAyODAyOTQwMjIxMDUyMDAyMjEwMzIwMDAyODAyOTAwMjIyMDEyMDBjMTAzMDQ1MDQ0MDIwMDQyMTAzMjAwMTIwMDgxMDMwNDUwZDAzMGIyMDAzMjAwNTEwOGYwMTBjMDEwYjBiMjAwODEwMmYyMTBjNDIwMDIxMTYyMDA2MjEwMTBjMDEwYjBiMGI0MTg3ODYwODQxMjExMDQxMDAwYjQxYTU4YTA4NDExNTEwNDEwMDBiMjAwMDQxODA4MDgwMjAzNjAyZDAwMTIwMDYyMDAwNDFkMDAxNmE0MTA0MTAwZjFhMjAwNjQxZWQ4NTA4NDEwNDEwMGYxYTBiMjAwMDQyMDAzNzAzZDAwMTIwMDYyMDAwNDFkMDAxNmEyMjAzNDEwODEwMGYxYTIwMDUyMDA2MTAzZjIwMDQyMDA2MTA0ZTEwYzcwMTEwNDMyMjAxNDE4YThkMDg0MTA4MTA0ZDEwNGUyMDAyMTA0MzEwMmYyMjAyMTAzZjIwMDIxMDNmMjAwMTIwMDIxMDI0MjAwMDIwMDQzNjAyZDAwMTIwMDAyMDA0MTAxMjM2MDI4ODAyMjAwMDQxMDAzNjAyODQwMjIwMDAyMDAzMzYwMjgwMDIwMzQwMjAwMDIwMDA0MTgwMDI2YTEwYzQwMTIwMDAyODAyMDAwNDQwMjAwMDI4MDIwNDEwMDcxYTBjMDEwYjBiMjAwMDQxYTAwMjZhMjQwMDBmMGI0MWJhOGEwODQxMWExMDQxMDAwYjBkMDAxMDIyNDEwMDEwNWExMGM3MDExMDI1MGIwZDAwMTAyMjQxMDAxMDVhMTBkMTAxMTA1YjBiMGQwMDEwMjI0MTAwMTA1YTEwZDQwMTEwNWQwYjBkMDAxMDIyNDEwMDEwNWExMGQ4MDExMDVkMGIyYTAxMDE3ZjEwMjI0MTAwMTA1YTEwY2IwMTEwYWIwMTIyMDA0MWZlZmZmZmZmMDc0NzA0NDAyMDAwMTAwNzFhMGYwYjQxZWQ4NTA4NDEwNDEwMjYwYjBkMDAxMDIyNDEwMDEwNWExMGRhMDExMDVkMGIwZDAwMTAyMjQxMDAxMDVhMTBjODAxMTA1YjBiMGQwMDEwMjI0MTAwMTA1YTEwYzkwMTEwNWIwYjBkMDAxMDIyNDEwMDEwNWExMGNjMDExMDViMGIwZDAwMTAyMjQxMDAxMDVhMTBkOTAxMTA1ZDBiMGQwMDEwMjI0MTAwMTA1YTEwZDIwMTEwNWIwYmExMDEwMTAyN2YyMzAwNDE0MDZhMjIwMDI0MDAxMDIyNDEwMTEwNWEyMDAwNDEwMDEwNGIzNjAyMTQyMDAwMjAwMDQxMTQ2YTEwZDYwMTEwYWMwMTIyMDEzNjAyMTgyMDAwNDEwODZhMTAzNTIwMDAyMDAwMmQwMDBjM2EwMDIwMjAwMDIwMDAyODAyMDgzNjAyMWMyMDAwMjAwMTEwMTIzNjAyMmMyMDAwNDEwMDM2MDIyODIwMDAyMDAwNDExODZhMzYwMjI0MjAwMDQxMzQ2YTIxMDEwMzQwMjAwMDQxMzA2YTIwMDA0MTI0NmExMGJhMDEyMDAwMjgwMjMwMDQ0MDIwMDEyMDAwNDExYzZhMTBiYjAxMGMwMTBiMGIyMDAwMjgwMjFjMjAwMDJkMDAyMDEwMzcyMDAwNDE0MDZiMjQwMDBiYTAwMTAxMDI3ZjIzMDA0MTQwNmEyMjAwMjQwMDEwMjI0MTAxMTA1YTIwMDA0MTAwMTA0YjM2MDIxNDIwMDAyMDAwNDExNDZhMTBkNTAxMTBiMjAxMjIwMTM2MDIxODIwMDA0MTA4NmExMDM1MjAwMDIwMDAyZDAwMGMzYTAwMjAyMDAwMjAwMDI4MDIwODM2MDIxYzIwMDAyMDAxMTAxMjM2MDIyYzIwMDA0MTAwMzYwMjI4MjAwMDIwMDA0MTE4NmEzNjAyMjQwMzQwMjAwMDQxMzA2YTIwMDA0MTI0NmExMGI1MDEyMDAwMmQwMDNjNDEwMjQ3MDQ0MDIwMDA0MTMwNmEyMDAwNDExYzZhMTBiNjAxMGMwMTBiMGIyMDAwMjgwMjFjMjAwMDJkMDAyMDEwMzcyMDAwNDE0MDZiMjQwMDBiMGQwMDEwMjI0MTAwMTA1YTEwZDMwMTEwNWUwYjBkMDAxMDIyNDEwMDEwNWExMGQ3MDExMDVlMGJlMzAzMDIwNTdmMDI3ZTIzMDA0MTkwMDE2YjIyMDAyNDAwMTA0OTQxMDAxMDVhMjAwMDEwNGEyMjAxMzYwMjE0MDI0MDIwMDExMDY1NDEwMTQ2MDQ0MDIwMDExMDEyMjEwMTIwMDA0MTAwMzYwMjM0MjAwMDIwMDEzNjAyMzAyMDAwNDEwMDM2MDIyYzIwMDAyMDAwNDExNDZhMzYwMjI4MjAwMDQxM2M2YTIxMDIyMDAwNDFmNDAwNmEyMTAzMjAwMDQxZjgwMDZhMjEwMTAzNDAyMDAwNDFmMDAwNmEyMDAwNDEyODZhMTA2NzIwMDAyOTAzNzA1MDBkMDIyMDAwNDFlMDAwNmEyMDAxNDEwODZhMjkwMzAwMjIwNTM3MDMwMDIwMDAyMDAxMjkwMzAwMjIwNjM3MDM1ODIwMDAyMDAwMjgwMjM0MjIwNDQxMDE2YTM2MDIzNDIwMDM0MTA4NmEyMDA1MzcwMjAwMjAwMzIwMDYzNzAyMDAyMDAwNDE0MDZiMjAwMTI5MDIwMDM3MDMwMDIwMDA0MWM4MDA2YTIwMDA0MTgwMDE2YTI4MDIwMDM2MDIwMDIwMDAyMDAwMjkwMjcwMzcwMzM4MjAwNDQ1MDQ0MDIwMDA0MTIwNmEyMDAyNDEwODZhMjkwMjAwMzcwMzAwMjAwMDIwMDIyOTAyMDAzNzAzMTgwYzAxMGIwYjEwMmMwMDBiNDFiMzgzMDg0MTIyMTAwMzAwMGIyMDAwNDEwODZhMjIwMTIwMDA0MTIwNmEyOTAzMDAzNzAzMDAyMDAwMjAwMDI5MDMxODM3MDMwMDEwZGEwMTEwYTcwMTIxMDIyMDAxMjgwMjAwMjAwMjEwMzA0NTA0NDA0MTk4OGEwODQxMGQxMDQxMDAwYjEwZDIwMTEwNWMyMTAyMjAwMDEwNDMzNjAyMTgyMDAwMTA0MzM2MDIyODIwMDA0MWYwMDA2YTIyMDEyMDAyMTAzMjQxYTc4MzA4NDEwNTEwMzMyMDAwMjgwMjc0MjIwMjIwMDA0MTE4NmExMDdiMjAwMjIwMDA0MTI4NmExMDdhMjAwMDQxZTgwMDZhMjAwMDQxODAwMTZhMjkwMzAwMzcwMzAwMjAwMDQxZTAwMDZhMjAwMDQxZjgwMDZhMjkwMzAwMzcwMzAwMjAwMDIwMDAyOTAzNzAzNzAzNTgyMDAwNDEzODZhMjIwMjIwMDA0MWQ4MDA2YTIwMDAxMDg0MDEyMDAxMjAwMjEwY2QwMTIwMDExMDc0MjAwMDQxOTAwMTZhMjQwMDBiOGMwMTAxMDI3ZjIzMDA0MTQwNmEyMjAwMjQwMDEwNDk0MTAwMTA1YTEwZDIwMTEwNWMyMTAxMjAwMDEwNDMzNjAyMDAyMDAwMTA0MzM2MDIwNDIwMDA0MTA4NmEyMDAxMTAzMjQxOTU4MzA4NDExMjEwMzMyMDAwMjgwMjBjMjIwMTIwMDAxMDdiMjAwMTIwMDA0MTA0NmExMDdhMjAwMDQxMzA2YTIwMDA0MTE4NmEyOTAzMDAzNzAzMDAyMDAwNDEyODZhMjAwMDQxMTA2YTI5MDMwMDM3MDMwMDIwMDAyMDAwMjkwMzA4MzcwMzIwMjAwMDEwN2QzNjAyMzgyMDAwNDEyMDZhMTA3NDIwMDA0MTQwNmIyNDAwMGJmZjAxMDIwNTdmMDE3ZTIzMDA0MTMwNmIyMjAwMjQwMDEwMjIxMDQ5NDEwMTEwNWEyMDAwMTA0ZjM2MDIxMDEwZDIwMTEwNWMyMDAwMTA0MzM2MDIxNDIwMDAxMDQzMzYwMjE4MTAzMjIxMDI0MWFjODMwODQxMDcxMDRkMjEwMzEwNDMyMjAxMjAwMDQxMTA2YTEwNzgyMDAxMjAwMDQxMTQ2YTEwN2IyMDAxMjAwMDQxMTg2YTEwN2ExMDdkMjEwNDEwMTYyMDAyMjAwNDIwMDMyMDAxMTA0NTIxMDExMDE3MjAwMTEwMTIyMTAyMjAwMDQxMDAzNjAyMjQyMDAwMjAwMTM2MDIxYzIwMDAyMDAyNDEwMjc2MzYwMjIwMjAwMDQxMWM2YTEwNzUyMTAxMjAwMDQyMDAzNzAzMjgyMDAxMTAxMjIyMDI0MTA5NDkwNDQwMDI0MDIwMDA0MTA4NmEyMDAwNDEyODZhMjAwMjEwYjAwMTIwMDE0MTAwMjAwMDI4MDIwODIyMDEyMDAwMjgwMjBjMjIwMjEwOGEwMTFhMjAwMTIwMDIxMGIxMDEyMjA1NDI4MDgwODA4MDEwNWEwZDAwMjAwNTEwMTQyMDAwNDEzMDZhMjQwMDBmMGIwYjQxOGE4NTA4NDEwYjQxOTU4NTA4NDEwZTEwNGMwMDBiOTgwMzAyMDU3ZjAxN2UyMzAwNDFlMDAwNmIyMjAwMjQwMDEwMjIxMDQ5NDFlNGRiMDgxMDEzMzYwMjAwNDFlNGRiMDgyODAyMDA0MTAwNDgwNDQwNDFlZjgzMDg0MTExMTAwMzAwMGIyMDAwNDEwMDM2MDIzODEwNDMyMTAzMjAwMDQxMzg2YTIyMDQyODAyMDAyMTAxMDM0MDQxZTRkYjA4MjgwMjAwMjAwMTRhMDQ0MDIwMDQyMDAxNDEwMTZhMjIwMjM2MDIwMDIwMDMyMDAxMTA0YjEwNGUyMDAyMjEwMTBjMDEwYjBiMjAwMzIxMDE0MWU0ZGIwODI4MDIwMDIwMDAyODAyMzg0YTA0NDA0MTgwODQwODQxMTIxMDAzMDAwYjIwMDAyMDAxMzYwMjFjMjAwNDEwZDIwMTEwNWMxMDMyNDFmOTgyMDg0MTBkMTAzMzIwMDAyMDAxMTAxMjM2MDI1YzIwMDA0MTAwMzYwMjU4MjAwMDIwMDA0MTFjNmEzNjAyNTQyMDAwMjgwMjNjMjEwMTAzNDAyMDAwNDExMDZhMjAwMDQxZDQwMDZhMTBjNDAxMjAwMDI4MDIxMDA0NDAyMDAxMjAwMDI4MDIxNDEwNmUwYzAxMGIwYjIwMDA0MTI4NmEyMDAwNDE0MDZiMjkwMzAwMzcwMzAwMjAwMDQxMzA2YTIwMDA0MWM4MDA2YTI5MDMwMDM3MDMwMDIwMDAyMDAwMjkwMzM4MzcwMzIwMjAwMDQxMzg2YTIwMDA0MTIwNmExMDdlMDI0MDIwMDAyODAyNDQyMjAxMTBjZTAxNDUwNDQwMjAwMDI4MDI0MDIxMDIwYzAxMGIxMDQ2MjAwMDI4MDI0MDIyMDI0MjAwMjAwMTEwNDIwYjIwMDAyOTAzMzgyMDAwNDEwODZhMTAzNTIwMDAyMDAwMmQwMDBjM2EwMDNjMjAwMDIwMDAyODAyMDgzNjAyMzgyMDAyMjAwMDQxMzg2YTIyMDIxMDNlMjAwMjEwYzYwMTIwMDEyMDAyMTAzYzIwMDAyODAyMzgyMDAwMmQwMDNjMTAzNzIwMDA0MWUwMDA2YTI0MDAwYjMxMDEwMTdlMTAyMjEwNDk0MTAxMTA1YTQxMDAxMDExMjIwMDQyODE4MDkwYmJiYWQ2YWRmMDBkNWEwNDQwNDFlZjhiMDg0MTIwMTA0MTAwMGIxMGQ3MDEyMDAwMTBhYTAxMGIzMTAxMDE3ZTEwMjIxMDQ5NDEwMTEwNWE0MTAwMTAxMTIyMDA0MjgxODA5MGJiYmFkNmFkZjAwZDVhMDQ0MDQxZDI4YjA4NDExZDEwNDEwMDBiMTBkMzAxMjAwMDEwYWEwMTBiZTMwMTAxMDM3ZjIzMDA0MTMwNmIyMjAwMjQwMDEwMjIxMDQ5NDEwMjEwNWE0MTAwMTA1ODIxMDEyMDAwNDEwMTEwNTEyMjAyMzYwMjBjMjAwMDIwMDEzNjAyMDgyMDAwMjAwMTEwMTIzNjAyMTgyMDAwNDEwMDM2MDIxNDIwMDAyMDAwNDEwODZhMzYwMjEwMDM0MDIwMDA0MTFjNmEyMDAwNDExMDZhMTBjMzAxMjAwMDI4MDIxYzA0NDAyMDAwMjAwMDI4MDIyNDIyMDEzNjAyMmMyMDAwMjAwMDI4MDIyMDM2MDIyODIwMDA0MTI4NmExMGQ2MDEyMDAxMTBiOTAxMGMwMTA1MjAwMDIwMDIxMDEyMzYwMjE4MjAwMDQxMDAzNjAyMTQyMDAwMjAwMDQxMGM2YTM2MDIxMDAzNDAyMDAwNDExYzZhMjAwMDQxMTA2YTEwYzMwMTIwMDAyODAyMWMwNDQwMjAwMDIwMDAyODAyMjQyMjAxMzYwMjJjMjAwMDIwMDAyODAyMjAzNjAyMjgyMDAwNDEyODZhMTBkNTAxMjAwMTEwYjQwMTBjMDEwYjBiMjAwMDQxMzA2YTI0MDAwYjBiMGJhYTA3MDIwYjdmMDE3ZTIzMDA0MTMwNmIyMjAwMjQwMDEwMjI0MTAwMTA1YTEwYzkwMTEwNWMyMjA5MTAyZjEwMzIyMTAxNDFkMjgxMDg0MTE0MTA0ZDIxMDIxMDQzMjEwNjEwN2QyMTA3MTAxNjIwMDEyMDA3MjAwMjIwMDYxMDQ1MjEwMTEwMTcyMDAxMTAxMjIxMDIyMDAwNDEwMDM2MDIxMDIwMDAyMDAxMzYwMjA4MjAwMDIwMDI0MTAyNzYzNjAyMGMyMDAwNDEwODZhMTA3NTIyMDIxMDEyMjEwMTIwMDA0MTI4NmE0MTAwM2EwMDAwMjAwMDQxMjQ2YTIwMDEzNjAyMDAyMDAwMjAwMjM2MDIyMDIwMDAyMDAxMzYwMjFjMjAwMDQxMDAzNjAyMTgwMjQwMDI3ZjAyNDAwMjQwMjAwMTQ1MGQwMDAyNDAwMjQwMDI0MDIwMDA0MTE4NmE0MThhODUwODQxMGIxMDU0NDFmZjAxNzEwZTAyMDIwMTAwMGI0MThhODUwODQxMGI0MWVkODYwODQxMGQxMDRjMDAwYjQxMDEyMTAzMjAwMDQxMTg2YTQxOGE4NTA4NDEwYjEwNTMyMTAxMGIyMDAwMjgwMjFjMjAwMDI4MDIxODQ3MGQwMzIwMDAyZDAwMjgwNDQwNDFkY2RiMDg0MTAwMzYwMjAwNDFlMGRiMDg0MTAwM2EwMDAwMGIyMDAzNDUwZDAwMjAwMDQxMTg2YTIyMDQyMDAxMTAyZjEwMzI0MWU0ODIwODQxMTUxMDMzMjAwMDIwMDQxMDdjMjIwMzM2MDIwMDIwMDQyMDAxMTAyZjEwMzI0MWIyODIwODQxMGIxMDMzMjAwMDQxMTg2YTEwN2M0MmJlOGE4NjBmMTAyZTEwOGUwMTIxMDYyMDA0MjAwMTEwMmYxMDMyNDFjOTgyMDg0MTBkMTAzMzIwMDA0MTE4NmExMDdjMjAwMzEwOTIwMTQyYmU4YTg2MGYxMDJlMTA4ZTAxNDEwYTEwMmQ0MTEyMTA5NDAxMTA4ZDAxMjEwNzIwMDQyMDAxMTAyZjEwMzI0MWJkODIwODQxMGMxMDMzMjAwMDQxMTg2YTEwN2M0MTBhMTAyZDQxMTIxMDk0MDEyMDAzMTA5MDAxMTA4ZTAxNDJiZThhODYwZjEwMmUxMDhlMDE0MTBhMTAyZDQxMTIxMDk0MDExMDhkMDEyMTBhMjAwNDIwMDkxMDJmMjIwMjEwMmYxMDMyNDE4NzgxMDg0MTBmMTAzMzIwMDAyMDAwNDExODZhMTA3YzIyMDUzNjAyMTQyMDA0MjAwMjEwMmYxMDMyNDFhYjgyMDg0MTA3MTAzMzIwMDA0MTE4NmExMDdjMjEwODIwMDQyMDAyMTAzMjQxYTY4MTA4NDExMDEwMzMyMDAwNDExODZhMTA3YzIxMDIyMDAwMjAwODIwMDUxMDkxMDEyMDAyMTA5MDAxMzYwMjA4MjAwNDIwMDExMDMyNDFkNjgyMDg0MTBlMTAzMzIwMDAyODAyMWMyMjAxMjAwMDQxMTQ2YTEwNzgyMDAxMjAwMDQxMDg2YTEwNzgyMDAwMjgwMjI4MjEwMjIwMDAyODAyMTgyMTA1MjAwMDI5MDMyMDEwN2QyMTA4MTA3MTIwMDIyMDA4MjAwNTIwMDExMDQ1MjEwMTEwMTcyMDAwMjAwMTEwNzMzNjAyMDQ0MjgwODA5MGJiYmFkNmFkZjAwZDEwMmUyMTAyMjAwMDEwN2QzNjAyMTgyMDAwNDEwNDZhMjAwNDEwY2YwMTIxMDUxMDdkMjIwMTIwMDUwZDAyMWEyMDAxMjAwMDI4MDIwNDEwODkwMTQxMDE2YTQxZmYwMTcxNDEwMTRkMDQ0MDIwMDA0MTA0NmEyMDAwMTBjZjAxMGQwMjIwMDAyODAyMDAyMTAzMGIyMDAwMjgwMjA0MjAwMzEwOTMwMTIwMGExMDhlMDEyMTAxNDEwYTEwMmQ0MTEyMTA5NDAxMjAwMDI4MDIwMDEwOTAwMTIxMDMyMDA2MjAwMjEwOTIwMTIwMDcyMDAyMTA5MjAxMTA4YzAxMjAwMTIwMDIxMDhlMDEyMDAzMTA4ZDAxMTA4YzAxMGMwMjBiNDFhMDhiMDg0MTMyMTA0MTAwMGIyMDAwMjgwMjA0MjAwNzEwOTIwMTIxMDEyMDA2MjAwMjEwOTIwMTIwMDEyMDAyMTA4ZTAxMjAwMDI4MDIwMDEwOGQwMTEwOGMwMTBiMjEwMTIwMDA0MTE4NmEyMjAzMjAwOTEwMzI0MTk2ODEwODQxMTAxMDMzMjAwMzEwN2MyMTAyNDEwYTEwMmQ0MTEyMTA5NDAxMjEwMzIwMDAyODAyMDQyMDAxMTA5MjAxMjAwMzIwMDIxMDkzMDExMDhlMDEyMDAzNDEwMzEwOTQwMTEwOGQwMTEwMjUyMDAwNDEzMDZhMjQwMDBmMGI0MThhODUwODQxMGI0MTk1ODUwODQxMGUxMDRjMDAwYjAzMDAwMTBiM2MwMTAxN2YyMzAwNDExMDZiMjIwNTI0MDAyMDA1NDEwODZhMjAwMTIwMDQyMDAyMjAwMzEwOWQwMTIwMDUyODAyMGMyMTAxMjAwMDIwMDUyODAyMDgzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MTEwNmEyNDAwMGIzYjAxMDE3ZjIzMDA0MTEwNmIyMjA1MjQwMDIwMDU0MTA4NmEyMDAyMjAwMzIwMDEyMDA0MTAyYjIwMDUyODAyMGMyMTAxMjAwMDIwMDUyODAyMDgzNjAyMDAyMDAwMjAwMTM2MDIwNDIwMDU0MTEwNmEyNDAwMGIwYmRhMGQwMjAwNDE4MDgwMDgwYmM2MGQ0ZTZmMjA3Mzc3NjE3MDIwNmY3MDY1NzI2MTc0Njk2ZjZlMjA2NjZmNzU2ZTY0MjA2MTc0MjA2OTZlNjQ2NTc4MjA3NTZlNzc3MjYxNzA0NTY3NmM2NDY3NjU3NDU3NzI2MTcwNzA2NTY0NDU2NzZjNjQ1NDZmNmI2NTZlNDk2NDc3NzI2MTcwNDU2NzZjNjQ3MjY1NjM2OTcwNjk2NTZlNzQyMDYxNjQ2NDcyNjU3MzczMjA2ZTZmNzQyMDczNjU3NDY1Nzg2OTc0NGQ2MTcyNmI2NTc0NjM2YzYxNjk2ZDUyNjU3NzYxNzI2NDczNjc2NTc0NDE2MzYzNmY3NTZlNzQ1NDZmNmI2NTZlNzM2NzY1NzQ1NDZmNzQ2MTZjNDI2ZjcyNzI2Zjc3NzM2NzY1NzQ1MjY1NzM2NTcyNzY2NTQ2NjE2Mzc0NmY3MjY3NjU3NDU0NmY3NDYxNmM1MjY1NzM2NTcyNzY2NTczNjc2NTc0NTQ2ZjZiNjU2ZTQ5NjQ2ZDY5NmU3NDQxNmU2NDQ1NmU3NDY1NzI0ZDYxNzI2YjY1NzQ2NzY1NzQ0OTZlNzQ2NTcyNjU3Mzc0NTI2MTc0NjU0ZDZmNjQ2NTZjNjc2NTc0NTU2ZTY0NjU3MjZjNzk2OTZlNjc0OTY0NzQ2ZjZiNjU2ZTczNTQ2ZjU1NmU2NDY1NzI2Yzc5Njk2ZTY3NDE2ZDZmNzU2ZTc0NzU2ZTY0NjU3MjZjNzk2OTZlNjc0MTZkNmY3NTZlNzQ1NDZmNTQ2ZjZiNjU2ZTczNzI2NTY0NjU2NTZkNjc2NTc0NDM2MTczNjg2NzY1NzQ0MjYxNzM2NTUyNjE3NDY1Njc2NTc0NGM2MTczNzQ1MzZjNmY3MDY1Njc2NTc0NDY2OTcyNzM3NDUzNmM2ZjcwNjU2NzY1NzQ1NTc0Njk2YzY5N2E2MTc0Njk2ZjZlNjc2NTc0NGY3MDc0Njk2ZDYxNmM1NTc0Njk2YzY5N2E2MTc0Njk2ZjZlNjM2YzYxNjk2ZDRkNzU2Yzc0Njk3MDZjNjU2NzY1NzQ1Mzc0NjE2YjY1NTQ2ZjZiNjU2ZTQ5NjQ3MjY1NjI2MTZjNjE2ZTYzNjU1MDZmNzI3NDY2NmY2YzY5NmY3Mzc0NjE2YjY1NzU2ZTczNzQ2MTZiNjU2OTZlNjM2ZjcyNzI2NTYzNzQyMDZlNzU2ZDYyNjU3MjIwNmY2NjIwNDU1MzQ0NTQyMDc0NzI2MTZlNzM2NjY1NzI3MzYxNzI2Nzc1NmQ2NTZlNzQyMDY0NjU2MzZmNjQ2NTIwNjU3MjcyNmY3MjIwMjgyOTNhMjA3NDZmNmYyMDY2NjU3NzIwNjE3MjY3NzU2ZDY1NmU3NDczNzQ2ZjZmMjA2ZDYxNmU3OTIwNjE3MjY3NzU2ZDY1NmU3NDczNzc3MjZmNmU2NzIwNmU3NTZkNjI2NTcyMjA2ZjY2MjA2MTcyNjc3NTZkNjU2ZTc0NzM2MzYxNmU2ZTZmNzQyMDczNzU2Mjc0NzI2MTYzNzQyMDYyNjU2MzYxNzU3MzY1MjA3MjY1NzM3NTZjNzQyMDc3NmY3NTZjNjQyMDYyNjUyMDZlNjU2NzYxNzQ2OTc2NjU0ZDc1NmM3NDY5NDU1MzQ0NTQ0ZTQ2NTQ1NDcyNjE2ZTczNjY2NTcyNDU1MzQ0NTQ0ZTQ2NTQ1NDcyNjE2ZTczNjY2NTcyNDU1MzQ0NTQ1NDcyNjE2ZTczNjY2NTcyNzM3OTZlNjMyMDcyNjU3Mzc1NmM3NDY5NmU3MDc1NzQyMDc0NmY2ZjIwNmM2ZjZlNjc2OTZlNzA3NTc0MjA3NDZmNmYyMDczNjg2ZjcyNzQ2MzYxNzM3NDIwNzQ2ZjIwNjkzNjM0MjA2NTcyNzI2ZjcyNGQ2MTZlNjE2NzY1NjQ1NjY1NjMyMDY5NmU2NDY1NzgyMDZmNzU3NDIwNmY2NjIwNzI2MTZlNjc2NTQ1NTM0NDU0MjA2NTc4NzA2NTYzNzQ2NTY0NDU0NzRjNDQ3Mzc0NmY3MjYxNjc2NTIwNjQ2NTYzNmY2NDY1MjA2NTcyNzI2ZjcyM2EyMDc1NmU2YjZlNmY3NzZlMjA3MjY1NjM2NTY5NzY2NTY0MjA3NDZmNmI2NTZlMjA2MTY2NzQ2NTcyMjA3Mzc3NjE3MDY1Nzg2MzY4NjE2ZTY3NjU2MjYxNjQyMDYxNzI3MjYxNzkyMDZjNjU2ZTY3NzQ2ODc3NzI2ZjZlNjcyMDcyNjU3NDc1NzI2ZTY1NjQyMDczNzc2MTcwMjA3NDZmNmI2NTZlNzM3NzYxNzA1NDZmNmI2NTZlNzM0NjY5Nzg2NTY0NDk2ZTcwNzU3NDY5NmU3NjYxNmM2OTY0MjA3NjYxNmM3NTY1Nzc3MjYxNzA3MDY1NjQ1ZjY1Njc2YzY0NWY2MzZmNmU3NDcyNjE2Mzc0NWY2MTY0NjQ3MjY1NzM3MzYzNmY2ZDcwNmY3NTZlNjQ1ZjYxNzM2ODczNzc2MTcwNWY3Mzc3NjE3MDczNjM2ZjZkNzA2Zjc1NmU2NDVmNzg2NTc4NjM2ODYxNmU2NzY1NWY3Mzc3NjE3MDczNzA2NTcyNjY2ZjcyNmQ2MTZlNjM2NTVmNjY2NTY1NzM1ZjcwNjU3MjYzNjU2ZTc0NjM2ZjZkNzA2Zjc1NmU2NDVmNjY2NTY1NzM1ZjcwNjU3MjYzNjU2ZTc0NjI2ZjZmNzM3NDY1NzI1ZjYxNjQ2NDcyNjU3MzczNmQ2ZjZlNjU3OTVmNmQ2MTcyNmI2NTc0NWY2MTY0NjQ3MjY1NzM3MzYzNmY2ZTc0NzI2ZjZjNmM2NTcyNWY2MTY0NjQ3MjY1NzM3MzYxNzM3MzY1NzQ1Zjc0NmY2YjY1NmU1ZjY5NjQ2NTZlNzQ2OTY2Njk2NTcyNzY2MTc1NmM3NDVmNjE2NDY0NzI2NTczNzM3MDYxNzk2ZDY1NmU3NDIwNzM2ODZmNzU2YzY0MjA2MjY1MjA2MTZlMjA0NTUzNDQ1NDIwNzQ2ZjZiNjU2ZTU0Njg2NTIwNjE3MzczNjU3NDIwNzQ2ZjZiNjU2ZTIwNjk2NDY1NmU3NDY5NjY2OTY1NzIyMDYxNmU2NDIwNzQ2ODY1MjA2ZDZmNmU2NTc5MjA2ZDYxNzI2YjY1NzQyMDc1NmU2NDY1NzI2Yzc5Njk2ZTY3MjA2OTY0NjU2ZTc0Njk2NjY5NjU3MjIwNjQ2ZjZlMjc3NDIwNmQ2MTc0NjM2ODU3Njg2NTZlMjA3NDYxNzI2NzY1NzQ2OTZlNjcyMDYxNmUyMDQ1NDc0YzQ0MjA2ZDYxNzI2YjY1NzQyMDc0Njg2NTIwNjE3MzczNjU3NDIwNzQ2ZjZiNjU2ZTIwNjk2NDY1NmU3NDY5NjY2OTY1NzIyMDczNjg2Zjc1NmM2NDIwNjI2NTIwNTc0NTQ3NGM0NDQzNjE2YzZjNjU3MjIwNzM2ODZmNzU2YzY0MjA2MjY1MjA3NjYxNzU2Yzc0Nzc3MjZmNmU2NzIwNzA2MTc5NmQ2NTZlNzQ2ZTZmMjA3MjY1Nzc2MTcyNjQyMDc0NmYyMDYzNmY2ZDcwNmY3NTZlNjQ2ZTZmMjA2YzY1NjY3NDIwNjE2ZDZmNzU2ZTc0MjA3NDZmMjA2MzZmNmQ3MDZmNzU2ZTY0Nzc3MjZmNmU2NzIwNzM3NzYxNzA3MDY1NjQyMDc0NmY2YjY1NmU2ZTZmMjA2NTc4Njk3NDIwNmQ2MTcyNmI2NTc0MjA3MDYxNzk2ZDY1NmU3NDIwNzI2NTYzNjU2OTc2NjU2NDZlNmYyMDcyNjU2NDY1NjU2ZDIwNzA2MTc5NmQ2NTZlNzQyMDcyNjU2MzY1Njk3NjY1NjQ0ZTZmMjA2OTZlNzQ2NTcyNjU3Mzc0MjA3MjYxNzQ2NTIwNmQ2ZjY0NjU2YzIwNzA3MjY1NzM2NTZlNzQyMDZmNmUyMDc0Njg2NTIwNmQ2ZjZlNjU3OTIwNmQ2MTcyNmI2NTc0NmU2NTc3MjA2MzZmNmQ3MDZmNzU2ZTY0MjA2NjY1NjU3MzIwNjU3ODYzNjU2NTY0MjAzMTMwMzAyNTZlNjU3NzIwNzA2NTcyNjY2ZjcyNmQ2MTZlNjM2NTIwNjY2NTY1NzMyMDY1Nzg2MzY1NjU2NDIwMzEzMDMwMjU2ZDZmNmU2NTc5NWY2ZDYxNzI2YjY1NzQ1Zjc0NmY2YjY1NmU1ZjY5NjQ2NTZlNzQ2OTY2Njk2NTcyNzc3MjYxNzA3MDY1NjQ1ZjY1Njc2YzY0NWY3NDZmNmI2NTZlNWY2OTY0NjU2ZTc0Njk2NjY5NjU3MjYyNmY2ZjczNzQ2NTcyNWY3Mzc0NjE2YjY1NjQ1Zjc0NmY2YjY1NmU1ZjY5NjQ2NTZlNzQ2OTY2Njk2NTcyNmQ2ZjZlNjU3OTVmNmQ2MTcyNmI2NTc0NWY3NTZlNjQ2NTcyNmM3OTY5NmU2NzVmNjk2NDY1NmU3NDY5NjY2OTY1NzI2MzZmNmQ3MDZmNzU2ZTY0NDU2ZTY0NzA2ZjY5NmU3NDIwNjM2MTZlMjA2ZjZlNmM3OTIwNjI2NTIwNjM2MTZjNmM2NTY0MjA2Mjc5MjA2Zjc3NmU2NTcyMDAwMDcwNjE2ZTY5NjMyMDZmNjM2Mzc1NzI3MjY1NjQwMDQxYzg4ZDA4MGIwNDljZmZmZmZmQDA1MDBAMDEwMEAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwQDU3NDU0NzRjNDQyZDYxMzIzODYzMzUzOUAwMDAwMDAwMDAwMDAwMDAwMDUwMGEzYjY2NjkwMmQ1ZjRiYmYwZmY5Mzc0OGZiOTE1YWViNDMxMjRjYmY2NTA5QDAwMDAwMDAwMDAwMDAwMDAwNTAwMzJkZTRmNDBmMTdhMmY0MWM0ZTQwYzIxZjU5NmUzNmE4NDY5OTRlMzY1MDlAMDAwMDAwMDAwMDAwMDAwMDA1MDBmODgzNjY4NmY3YzZjMGYxM2Q3Mjc1MTUxYjc4ZjU5ZjhmMmY3MjlhNjUwOUBAQEBAMDAwMDAwMDAwMDAwMDAwMDA1MDAwYjFlNWIyNDQzMjUwOTU4NDlmNGUzNzEzNDY2MWQ1YmZkY2Q5MjVlN2NlYg==", + "signature": "edf0ec99b6f60414fa5e36d40cfb1d0075d01fd7c4ad7ba59bbe62b8b48eb892beb0c18bba203ff32b83827c3953847b190cdc89a4806f4615565dc2b3b5940f", + "sourceShard": 1, + "destinationShard": 1, + "blockNonce": 2127577, + "blockHash": "e3aea17b5345b45f61b233834d3b4ba0ac6f2b7d53eb3f1b1cf2bf0534ba567f", + "notarizedAtSourceInMetaNonce": 2129029, + "NotarizedAtSourceInMetaHash": "73ee8458f55bf5c9ea4a9974c0c838ced51a236c2b13238761f444598f40575e", + "notarizedAtDestinationInMetaNonce": 2129029, + "notarizedAtDestinationInMetaHash": "73ee8458f55bf5c9ea4a9974c0c838ced51a236c2b13238761f444598f40575e", + "miniblockType": "TxBlock", + "miniblockHash": "cc7e81e68269c2c633daf997fd2d52fc82d8ba3bb699d7e75250008bd9b7aa29", + "hyperblockNonce": 2129029, + "hyperblockHash": "73ee8458f55bf5c9ea4a9974c0c838ced51a236c2b13238761f444598f40575e", + "timestamp": 1707144290, + "status": "success", + "operation": "scDeploy", + "initiallyPaidFee": "82333950000000000", + "chainID": "D", + "version": 1, + "options": 0 + } + }, + "error": "", + "code": "successful" +} + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + let opt_address = tx_response.new_deployed_address.map(|e| { + multiversx_sdk::data::address::Address::from_bytes(*e.as_array()) + .to_bech32_string() + .unwrap() + }); + + let expected = + Some("erd1qqqqqqqqqqqqqpgqwpdf84ggxzqzmr2zmw959q4nlf9nz562q33sak25ze".to_string()); + + assert_eq!(opt_address, expected) +} + +#[test] +fn test_deployed_address_should_be_none_if_not_a_sc_deployment_tx() { + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "BuiltInFunctionCall", + "processingTypeOnDestination": "SCInvoking", + "hash": "238ad6dbe75dab1d53caeb9cabd584aabc6fc113c849a983afef5a5e439ce9e5", + "nonce": 13, + "round": 2192628, + "epoch": 888, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgqydwpdrplefjlwp3sp9xmn3vevdxdelfkwmfsw6e5xw", + "sender": "erd179xw6t04ug48m74jzyw9zq028hv66jhqayelzpzvgds0ptnzmckq2jf07f", + "gasPrice": 1000000000, + "gasLimit": 20000000, + "data": "RVNEVFRyYW5zZmVyQDRmNTU1MjRmMmQ2NDM4MzEzNzMxNjZAMDI0NmQyZDBiNmI1ZjBANjI3NTc5QDFiYzE2ZDY3NGVjODAwMDA=", + "signature": "ce984b4d785ccc7aca4b1cdea57ddcd568a502209f81e6b5bc678e1dd52b78d764fe46ea3ff77b926eb9f70eb52ae8f3f2afa2e9d0efa82655e361641458b900", + "sourceShard": 0, + "destinationShard": 1, + "blockNonce": 2129490, + "blockHash": "0ab10909b27565c5b7b59e8e1ee4a68d7046f49225fcde4c12d4b1ea3f512b8a", + "notarizedAtSourceInMetaNonce": 2130938, + "NotarizedAtSourceInMetaHash": "0c545160fd37f09f0196505b9cd2e730596bcd99438978a5bb415b9e1be1849d", + "notarizedAtDestinationInMetaNonce": 2130942, + "notarizedAtDestinationInMetaHash": "1ddd6b7aeeff824b5d11f2936a6284e470fc5abe41e34a8df229b719dc1a537d", + "miniblockType": "TxBlock", + "miniblockHash": "dc8ae41e1ae321c0fccbeb807194d11ff6e0f4ed71163764d850f1daaa60bd22", + "hyperblockNonce": 2130942, + "hyperblockHash": "1ddd6b7aeeff824b5d11f2936a6284e470fc5abe41e34a8df229b719dc1a537d", + "timestamp": 1707155768, + "status": "success", + "tokens": [ + "OURO-d8171f" + ], + "esdtValues": [ + "640821212132848" + ], + "operation": "ESDTTransfer", + "function": "buy", + "initiallyPaidFee": "359390000000000", + "chainID": "D", + "version": 1, + "options": 0 + } + }, + "error": "", + "code": "successful" +} + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + let opt_address = tx_response.new_deployed_address; + + let expected: Option
= None; + + assert_eq!(opt_address, expected) +} diff --git a/framework/snippets/tests/test_tx_issued_token_identifier.rs b/framework/snippets/tests/test_tx_issued_token_identifier.rs new file mode 100644 index 0000000000..3539c4e757 --- /dev/null +++ b/framework/snippets/tests/test_tx_issued_token_identifier.rs @@ -0,0 +1,1422 @@ +use multiversx_sc_snippets::network_response; +use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; + +#[test] +fn test_process_issued_token_identifier_fungible() { + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", + "nonce": 61, + "round": 173598, + "epoch": 72, + "value": "50000000000000000", + "receiver": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "sender": "erd1x39tc3q3nn72ecjnmcz7x0qp09kp97t080x99dgyhx7zh95j0n4szskhlv", + "gasPrice": 1000000000, + "gasLimit": 100000000, + "gasUsed": 100000000, + "data": "aXNzdWVMcFRva2VuQDAwMDAwMDAwMDAwMDAwMDAwNTAwMTM5ZWQ3YWU0YWEwMzc5MmU2YmNiMzMyMzk0YTQwZmU3NDZlZWZhNDdjZWJANDU0NzRjNDQ0ZDQ1NTg0YzUwQDQ1NDc0YzQ0NGQ0NTU4", + "signature": "b5049d2906adc1305a6a8d0f42749254ca6259c6996d9a35e7dc7528b3c87b48a421879aff70bc6d81483a7559b75e5dcf9be499dcb7d57aa9f25c79ac2ad40d", + "sourceShard": 1, + "destinationShard": 1, + "blockNonce": 173354, + "blockHash": "09d85ac264a54e12e7613395211c53fe0ee5a7d3b7111bf5fec1d02794caaacd", + "notarizedAtSourceInMetaNonce": 173321, + "NotarizedAtSourceInMetaHash": "64a83759da97fe8305cd4cda4b518f2d41ef0a8f3995d264460821edad45e09e", + "notarizedAtDestinationInMetaNonce": 173321, + "notarizedAtDestinationInMetaHash": "64a83759da97fe8305cd4cda4b518f2d41ef0a8f3995d264460821edad45e09e", + "miniblockType": "TxBlock", + "miniblockHash": "7f45eee4e35ffc1fbce66b92e4dd2aeae2acb092416aa5aa775b96493256b81d", + "hyperblockNonce": 173321, + "hyperblockHash": "64a83759da97fe8305cd4cda4b518f2d41ef0a8f3995d264460821edad45e09e", + "timestamp": 1695041588, + "smartContractResults": [ + { + "hash": "bce3d0dceb0b3e5c8c5780d7da3755c3f7492d551685d493a73bf66ebd36754b", + "nonce": 0, + "value": 50000000000000000, + "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "sender": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "data": "issue@45474c444d45584c50@45474c444d4558@03e8@12@63616e467265657a65@74727565@63616e57697065@74727565@63616e5061757365@74727565@63616e4d696e74@74727565@63616e4275726e@74727565@63616e4368616e67654f776e6572@74727565@63616e55706772616465@74727565@63616e4164645370656369616c526f6c6573@74727565@65ba30", + "prevTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", + "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", + "gasLimit": 89624222, + "gasPrice": 1000000000, + "callType": 1, + "originalSender": "erd1x39tc3q3nn72ecjnmcz7x0qp09kp97t080x99dgyhx7zh95j0n4szskhlv", + "operation": "transfer", + "function": "issue" + }, + { + "hash": "2a452ff652791d79be5f6933fb583cc5503e876893e54b3b51381a92aa2e904d", + "nonce": 0, + "value": 0, + "receiver": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "ESDTSetBurnRoleForAll@45474c444d45582d393563366435", + "prevTxHash": "bce3d0dceb0b3e5c8c5780d7da3755c3f7492d551685d493a73bf66ebd36754b", + "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "logs": { + "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", + "events": [ + { + "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", + "identifier": "completedTxEvent", + "topics": [ + "vOPQ3OsLPlyMV4DX2jdVw/dJLVUWhdSTpzv2br02dUs=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "transfer" + }, + { + "hash": "2c84740ccb3376ea9fa00dab6c6c93fe7a35ee0a1d6dbfa0a1e61064853b0874", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "ESDTTransfer@45474c444d45582d393563366435@03e8@00", + "prevTxHash": "bce3d0dceb0b3e5c8c5780d7da3755c3f7492d551685d493a73bf66ebd36754b", + "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", + "gasLimit": 39624222, + "gasPrice": 1000000000, + "callType": 2, + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "identifier": "ESDTTransfer", + "topics": [ + "RUdMRE1FWC05NWM2ZDU=", + "", + "A+g=", + "AAAAAAAAAAAFAO+ux8+3RD51ieGHV10Z68X293CYfOs=" + ], + "data": null, + "additionalData": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "identifier": "completedTxEvent", + "topics": [ + "vOPQ3OsLPlyMV4DX2jdVw/dJLVUWhdSTpzv2br02dUs=" + ], + "data": null, + "additionalData": null + } + ] + }, + "tokens": [ + "EGLDMEX-95c6d5" + ], + "esdtValues": [ + "1000" + ], + "operation": "ESDTTransfer", + "function": "\u0000" + }, + { + "hash": "c9dfc4de3c3cee319123087a4f5dd03cc051e728ec6070707a63ea977b535227", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "sender": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "data": "\u0000", + "prevTxHash": "2c84740ccb3376ea9fa00dab6c6c93fe7a35ee0a1d6dbfa0a1e61064853b0874", + "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", + "gasLimit": 39424222, + "gasPrice": 1000000000, + "callType": 2, + "operation": "transfer", + "function": "\u0000" + }, + { + "hash": "609c3a8e1903680fef1f6d9e47527b1b5c1259664b868af600162120ce0b8192", + "nonce": 1, + "value": 300925400000000, + "receiver": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "sender": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "data": "@6f6b", + "prevTxHash": "2c84740ccb3376ea9fa00dab6c6c93fe7a35ee0a1d6dbfa0a1e61064853b0874", + "originalTxHash": "b78170cc5ca5ba441ea46fe84540db9610ccab243ccd4cd3cd976e170c4864c8", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "operation": "transfer", + "isRefund": true + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "identifier": "transferValueOnly", + "topics": [ + "AAAAAAAAAAAFAO+ux8+3RD51ieGHV10Z68X293CYfOs=", + "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=", + "saK8LsUAAA==" + ], + "data": null, + "additionalData": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgqa7hv0nahgsl8tz0psat46x0tchm0wuyc0n4s6q28ad", + "identifier": "writeLog", + "topics": [ + "NEq8RBGc/KziU94F4zwBeWwS+W87zFK1BLm8K5aSfOs=" + ], + "data": "QDZmNmI=", + "additionalData": null + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "issueLpToken", + "initiallyPaidFee": "1214335000000000", + "fee": "1214335000000000", + "chainID": "D", + "version": 2, + "options": 0 + } + }, + "error": "", + "code": "successful" +} + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Option = Some("EGLDMEX-95c6d5".to_string()); + + assert_eq!(tx_response.new_issued_token_identifier, expected) +} + +#[test] +fn test_process_issued_token_identifier_semi_fungible() { + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", + "nonce": 65, + "round": 8422527, + "epoch": 584, + "value": "50000000000000000", + "receiver": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "sender": "erd1x3g000ew7zzv6kyqhj9jl2wy5g6cc72qahvvxz29zv76jwq6ssvqt0d998", + "gasPrice": 1000000000, + "gasLimit": 80000000, + "gasUsed": 80000000, + "data": "aXNzdWVUb2tlbkA0NDZmNzA2NTU0NjU3Mzc0QDQ0NGY1MDQ1NTQ0NTUzNTQ=", + "signature": "0191848976e930996f6c62d4921e732f9b0ada8b41ca3b5b63d6bfd304fd44c2a1e8e6643479618ba4a764a36e87f53882b4f707600d5b7d476f2fdd2bac040e", + "sourceShard": 0, + "destinationShard": 0, + "blockNonce": 8420241, + "blockHash": "4d302220f6015876c95e7961b770cc67f8ab63c5f0ab69b4d6c2fb15c8bc23bd", + "notarizedAtSourceInMetaNonce": 8403647, + "NotarizedAtSourceInMetaHash": "f8b83b6d38fa45dacc167b15c93dd07ee5c40db906de34f26e11e7a24f539e30", + "notarizedAtDestinationInMetaNonce": 8403647, + "notarizedAtDestinationInMetaHash": "f8b83b6d38fa45dacc167b15c93dd07ee5c40db906de34f26e11e7a24f539e30", + "miniblockType": "TxBlock", + "miniblockHash": "b7b8fc9f3b81d7daae1113cbf73457e16ee31f3a864ef3729a1a21f3a929e112", + "hyperblockNonce": 8403647, + "hyperblockHash": "f8b83b6d38fa45dacc167b15c93dd07ee5c40db906de34f26e11e7a24f539e30", + "timestamp": 1646652762, + "smartContractResults": [ + { + "hash": "9aecf3bd5dd5c706a28d1cc7059ac20db74340f136816f667dbefcc58daa3aba", + "nonce": 0, + "value": 50000000000000000, + "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "sender": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "data": "issueSemiFungible@446f706554657374@444f504554455354@63616e467265657a65@74727565@63616e57697065@74727565@63616e5061757365@74727565@63616e4368616e67654f776e6572@74727565@63616e55706772616465@74727565@63616e4164645370656369616c526f6c6573@74727565@5ca148", + "prevTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", + "originalTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", + "gasLimit": 75958360, + "gasPrice": 1000000000, + "callType": 1, + "originalSender": "erd1x3g000ew7zzv6kyqhj9jl2wy5g6cc72qahvvxz29zv76jwq6ssvqt0d998", + "operation": "transfer", + "function": "issueSemiFungible" + }, + { + "hash": "aacfe9088bb9d2d5b3fbe9cab2b2f1c6a7e9cbab2f1a41020e2c819fc9b43570", + "nonce": 66, + "value": 0, + "receiver": "erd1x3g000ew7zzv6kyqhj9jl2wy5g6cc72qahvvxz29zv76jwq6ssvqt0d998", + "sender": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "data": "@6f6b", + "prevTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", + "originalTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "operation": "transfer" + }, + { + "hash": "3f6f0f3de9e942884e7e1592823a7db7ce935a3f9d3359d8c1ee98a5645332d8", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "@00@444f5045544553542d373732303063", + "prevTxHash": "9aecf3bd5dd5c706a28d1cc7059ac20db74340f136816f667dbefcc58daa3aba", + "originalTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", + "gasLimit": 25958360, + "gasPrice": 1000000000, + "callType": 2, + "originalSender": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "identifier": "completedTxEvent", + "topics": [ + "muzzvV3VxwaijRzHBZrCDbdDQPE2gW9mfb78xY2qOro=" + ], + "data": null + } + ] + }, + "operation": "transfer" + }, + { + "hash": "c6e4f7c5da455009fb4f6967ce8a273a97b826aa617fa798ffd0cf17bde6b97a", + "nonce": 1, + "value": 225516180000000, + "receiver": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "sender": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "data": "@6f6b", + "prevTxHash": "3f6f0f3de9e942884e7e1592823a7db7ce935a3f9d3359d8c1ee98a5645332d8", + "originalTxHash": "0634b9c1db9fd6bfa065fc937d51cec37958fd5d33d0c934a0da3d27776a33ae", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "operation": "transfer", + "isRefund": true + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "identifier": "transferValueOnly", + "topics": [ + "AAAAAAAAAAAFAH6d74PDz8xLqvowrlOA5lVDBMUghBg=", + "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=", + "saK8LsUAAA==" + ], + "data": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgq06w7lq7relxyh2h6xzh98q8x24psf3fqssvqn4ptek", + "identifier": "writeLog", + "topics": [ + "NFD3vy7whM1YgLyLL6nEojWMeUDt2MMJRRM9qTgahBg=" + ], + "data": "QDZmNmI=" + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "issueToken", + "initiallyPaidFee": "914840000000000", + "fee": "914840000000000", + "chainID": "1", + "version": 1, + "options": 0 + } + }, + "error": "", + "code": "successful" +} + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Option = Some("DOPETEST-77200c".to_string()); + + assert_eq!(tx_response.new_issued_token_identifier, expected) +} + +#[test] +fn test_process_issued_token_identifier_non_fungible() { + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", + "nonce": 16, + "round": 820170, + "epoch": 341, + "value": "50000000000000000", + "receiver": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "sender": "erd162knt53z7m0f9jjms9wxphr3q9d7zu4ky85xs2cc0ekrqz7k4fdq85lkuc", + "gasPrice": 1000000000, + "gasLimit": 200000000, + "gasUsed": 200000000, + "data": "aXNzdWVUb2tlbkA2NzY1NmU2NTdhNzk3M0A0NzQ1NGU=", + "signature": "e80d45f4de419799a2bbff1cae1235521c8eef1853ee45b02f95c2da74ce50d241bf75b6ab0c650245562700862ea9759caad40f3e381ac0c4d82cfe56e67c09", + "sourceShard": 2, + "destinationShard": 2, + "blockNonce": 819313, + "blockHash": "a1db4ef13f07b86678000df9cc78f244d83dcc35ae51de545f333bf616930d39", + "notarizedAtSourceInMetaNonce": 819396, + "NotarizedAtSourceInMetaHash": "6d9e511e46d318aa5b77cbfdfde14d2ce8515ce4e954b286f130a6b518ddf26a", + "notarizedAtDestinationInMetaNonce": 819396, + "notarizedAtDestinationInMetaHash": "6d9e511e46d318aa5b77cbfdfde14d2ce8515ce4e954b286f130a6b518ddf26a", + "miniblockType": "TxBlock", + "miniblockHash": "afdb278522181aeb9b12f08840e6c534e398e6af9c7f757548308e300e7ec4e9", + "hyperblockNonce": 819396, + "hyperblockHash": "6d9e511e46d318aa5b77cbfdfde14d2ce8515ce4e954b286f130a6b518ddf26a", + "timestamp": 1698921020, + "smartContractResults": [ + { + "hash": "6fe0cc002802af1744f394eee4a69224b5e775961d8386e04e7a5b9242f7ff65", + "nonce": 0, + "value": 50000000000000000, + "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "sender": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "data": "issueNonFungible@67656e657a7973@47454e@63616e467265657a65@74727565@63616e57697065@74727565@63616e5061757365@74727565@63616e5472616e736665724e4654437265617465526f6c65@74727565@63616e4368616e67654f776e6572@66616c7365@63616e55706772616465@66616c7365@63616e4164645370656369616c526f6c6573@74727565@5e30e4", + "prevTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", + "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", + "gasLimit": 196098365, + "gasPrice": 1000000000, + "callType": 1, + "originalSender": "erd162knt53z7m0f9jjms9wxphr3q9d7zu4ky85xs2cc0ekrqz7k4fdq85lkuc", + "operation": "transfer", + "function": "issueNonFungible" + }, + { + "hash": "98afe82512c79f1caaf171bd5919ee469d11ba0c4f725aefcab834278c0f1e58", + "nonce": 0, + "value": 0, + "receiver": "erd1lllllllllllllllllllllllllllllllllllllllllllllllllupq9x7ny0", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "ESDTSetBurnRoleForAll@47454e2d383638353933", + "prevTxHash": "6fe0cc002802af1744f394eee4a69224b5e775961d8386e04e7a5b9242f7ff65", + "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "logs": { + "address": "erd1lllllllllllllllllllllllllllllllllllllllllllllllllupq9x7ny0", + "events": [ + { + "address": "erd1lllllllllllllllllllllllllllllllllllllllllllllllllupq9x7ny0", + "identifier": "completedTxEvent", + "topics": [ + "b+DMACgCrxdE85Tu5KaSJLXndZYdg4bgTnpbkkL3/2U=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "transfer" + }, + { + "hash": "83494ad9369738b574a7266cbfb12ce63ccf634950cd6b0ec16107b8fb42f8f6", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "sender": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "data": "setSpecialRole@47454e2d383638353933@00000000000000000500de51fa8943c26e6933419f9bb7ceb79b7ff4f7bbaa5a@45534454526f6c654e4654437265617465@5e30e4", + "prevTxHash": "112d18ec0364b4700b1bfb3df517c80dba547a53373ece2a9e71acd5266e7b64", + "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", + "gasLimit": 142399698, + "gasPrice": 1000000000, + "callType": 1, + "operation": "transfer", + "function": "setSpecialRole" + }, + { + "hash": "112d18ec0364b4700b1bfb3df517c80dba547a53373ece2a9e71acd5266e7b64", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "@00@47454e2d383638353933", + "prevTxHash": "6fe0cc002802af1744f394eee4a69224b5e775961d8386e04e7a5b9242f7ff65", + "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", + "gasLimit": 146098365, + "gasPrice": 1000000000, + "callType": 2, + "originalSender": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "identifier": "writeLog", + "topics": [ + "AAAAAAAAAAAFAN5R+olDwm5pM0Gfm7fOt5t/9Pe7qlo=" + ], + "data": "QDZmNmI=", + "additionalData": null + } + ] + }, + "operation": "transfer" + }, + { + "hash": "db5d74970374337956fa61fb4fd90057b3f6a82ea3e259b389934b71a1652e5f", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "ESDTSetRole@47454e2d383638353933@45534454526f6c654e4654437265617465", + "prevTxHash": "83494ad9369738b574a7266cbfb12ce63ccf634950cd6b0ec16107b8fb42f8f6", + "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "identifier": "ESDTSetRole", + "topics": [ + "R0VOLTg2ODU5Mw==", + "", + "", + "RVNEVFJvbGVORlRDcmVhdGU=" + ], + "data": null, + "additionalData": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "identifier": "completedTxEvent", + "topics": [ + "g0lK2TaXOLV0pyZsv7Es5jzPY0lQzWsOwWEHuPtC+PY=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "ESDTSetRole", + "function": "ESDTSetRole" + }, + { + "hash": "a6a665f47977a59c4c2baf460281fc938e04ae0f87ac2e78040a14ae27822701", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "@00", + "prevTxHash": "83494ad9369738b574a7266cbfb12ce63ccf634950cd6b0ec16107b8fb42f8f6", + "originalTxHash": "d296186b432d7e7937bde37d725cd52b765ef334c00b95adcb079933bc2277bb", + "gasLimit": 92399698, + "gasPrice": 1000000000, + "callType": 2, + "originalSender": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "identifier": "writeLog", + "topics": [ + "AAAAAAAAAAAFAN5R+olDwm5pM0Gfm7fOt5t/9Pe7qlo=", + "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gOTIzOTk2OTgsIGdhcyB1c2VkID0gMzE0MTg4MA==" + ], + "data": "QDZmNmI=", + "additionalData": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "identifier": "completedTxEvent", + "topics": [ + "g0lK2TaXOLV0pyZsv7Es5jzPY0lQzWsOwWEHuPtC+PY=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "transfer" + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "identifier": "transferValueOnly", + "topics": [ + "AAAAAAAAAAAFAN5R+olDwm5pM0Gfm7fOt5t/9Pe7qlo=", + "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=", + "saK8LsUAAA==" + ], + "data": null, + "additionalData": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgqmegl4z2rcfhxjv6pn7dm0n4hndllfaam4fdqwqxld8", + "identifier": "writeLog", + "topics": [ + "0q010iL23pLKW4FcYNxxAVvhcrYh6GgrGH5sMAvWqlo=" + ], + "data": "QDZmNmI=", + "additionalData": null + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "issueToken", + "initiallyPaidFee": "2097020000000000", + "fee": "2097020000000000", + "chainID": "D", + "version": 1, + "options": 0 + } + }, + "error": "", + "code": "successful" +} + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Option = Some("GEN-868593".to_string()); + + assert_eq!(tx_response.new_issued_token_identifier, expected) +} + +#[test] +fn test_process_issued_token_identifier_meta_esdt() { + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", + "nonce": 419, + "round": 1787093, + "epoch": 744, + "value": "50000000000000000", + "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "sender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "gasPrice": 1000000000, + "gasLimit": 600000000, + "gasUsed": 157220928, + "data": "ZGVwbG95QXNoc3dhcExQQUNTdHJhdGVneUA0MTRjNTAyZDYzNjE2NTYxNjMzNUA0MTU0NTMyZDM0NjMzMDM5MzIzMEAwM2U4QDAzZThAQDNiOWFjYTAwQDAwMDAwMDAwMDAwMDAwMDAwNTAwOTU3MzkwYWVkYTQzMmY1MmE0MTFkNTE5NzRmZTkzZDQwZDI3NzMzZTA0NjNAMDAwMDAwMDAwMDAwMDAwMDA1MDBkMTJjYzczY2JkYTZmMjY1OWM5NTllNWQ1NzU4YWY5MmNhMTM4NDg2NTIzM0AwMDAwMDAwMDAwMDAwMDAwMDUwMDUxZGY3MTc1OGNmMmFjYTViNDZkZWQ4MTU1OGI1NTE1ZGMyOWYzZjM1MjMzQEAwMDAwMDAwMDAwMDAwMDAwMDUwMDdlNGExZGZjNDM3Y2VkNDlkYjlmMTYzNzk4NDE2Yjg0YWMyMWQ0Yzk3Y2ViMDAwMDAwMGM1NzQ1NDc0YzQ0MmQ2MTMyMzg2MzM1MzkwMDAwMDAwMDAwMDAwMDAwMDUwMGE4YmE5ZTY4NjI2YmJjOTkzZmQ3OTVlOGJiNmY0Nzk0M2IyZjVmZmE3Y2ViMDAwMDAwMGE1NTU0NGIyZDMxMzQ2NDM1Mzc2NEAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwNTAwNTFkZjcxNzU4Y2YyYWNhNWI0NmRlZDgxNTU4YjU1MTVkYzI5ZjNmMzUyMzMwMDAwMDAwYjQyNTU1MzQ0MmQ2NDM0NjMzMDMxMzQwMDAwMDAwMDAwQDAxODZhMEAyNzEw", + "signature": "4648af0b96eb430e4986b9fb760549742de09c809b46b984e5d995c898d80c25bfc0717c30da34bd89cd3005d98ee895afa39ee588b7b74b4807c63cbeade807", + "sourceShard": 1, + "destinationShard": 1, + "blockNonce": 1785520, + "blockHash": "8f926a5d79fa84bc69949a21bfbba17447091a8a074ac172fa0b88e4475a1214", + "notarizedAtSourceInMetaNonce": 1785568, + "NotarizedAtSourceInMetaHash": "eebd1aa5c3dde083f9c367242c054affedd36bfc95f7bcc1d4e2d90beb5754e9", + "notarizedAtDestinationInMetaNonce": 1785568, + "notarizedAtDestinationInMetaHash": "eebd1aa5c3dde083f9c367242c054affedd36bfc95f7bcc1d4e2d90beb5754e9", + "miniblockType": "TxBlock", + "miniblockHash": "b85d82db6d69cbc1911b3455d2837eeb3170b391926efa2eacb4d9c8e3c96ee4", + "hyperblockNonce": 1785568, + "hyperblockHash": "eebd1aa5c3dde083f9c367242c054affedd36bfc95f7bcc1d4e2d90beb5754e9", + "timestamp": 1704722558, + "smartContractResults": [ + { + "hash": "ea9a96c079e66249e6b73c0341991dad96ca81f855f2fc4abe0d432be117a882", + "nonce": 420, + "value": 4427790720000000, + "receiver": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "data": "@6f6b", + "prevTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", + "originalTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "operation": "transfer", + "isRefund": true + }, + { + "hash": "6082975132a2c9d8197dfd0f9852b454ad344740eebdbdf93f620b2796ab723b", + "nonce": 0, + "value": 50000000000000000, + "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "data": "registerMetaESDT@415453417368537761704c5041435661756c74@4156415348@12@63616e467265657a65@66616c7365@63616e57697065@66616c7365@63616e5061757365@66616c7365@63616e5472616e736665724e4654437265617465526f6c65@66616c7365@63616e4368616e67654f776e6572@66616c7365@63616e55706772616465@66616c7365@63616e4164645370656369616c526f6c6573@74727565@9eb30a87c92674ab1469700c0b385b3850e86de80f87dec6cf3213c7e379a646@408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43@03eb4a30", + "prevTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", + "originalTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", + "gasLimit": 125751600, + "gasPrice": 1000000000, + "callType": 1, + "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "operation": "transfer", + "function": "registerMetaESDT" + }, + { + "hash": "290f85d7ec2f7d5797510290358e9e0f76bb880451efaacb0d69280b8d94c67a", + "nonce": 0, + "value": 0, + "receiver": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "ESDTSetBurnRoleForAll@41564153482d376438623564", + "prevTxHash": "6082975132a2c9d8197dfd0f9852b454ad344740eebdbdf93f620b2796ab723b", + "originalTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "logs": { + "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", + "events": [ + { + "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqsl6e366", + "identifier": "completedTxEvent", + "topics": [ + "YIKXUTKiydgZff0PmFK0VK00R0Duvb35P2ILJ5arcjs=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "transfer" + }, + { + "hash": "1aa62a6251edd216bd4e5ae59f7e676d5d2f88597685e0ec0e25ac4434bfccdb", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "@00@41564153482d376438623564@d0644194444642fd16ee156307f6fda0e8f8baf4c496e1a1dc85e027ecc08a4a@9eb30a87c92674ab1469700c0b385b3850e86de80f87dec6cf3213c7e379a646@408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43@00", + "prevTxHash": "6082975132a2c9d8197dfd0f9852b454ad344740eebdbdf93f620b2796ab723b", + "originalTxHash": "408433c5db749f4666bee6a8b599944071bf493c43ff5f01282a74c22ea2ea43", + "gasLimit": 75751600, + "gasPrice": 1000000000, + "callType": 2, + "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "writeLog", + "topics": [ + "AAAAAAAAAAAFAH6UefeHERqHcLpMz2gC3xXGhFsJBGM=", + "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNzU3NTE2MDAsIGdhcyB1c2VkID0gNDE3NjA1OQ==" + ], + "data": "QDZmNmI=", + "additionalData": [ + "QDZmNmI=" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "completedTxEvent", + "topics": [ + "YIKXUTKiydgZff0PmFK0VK00R0Duvb35P2ILJ5arcjs=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "transfer" + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "transferValueOnly", + "topics": [ + "", + "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=" + ], + "data": "RGVwbG95RnJvbVNvdXJjZQ==", + "additionalData": [ + "RGVwbG95RnJvbVNvdXJjZQ==", + "aW5pdA==", + "QUxQLWNhZWFjNQ==", + "QVRTLTRjMDkyMA==", + "A+g=", + "A+g=", + "", + "O5rKAA==" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "transferValueOnly", + "topics": [ + "", + "AAAAAAAAAAAFADJ0SE0vUW6bO5SurLeFIMfK/HtBBGM=" + ], + "data": "RGVwbG95RnJvbVNvdXJjZQ==", + "additionalData": [ + "RGVwbG95RnJvbVNvdXJjZQ==", + "aW5pdA==", + "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=", + "AAAAAAAAAAAFAJVzkK7aQy9SpBHVGXT+k9QNJ3M+BGM=", + "AAAAAAAAAAAFANEsxzy9pvJlnJWeXVdYr5LKE4SGUjM=", + "AAAAAAAAAAAFAFHfcXWM8qyltG3tgVWLVRXcKfPzUjM=", + "", + "AAAAAAAAAAAFAH5KHfxDfO1J258WN5hBa4SsIdTJfOsAAAAMV0VHTEQtYTI4YzU5AAAAAAAAAAAFAKi6nmhia7yZP9eV6LtvR5Q7L1/6fOsAAAAKVVRLLTE0ZDU3ZA==", + "AAAAAQAAAAAAAAAABQBR33F1jPKspbRt7YFVi1UV3Cnz81IzAAAAC0JVU0QtZDRjMDE0AAAAAAA=", + "AYag", + "JxA=" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqxf6ysnf029hfkwu546kt0pfqcl90c76pq33s0a320f", + "identifier": "transferValueOnly", + "topics": [ + "", + "AAAAAAAAAAAFANEsxzy9pvJlnJWeXVdYr5LKE4SGUjM=" + ], + "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "additionalData": [ + "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "Z2V0RmFybWluZ1Rva2VuSWQ=" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqxf6ysnf029hfkwu546kt0pfqcl90c76pq33s0a320f", + "identifier": "transferValueOnly", + "topics": [ + "", + "AAAAAAAAAAAFANEsxzy9pvJlnJWeXVdYr5LKE4SGUjM=" + ], + "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "additionalData": [ + "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "Z2V0RmFybVRva2VuSWQ=" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqxf6ysnf029hfkwu546kt0pfqcl90c76pq33s0a320f", + "identifier": "transferValueOnly", + "topics": [ + "", + "AAAAAAAAAAAFANEsxzy9pvJlnJWeXVdYr5LKE4SGUjM=" + ], + "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "additionalData": [ + "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "Z2V0UmV3YXJkVG9rZW5JZA==" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "transferValueOnly", + "topics": [ + "saK8LsUAAA==", + "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=" + ], + "data": "QXN5bmNDYWxs", + "additionalData": [ + "QXN5bmNDYWxs", + "cmVnaXN0ZXJNZXRhRVNEVA==", + "QVRTQXNoU3dhcExQQUNWYXVsdA==", + "QVZBU0g=", + "Eg==", + "Y2FuRnJlZXpl", + "ZmFsc2U=", + "Y2FuV2lwZQ==", + "ZmFsc2U=", + "Y2FuUGF1c2U=", + "ZmFsc2U=", + "Y2FuVHJhbnNmZXJORlRDcmVhdGVSb2xl", + "ZmFsc2U=", + "Y2FuQ2hhbmdlT3duZXI=", + "ZmFsc2U=", + "Y2FuVXBncmFkZQ==", + "ZmFsc2U=", + "Y2FuQWRkU3BlY2lhbFJvbGVz", + "dHJ1ZQ==" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqxf6ysnf029hfkwu546kt0pfqcl90c76pq33s0a320f", + "identifier": "SCDeploy", + "topics": [ + "AAAAAAAAAAAFADJ0SE0vUW6bO5SurLeFIMfK/HtBBGM=", + "AAAAAAAAAAAFAH6UefeHERqHcLpMz2gC3xXGhFsJBGM=", + "fvRqbue54Womde/CN2IkRGkrx8tsU+xkLvi3+uwMkhY=" + ], + "data": null, + "additionalData": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", + "identifier": "SCDeploy", + "topics": [ + "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=", + "AAAAAAAAAAAFAH6UefeHERqHcLpMz2gC3xXGhFsJBGM=", + "E3blQfRJfCKLWDr06Od703DSZenIzq8KND+xUjmGY/M=" + ], + "data": null, + "additionalData": null + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "deployAshswapLPACStrategy", + "initiallyPaidFee": "6936045000000000", + "fee": "2508254280000000", + "chainID": "D", + "version": 1, + "options": 0 + } + }, + "error": "", + "code": "successful" +} + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Option = Some("AVASH-7d8b5d".to_string()); + + assert_eq!(tx_response.new_issued_token_identifier, expected) +} + +#[test] +fn test_set_special_roles_should_not_process_issued_token_identifier() { + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", + "nonce": 420, + "round": 1787109, + "epoch": 744, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "sender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "gasPrice": 1000000000, + "gasLimit": 600000000, + "gasUsed": 129636807, + "data": "ZmluaXNoVmF1bHREZXBsb3ltZW50cw==", + "signature": "dca943ef1a788bfa6cb0e9aa3900b8340e4908075cbfefaa2a66688f6f0c0fed349edb2eb48eec427cd9098822fba875e4d66072fbdb44cb7f4c1a416736e20c", + "sourceShard": 1, + "destinationShard": 1, + "blockNonce": 1785536, + "blockHash": "93ca539e81612768b67a85b7135f7c104e76bec031a758a6b1782910ae49dd8f", + "notarizedAtSourceInMetaNonce": 1785584, + "NotarizedAtSourceInMetaHash": "71d17afe660282bb42de1ea3eec3e3534a179bd32aa1471c2861ce411bf30552", + "notarizedAtDestinationInMetaNonce": 1785584, + "notarizedAtDestinationInMetaHash": "71d17afe660282bb42de1ea3eec3e3534a179bd32aa1471c2861ce411bf30552", + "miniblockType": "TxBlock", + "miniblockHash": "f8c60565af746e92d2c9c09a92734e5eb8da7e42c67a86854c93b349bfe287eb", + "hyperblockNonce": 1785584, + "hyperblockHash": "71d17afe660282bb42de1ea3eec3e3534a179bd32aa1471c2861ce411bf30552", + "timestamp": 1704722654, + "smartContractResults": [ + { + "hash": "c3ce9c364de3823ffae250c2bfb40aaf2b18f771ed4bd37bf788ad83a2c651f3", + "nonce": 421, + "value": 4703631930000000, + "receiver": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "data": "@6f6b", + "prevTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", + "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "operation": "transfer", + "isRefund": true + }, + { + "hash": "50f9c25a1402ce6d87ae9f890659c8a67462292e471e02c74d64ff7ba1995e60", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "data": "setSpecialRole@41564153482d376438623564@00000000000000000500d00cc0e63887ff6b792d34234a44e7ac6b575d4b0463@45534454526f6c654e4654437265617465@45534454526f6c654e46544164645175616e74697479@45534454526f6c654e46544275726e@0192c6db2c69f50b6968fb22ac558337a851719519cfd1e6bbf79a07bbcf18bc@cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0@03eb4a30", + "prevTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", + "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", + "gasLimit": 125751600, + "gasPrice": 1000000000, + "callType": 1, + "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "operation": "transfer", + "function": "setSpecialRole" + }, + { + "hash": "d6a5824a60b6c9050462c3f5a02ace00c36e8b4ba1958d132bd394e2ed1e7226", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "ESDTSetRole@41564153482d376438623564@45534454526f6c654e4654437265617465@45534454526f6c654e46544164645175616e74697479@45534454526f6c654e46544275726e", + "prevTxHash": "50f9c25a1402ce6d87ae9f890659c8a67462292e471e02c74d64ff7ba1995e60", + "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", + "identifier": "ESDTSetRole", + "topics": [ + "QVZBU0gtN2Q4YjVk", + "", + "", + "RVNEVFJvbGVORlRDcmVhdGU=", + "RVNEVFJvbGVORlRBZGRRdWFudGl0eQ==", + "RVNEVFJvbGVORlRCdXJu" + ], + "data": null, + "additionalData": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgq6qxvpe3csllkk7fdxs3553884344wh2tq33sakulat", + "identifier": "completedTxEvent", + "topics": [ + "UPnCWhQCzm2Hrp+JBlnIpnRiKS5HHgLHTWT/e6GZXmA=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "ESDTSetRole", + "function": "ESDTSetRole" + }, + { + "hash": "bf1b8b4b301ff548368dfd972896489d5e2a088d5cbdfa1bfe2421cc7f641f7a", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "@00@a68d44c751eba85db0713db8dc9c10c78749189ec0d6f1af5fc67bb656c1254b@0192c6db2c69f50b6968fb22ac558337a851719519cfd1e6bbf79a07bbcf18bc@cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0@00", + "prevTxHash": "50f9c25a1402ce6d87ae9f890659c8a67462292e471e02c74d64ff7ba1995e60", + "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", + "gasLimit": 75751600, + "gasPrice": 1000000000, + "callType": 2, + "originalSender": "erd1j6kua7p67qnaw3y4sudmk25xsuv4k8ws6pwvax8fd2vtmuc3q33s840l87", + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "transferValueOnly", + "topics": [ + "", + "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=" + ], + "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "additionalData": [ + "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "c2V0U2hhcmVUb2tlbklkZW50aWZpZXI=", + "QVZBU0gtN2Q4YjVk" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "transferValueOnly", + "topics": [ + "", + "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=" + ], + "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "additionalData": [ + "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "c2V0U3RyYXRlZ3lBZGRyZXNz", + "AAAAAAAAAAAFADJ0SE0vUW6bO5SurLeFIMfK/HtBBGM=" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "completedTxEvent", + "topics": [ + "UPnCWhQCzm2Hrp+JBlnIpnRiKS5HHgLHTWT/e6GZXmA=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "transfer" + }, + { + "hash": "9d75a398545f488d4764149245e6ec3101debfce99477c353ac11c3239acd897", + "nonce": 1, + "value": 648519550000000, + "receiver": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "sender": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "data": "@6f6b", + "prevTxHash": "bf1b8b4b301ff548368dfd972896489d5e2a088d5cbdfa1bfe2421cc7f641f7a", + "originalTxHash": "cbb1f866da564a04332297dfc4f637be2e50e62bbf4441bf42247ad429747ce0", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "operation": "transfer", + "isRefund": true + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "transferValueOnly", + "topics": [ + "", + "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=" + ], + "data": "QXN5bmNDYWxs", + "additionalData": [ + "QXN5bmNDYWxs", + "c2V0U3BlY2lhbFJvbGU=", + "QVZBU0gtN2Q4YjVk", + "AAAAAAAAAAAFANAMwOY4h/9reS00I0pE56xrV11LBGM=", + "RVNEVFJvbGVORlRDcmVhdGU=", + "RVNEVFJvbGVORlRBZGRRdWFudGl0eQ==", + "RVNEVFJvbGVORlRCdXJu" + ] + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "finishVaultDeployments", + "initiallyPaidFee": "6082170000000000", + "fee": "1378538070000000", + "chainID": "D", + "version": 1, + "options": 0 + } + }, + "error": "", + "code": "successful" +} + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Option = None; + + assert_eq!(tx_response.new_issued_token_identifier, expected) +} + +#[test] +fn test_multisig_issue_nft_and_set_all_roles() { + let data = r#" +{ + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "08582bc19734ad82d7390be88463c948e5d9f026f4b8f0bfc57620957c3433bd", + "nonce": 53, + "round": 3050972, + "epoch": 1246, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "sender": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "gasPrice": 1000000000, + "gasLimit": 80000000, + "gasUsed": 80000000, + "data": "cGVyZm9ybUFjdGlvbkAwMQ==", + "signature": "cb67645595cee5f7967d8d85af05bb7db73e80d9b97611796819249d87cd174b69b4abfc2a3fbe52df1aec965bdea921f7eb34d2b1118aa480699ad1dc85790a", + "sourceShard": 0, + "destinationShard": 0, + "blockNonce": 2984930, + "blockHash": "644ae8703b826a23e89429953919ec37f875e34a547ea9f7edd53fb71a99c746", + "notarizedAtSourceInMetaNonce": 2988311, + "NotarizedAtSourceInMetaHash": "4f608a72e654dd9f466801cd489be8ee1a73fbcd77b128559cd46182d3b9455a", + "notarizedAtDestinationInMetaNonce": 2988311, + "notarizedAtDestinationInMetaHash": "4f608a72e654dd9f466801cd489be8ee1a73fbcd77b128559cd46182d3b9455a", + "miniblockType": "TxBlock", + "miniblockHash": "c5a73671bc1d37835ddd15b926157721bc83203ec4e00cd48ae0d46015cb5f0b", + "hyperblockNonce": 2988311, + "hyperblockHash": "4f608a72e654dd9f466801cd489be8ee1a73fbcd77b128559cd46182d3b9455a", + "timestamp": 1712305832, + "smartContractResults": [ + { + "hash": "b0b3c8df519c33b314c0ee3d25abae6f17c4432fb3382676ce17a42690811cff", + "nonce": 0, + "value": 50000000000000000, + "receiver": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "sender": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "data": "registerAndSetAllRoles@54657374436f6c6c656374696f6e31@54455354434f4c4c31@4e4654@@98fa4ff554b9c6990ce577fbb816a271f690dcbd6b148f6583fe7692868ae538@08582bc19734ad82d7390be88463c948e5d9f026f4b8f0bfc57620957c3433bd@5e2338", + "prevTxHash": "08582bc19734ad82d7390be88463c948e5d9f026f4b8f0bfc57620957c3433bd", + "originalTxHash": "08582bc19734ad82d7390be88463c948e5d9f026f4b8f0bfc57620957c3433bd", + "gasLimit": 73052300, + "gasPrice": 1000000000, + "callType": 1, + "originalSender": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "operation": "transfer", + "function": "registerAndSetAllRoles" + }, + { + "hash": "5ae4f74e134e4fa63c8b92e06ff12b2a4b544233d01d80db6a922af35ee55356", + "nonce": 1, + "value": 196430610000000, + "receiver": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "sender": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "data": "@6f6b", + "prevTxHash": "c4a24b01b48d32308636310e2d335d6ed1f34dcbdfc1133aed7995e78e831c18", + "originalTxHash": "08582bc19734ad82d7390be88463c948e5d9f026f4b8f0bfc57620957c3433bd", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "operation": "transfer", + "isRefund": true + }, + { + "hash": "7589c1ad622d8a9ab2f186731fc82aeeab0aea5a8198cb94b6eba85a966e7962", + "nonce": 0, + "value": 0, + "receiver": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqq2m3f0f", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "ESDTSetBurnRoleForAll@54455354434f4c4c312d356161383063", + "prevTxHash": "b0b3c8df519c33b314c0ee3d25abae6f17c4432fb3382676ce17a42690811cff", + "originalTxHash": "08582bc19734ad82d7390be88463c948e5d9f026f4b8f0bfc57620957c3433bd", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "originalSender": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "logs": { + "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqq2m3f0f", + "events": [ + { + "address": "erd1llllllllllllllllllllllllllllllllllllllllllllllllluqq2m3f0f", + "identifier": "completedTxEvent", + "topics": [ + "sLPI31GcM7MUwO49JauubxfEQy+zOCZ2zhekJpCBHP8=" + ] + } + ] + }, + "operation": "transfer" + }, + { + "hash": "86d1ec3365ea1311dbde2f2366de4ea8627d7e49c29a974578c0869b66903cbc", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "ESDTSetRole@54455354434f4c4c312d356161383063@45534454526f6c654e4654437265617465@45534454526f6c654e46544275726e@45534454526f6c654e465455706461746541747472696275746573@45534454526f6c654e4654416464555249", + "prevTxHash": "b0b3c8df519c33b314c0ee3d25abae6f17c4432fb3382676ce17a42690811cff", + "originalTxHash": "08582bc19734ad82d7390be88463c948e5d9f026f4b8f0bfc57620957c3433bd", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "originalSender": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "identifier": "ESDTSetRole", + "topics": [ + "VEVTVENPTEwxLTVhYTgwYw==", + "", + "", + "RVNEVFJvbGVORlRDcmVhdGU=", + "RVNEVFJvbGVORlRCdXJu", + "RVNEVFJvbGVORlRVcGRhdGVBdHRyaWJ1dGVz", + "RVNEVFJvbGVORlRBZGRVUkk=" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "identifier": "completedTxEvent", + "topics": [ + "sLPI31GcM7MUwO49JauubxfEQy+zOCZ2zhekJpCBHP8=" + ] + } + ] + }, + "operation": "ESDTSetRole", + "function": "ESDTSetRole" + }, + { + "hash": "c4a24b01b48d32308636310e2d335d6ed1f34dcbdfc1133aed7995e78e831c18", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "sender": "erd1qqqqqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzllls8a5w6u", + "data": "@00@54455354434f4c4c312d356161383063@3ec73c55022548038bbe06c0639156b3db70b7c770955e340f14fcfcd45df06a@98fa4ff554b9c6990ce577fbb816a271f690dcbd6b148f6583fe7692868ae538@08582bc19734ad82d7390be88463c948e5d9f026f4b8f0bfc57620957c3433bd@00", + "prevTxHash": "b0b3c8df519c33b314c0ee3d25abae6f17c4432fb3382676ce17a42690811cff", + "originalTxHash": "08582bc19734ad82d7390be88463c948e5d9f026f4b8f0bfc57620957c3433bd", + "gasLimit": 23052300, + "gasPrice": 1000000000, + "callType": 2, + "originalSender": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "identifier": "callBack", + "topics": [ + "YXN5bmNDYWxsU3VjY2Vzcw==", + "VEVTVENPTEwxLTVhYTgwYw==" + ], + "additionalData": [ + "" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "identifier": "completedTxEvent", + "topics": [ + "sLPI31GcM7MUwO49JauubxfEQy+zOCZ2zhekJpCBHP8=" + ] + } + ] + }, + "operation": "transfer" + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "identifier": "performAction", + "topics": [ + "c3RhcnRQZXJmb3JtQWN0aW9u" + ], + "data": "AAAAAQYAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAL//wAAAAexorwuxQAAAAAAFnJlZ2lzdGVyQW5kU2V0QWxsUm9sZXMAAAAEAAAAD1Rlc3RDb2xsZWN0aW9uMQAAAAlURVNUQ09MTDEAAAADTkZUAAAAAAAAAATjKv7ckE/hk5dGrZc76zg1Y89jZCumabMED5uUKKXtYLE6AXQjw2bK/4zs+3ehJhChMPSIgTQSLHk3/q4NbX0XOvjZyUI7JXfGJSciwdkCEqQRH3ID+XRPdvz6HQoxADOyoRVVzlIeSUTgmrF1SdhbSH3NJshLUBejnjGjZwiJug==", + "additionalData": [ + "AAAAAQYAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAL//wAAAAexorwuxQAAAAAAFnJlZ2lzdGVyQW5kU2V0QWxsUm9sZXMAAAAEAAAAD1Rlc3RDb2xsZWN0aW9uMQAAAAlURVNUQ09MTDEAAAADTkZUAAAAAAAAAATjKv7ckE/hk5dGrZc76zg1Y89jZCumabMED5uUKKXtYLE6AXQjw2bK/4zs+3ehJhChMPSIgTQSLHk3/q4NbX0XOvjZyUI7JXfGJSciwdkCEqQRH3ID+XRPdvz6HQoxADOyoRVVzlIeSUTgmrF1SdhbSH3NJshLUBejnjGjZwiJug==" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "identifier": "performAction", + "topics": [ + "cGVyZm9ybUFzeW5jQ2FsbA==", + "AQ==", + "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=", + "saK8LsUAAA==", + "BGa4HQ==", + "cmVnaXN0ZXJBbmRTZXRBbGxSb2xlcw==", + "VGVzdENvbGxlY3Rpb24x", + "VEVTVENPTEwx", + "TkZU", + "" + ], + "additionalData": [ + "" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "identifier": "transferValueOnly", + "topics": [ + "saK8LsUAAA==", + "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAC//8=" + ], + "data": "QXN5bmNDYWxs", + "additionalData": [ + "QXN5bmNDYWxs", + "cmVnaXN0ZXJBbmRTZXRBbGxSb2xlcw==", + "VGVzdENvbGxlY3Rpb24x", + "VEVTVENPTEwx", + "TkZU", + "" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqrp3n58vp2dmcaur4whazxngvuhac4xwqa4sq2pjl73", + "identifier": "writeLog", + "topics": [ + "4yr+3JBP4ZOXRq2XO+s4NWPPY2QrpmmzBA+blCil7WA=" + ], + "data": "QDZmNmI=", + "additionalData": [ + "QDZmNmI=" + ] + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "performAction", + "initiallyPaidFee": "873260000000000", + "fee": "873260000000000", + "chainID": "D", + "version": 1, + "options": 0 + } + }, + "code": "successful" +} + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected = Some("TESTCOLL1-5aa80c".to_string()); + + assert_eq!(tx_response.new_issued_token_identifier, expected) +} diff --git a/framework/snippets/tests/test_tx_multi_contract_sc_result.rs b/framework/snippets/tests/test_tx_multi_contract_sc_result.rs new file mode 100644 index 0000000000..a9b64d8941 --- /dev/null +++ b/framework/snippets/tests/test_tx_multi_contract_sc_result.rs @@ -0,0 +1,477 @@ +use multiversx_sc_snippets::network_response; +use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; + +#[test] +fn test_with_multi_contract_same_shard_tx_that_has_no_sc_result() { + // transaction data from the devnet + // context : user -> A --call--> B, B returns a MultiValue2, A returns the B's returned value + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "e914857f1bfd003ba411bae372266703e5f706fa412c378feb37faa5e18c3d73", + "nonce": 49, + "round": 7646960, + "epoch": 6339, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgqshqmekudxlxwp0d9j368etjamr5dw7k45u7qx40w6h", + "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", + "gasPrice": 1000000000, + "gasLimit": 600000000, + "gasUsed": 600000000, + "data": "Y2FsbEFub3RoZXJDb250cmFjdFJldHVyblR3b1U2NEAwMDAwMDAwMDAwMDAwMDAwMDUwMEFDRkY2QjdBNEVCODEwMUE4REU3RkY3RjVEMkMwQkYzRTRENjNGNDdBNzND", + "signature": "53cc6496647287d735bd7950f4ec79d7b51f884defda1d6d840d722b7d0d869900ccecc01602da7a7c717955e8d4ed0711b92acd980d64ed6eebd6eaed0c4608", + "sourceShard": 0, + "destinationShard": 0, + "blockNonce": 7600794, + "blockHash": "77eb0904e56d6dd596c0d72821cf33b326fde383e72903ca4df5c2f200b0ea75", + "notarizedAtSourceInMetaNonce": 7609344, + "NotarizedAtSourceInMetaHash": "12df3fe65cacde2c9742b9506ac2261d34f3c72d690301192fd8016430d51913", + "notarizedAtDestinationInMetaNonce": 7609344, + "notarizedAtDestinationInMetaHash": "12df3fe65cacde2c9742b9506ac2261d34f3c72d690301192fd8016430d51913", + "miniblockType": "TxBlock", + "miniblockHash": "03219ac7427f7511687f0768c722c759c1b1428b2664b44a0cbe2072154851ee", + "hyperblockNonce": 7609344, + "hyperblockHash": "12df3fe65cacde2c9742b9506ac2261d34f3c72d690301192fd8016430d51913", + "timestamp": 1694433360, + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqshqmekudxlxwp0d9j368etjamr5dw7k45u7qx40w6h", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqshqmekudxlxwp0d9j368etjamr5dw7k45u7qx40w6h", + "identifier": "writeLog", + "topics": [ + "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=", + "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk5ODA2MDAwLCBnYXMgdXNlZCA9IDM4NDcyNDA=" + ], + "data": "QDZmNmJAMGFAMDIxODcxMWEwMA==" + }, + { + "address": "erd1qqqqqqqqqqqqqpgqshqmekudxlxwp0d9j368etjamr5dw7k45u7qx40w6h", + "identifier": "completedTxEvent", + "topics": [ + "6RSFfxv9ADukEbrjciZnA+X3BvpBLDeP6zf6peGMPXM=" + ], + "data": null + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "callAnotherContractReturnTwoU64", + "initiallyPaidFee": "6192060000000000", + "fee": "6192060000000000", + "chainID": "D", + "version": 2, + "options": 0 + } + }, + "error": "", + "code": "successful" + } + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Vec> = vec![ + hex::decode("0a").unwrap(), + hex::decode("0218711a00").unwrap(), + ]; + + assert_eq!(tx_response.out, expected) +} + +#[test] +fn test_with_multi_contract_cross_shard_tx_that_has_no_callback() { + // transaction data from the devnet + // context : user -> A --async call--> B, no callback + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "4d50a055663dfee2479851684d7fb83cf00695b6f03f4dbbdf0f9232477cafc4", + "nonce": 51, + "round": 7647523, + "epoch": 6340, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", + "gasPrice": 1000000000, + "gasLimit": 600000000, + "gasUsed": 600000000, + "data": "YXN5bmNDYWxsQW5vdGhlckNvbnRyYWN0UmV0dXJuVHdvVTY0Tm9DYWxsYmFja0AwMDAwMDAwMDAwMDAwMDAwMDUwMEFDRkY2QjdBNEVCODEwMUE4REU3RkY3RjVEMkMwQkYzRTRENjNGNDdBNzND", + "signature": "0fc30cddaa8e5365662a14344e3434cbccf287f357be99b3ed4add182f64dded774ec0d095ab1589e7c6c07e00de3b7239efc96eb2e0e97b48c1ef87084cec01", + "sourceShard": 0, + "destinationShard": 1, + "blockNonce": 7593758, + "blockHash": "a828c0ca58ef1c8aff60e512ab59f18204f1915d4a6c8285cfceb1c5725b88e8", + "notarizedAtSourceInMetaNonce": 7609903, + "NotarizedAtSourceInMetaHash": "4e90fe45c2fdccd5cf6977c1422e5f4ffa41c4e9f31fb4a50c20455f87df1e99", + "notarizedAtDestinationInMetaNonce": 7609907, + "notarizedAtDestinationInMetaHash": "10b8666a44411c3babbe20af7154fb3d47efcb1cb10d955523ec68fece26e517", + "miniblockType": "TxBlock", + "miniblockHash": "4ff4bb1ac88911d617c9b0342aeb5158db78490c2fe414cad08adcc584a77be7", + "hyperblockNonce": 7609907, + "hyperblockHash": "10b8666a44411c3babbe20af7154fb3d47efcb1cb10d955523ec68fece26e517", + "timestamp": 1694436738, + "smartContractResults": [ + { + "hash": "462b56a1530e6070dc7c15f755e51a97a6972c8cd7891f3be4635b93211890c5", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "sender": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "data": "@00@0a@0218711a00", + "prevTxHash": "41d56fdacf3e14de67e821427c732b62ebfa07c82d2e5db6de75fe3a1c828d9b", + "originalTxHash": "4d50a055663dfee2479851684d7fb83cf00695b6f03f4dbbdf0f9232477cafc4", + "gasLimit": 595637825, + "gasPrice": 1000000000, + "callType": 2, + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "identifier": "writeLog", + "topics": [ + "AAAAAAAAAAAFAP/Aj4ZNGKlpx2+xeJLdoJbREzb20P0=", + "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk1NjM3ODI1LCBnYXMgdXNlZCA9IDIxNjE3NzA=" + ], + "data": "QDZmNmI=" + }, + { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "identifier": "completedTxEvent", + "topics": [ + "QdVv2s8+FN5n6CFCfHMrYuv6B8gtLl223nX+OhyCjZs=" + ], + "data": null + } + ] + }, + "operation": "transfer" + }, + { + "hash": "41d56fdacf3e14de67e821427c732b62ebfa07c82d2e5db6de75fe3a1c828d9b", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "sender": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "data": "returnTwoU64@4f3c60", + "prevTxHash": "4d50a055663dfee2479851684d7fb83cf00695b6f03f4dbbdf0f9232477cafc4", + "originalTxHash": "4d50a055663dfee2479851684d7fb83cf00695b6f03f4dbbdf0f9232477cafc4", + "gasLimit": 597479490, + "gasPrice": 1000000000, + "callType": 1, + "operation": "transfer", + "function": "returnTwoU64" + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "identifier": "writeLog", + "topics": [ + "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=" + ], + "data": "QDZmNmI=" + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "asyncCallAnotherContractReturnTwoU64NoCallback", + "initiallyPaidFee": "6214335000000000", + "fee": "6214335000000000", + "chainID": "D", + "version": 2, + "options": 0 + } + }, + "error": "", + "code": "successful" + } + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Vec> = vec![]; + + assert_eq!(tx_response.out, expected) +} + +#[test] +fn test_with_multi_contract_cross_shard_tx_that_has_non_returning_callback() { + // transaction data from the devnet + // context : user -> A --async call--> B --callback--> A, the callback returns () + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "4f7f19e448176e4d47a0f844cbd6bdb1b6c68035dafe927e8249ed60af1c3b17", + "nonce": 52, + "round": 7647560, + "epoch": 6340, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", + "gasPrice": 1000000000, + "gasLimit": 600000000, + "gasUsed": 600000000, + "data": "YXN5bmNDYWxsQW5vdGhlckNvbnRyYWN0UmV0dXJuVHdvVTY0V2l0aE5vblJldHVybmluZ0NhbGxiYWNrQDAwMDAwMDAwMDAwMDAwMDAwNTAwQUNGRjZCN0E0RUI4MTAxQThERTdGRjdGNUQyQzBCRjNFNEQ2M0Y0N0E3M0M=", + "signature": "3918fce429b2059b2321b709011079755dbb835e12839278ee510e4741180540e80c6111eea1d3312b2c63446de08b20e01f6040358fa94d1633c355bb65bc0f", + "sourceShard": 0, + "destinationShard": 1, + "blockNonce": 7593795, + "blockHash": "c17e727f90025225670b7852ea9807c67753c9b3f21b6ec7cc40077e3849a8b7", + "notarizedAtSourceInMetaNonce": 7609940, + "NotarizedAtSourceInMetaHash": "c67b5c550986cfd6c94d00f4b90234eb38ee196ff0d79a00d916f3bd24be272c", + "notarizedAtDestinationInMetaNonce": 7609944, + "notarizedAtDestinationInMetaHash": "d59b7398d962ce3119679af59d5d74e10083e62c3ee2b15421cc0d607979ca18", + "miniblockType": "TxBlock", + "miniblockHash": "2977affeffeb6cf41117bed442662021cb713528cdb1d0dce4537b01caeb8e0b", + "hyperblockNonce": 7609944, + "hyperblockHash": "d59b7398d962ce3119679af59d5d74e10083e62c3ee2b15421cc0d607979ca18", + "timestamp": 1694436960, + "smartContractResults": [ + { + "hash": "fe7474188d5ca4b84c7577f03fc778d22d53c070dfcb05a9cda840229d30e4d3", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "sender": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "data": "returnTwoU64@4f3c60", + "prevTxHash": "4f7f19e448176e4d47a0f844cbd6bdb1b6c68035dafe927e8249ed60af1c3b17", + "originalTxHash": "4f7f19e448176e4d47a0f844cbd6bdb1b6c68035dafe927e8249ed60af1c3b17", + "gasLimit": 596979545, + "gasPrice": 1000000000, + "callType": 1, + "operation": "transfer", + "function": "returnTwoU64" + }, + { + "hash": "948dc6702b376d1e043db8de2f87ca12907c342f54cfad7dfebadf59145ca3ac", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "sender": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "data": "@00@0a@0218711a00", + "prevTxHash": "fe7474188d5ca4b84c7577f03fc778d22d53c070dfcb05a9cda840229d30e4d3", + "originalTxHash": "4f7f19e448176e4d47a0f844cbd6bdb1b6c68035dafe927e8249ed60af1c3b17", + "gasLimit": 595137880, + "gasPrice": 1000000000, + "callType": 2, + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "identifier": "writeLog", + "topics": [ + "AAAAAAAAAAAFAP/Aj4ZNGKlpx2+xeJLdoJbREzb20P0=", + "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk1MTM3ODgwLCBnYXMgdXNlZCA9IDIyODg1NTA=" + ], + "data": "QDZmNmJAMGFAMDIxODcxMWEwMA==" + }, + { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "identifier": "completedTxEvent", + "topics": [ + "/nR0GI1cpLhMdXfwP8d40i1TwHDfywWpzahAIp0w5NM=" + ], + "data": null + } + ] + }, + "operation": "transfer" + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "identifier": "writeLog", + "topics": [ + "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=" + ], + "data": "QDZmNmI=" + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "asyncCallAnotherContractReturnTwoU64WithNonReturningCallback", + "initiallyPaidFee": "6235125000000000", + "fee": "6235125000000000", + "chainID": "D", + "version": 2, + "options": 0 + } + }, + "error": "", + "code": "successful" + } + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Vec> = vec![]; + + assert_eq!(tx_response.out, expected) +} + +#[test] +fn test_with_multi_contract_cross_shard_tx_that_has_returning_callback() { + // transaction data from the devnet + // context : user -> A --async call--> B --callback--> A, the callback returns a MultiValue2 + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "f34e136ca81c0e32f6fb532b753612715675073f3718b5db009bb275d246fd7a", + "nonce": 53, + "round": 7647583, + "epoch": 6340, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", + "gasPrice": 1000000000, + "gasLimit": 600000000, + "gasUsed": 600000000, + "data": "YXN5bmNDYWxsQW5vdGhlckNvbnRyYWN0UmV0dXJuVHdvVTY0V2l0aFJldHVybmluZ0NhbGxiYWNrQDAwMDAwMDAwMDAwMDAwMDAwNTAwQUNGRjZCN0E0RUI4MTAxQThERTdGRjdGNUQyQzBCRjNFNEQ2M0Y0N0E3M0M=", + "signature": "858958d4aaf9cb0220ab2933edad3f65e1cb4c58aa7940cb0f40b489d0bd9fdf5c4736a40d6e813743ee622bb91e9f86eacf01b9a31e0ff53f9c84f13c500304", + "sourceShard": 0, + "destinationShard": 1, + "blockNonce": 7593818, + "blockHash": "b19f97110ca38d3cb15f802a00ab403491b0e5804ebc701527ab50064dc06825", + "notarizedAtSourceInMetaNonce": 7609963, + "NotarizedAtSourceInMetaHash": "4d9db6de610ca778114d44fe91dd036fac7c375c373ae9e77130d3fb9efc8391", + "notarizedAtDestinationInMetaNonce": 7609967, + "notarizedAtDestinationInMetaHash": "a4573d388c31860f9bd6f9507b65d1b3130e445abcada538f10704feba4614e7", + "miniblockType": "TxBlock", + "miniblockHash": "530f5fa3c7af474a187caca8dcea02a7a155017414147871d083bed5c49ec8f5", + "hyperblockNonce": 7609967, + "hyperblockHash": "a4573d388c31860f9bd6f9507b65d1b3130e445abcada538f10704feba4614e7", + "timestamp": 1694437098, + "smartContractResults": [ + { + "hash": "065291164a8acd27c26b5a8f09664810081fda18cd54fca635196cf9b200297a", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "sender": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "data": "returnTwoU64@4f3c60", + "prevTxHash": "f34e136ca81c0e32f6fb532b753612715675073f3718b5db009bb275d246fd7a", + "originalTxHash": "f34e136ca81c0e32f6fb532b753612715675073f3718b5db009bb275d246fd7a", + "gasLimit": 596994205, + "gasPrice": 1000000000, + "callType": 1, + "operation": "transfer", + "function": "returnTwoU64" + }, + { + "hash": "bc31cb153ae615204625df84fe9ae3a159aa412b7342f3dca958dd5517a08197", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "sender": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "data": "@00@0a@0218711a00", + "prevTxHash": "065291164a8acd27c26b5a8f09664810081fda18cd54fca635196cf9b200297a", + "originalTxHash": "f34e136ca81c0e32f6fb532b753612715675073f3718b5db009bb275d246fd7a", + "gasLimit": 595152540, + "gasPrice": 1000000000, + "callType": 2, + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "identifier": "writeLog", + "topics": [ + "AAAAAAAAAAAFAP/Aj4ZNGKlpx2+xeJLdoJbREzb20P0=", + "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk1MTUyNTQwLCBnYXMgdXNlZCA9IDIyODgwMTU=" + ], + "data": "QDZmNmJAMGFAMDIxODcxMWEwMA==" + }, + { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "identifier": "completedTxEvent", + "topics": [ + "BlKRFkqKzSfCa1qPCWZIEAgf2hjNVPymNRls+bIAKXo=" + ], + "data": null + } + ] + }, + "operation": "transfer" + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgqllqglpjdrz5kn3m0k9uf9hdqjmg3xdhk6r7se3wvlk", + "identifier": "writeLog", + "topics": [ + "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=" + ], + "data": "QDZmNmI=" + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "asyncCallAnotherContractReturnTwoU64WithReturningCallback", + "initiallyPaidFee": "6230670000000000", + "fee": "6230670000000000", + "chainID": "D", + "version": 2, + "options": 0 + } + }, + "error": "", + "code": "successful" + } + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Vec> = vec![]; + + assert_eq!(tx_response.out, expected) +} diff --git a/framework/snippets/tests/test_tx_multiple_sc_results.rs b/framework/snippets/tests/test_tx_multiple_sc_results.rs new file mode 100644 index 0000000000..25e6fc477a --- /dev/null +++ b/framework/snippets/tests/test_tx_multiple_sc_results.rs @@ -0,0 +1,287 @@ +use multiversx_sc_snippets::network_response::{self, is_out_scr}; +use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; + +#[test] +fn test_transaction_multiple_sc_results() { + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "BuiltInFunctionCall", + "processingTypeOnDestination": "SCInvoking", + "hash": "c6dc718c56c8795156d847f4f9768f2b1976a516d390fdce0f5b8bad1ac3cce5", + "nonce": 236, + "round": 3353069, + "epoch": 1371, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "sender": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "gasPrice": 1000000000, + "gasLimit": 100000000, + "gasUsed": 12767998, + "data": "RVNEVFRyYW5zZmVyQDU1NTQ0YjJkMzEzNDY0MzUzNzY0QDhhYzcyMzA0ODllODAwMDBANzM3NzYxNzA1NDZmNmI2NTZlNzM0NjY5Nzg2NTY0NDk2ZTcwNzU3NEA1NzQ1NDc0YzQ0MmQ2MTMyMzg2MzM1MzlAZThkNGE1MTAwMA==", + "signature": "caed340339e3ae17a92783f5f08f96ac875885e44c25510cd11251ce23f22994985a6605c4d36f841b7110288a5e928f624f150a66a9de8ade36b68028a9af09", + "sourceShard": 0, + "destinationShard": 1, + "blockNonce": 3288476, + "blockHash": "0e70ea5fb26c58b1029c84e24eb9a661272b6253d30c668af91f167bfd67b2b0", + "notarizedAtSourceInMetaNonce": 3290316, + "NotarizedAtSourceInMetaHash": "8200662ca3ade8fa8e1dd3a4184b0a74d4c43de8f4153170a506f60c94ad3e8b", + "notarizedAtDestinationInMetaNonce": 3290320, + "notarizedAtDestinationInMetaHash": "e5f332a8f2070fd1c4ff90f5dc1ee691f36e4ecb9cb5c37e8e7c8595036c3792", + "miniblockType": "TxBlock", + "miniblockHash": "d271ad87c6cf8653cc950272f3ee5e976820ada80468518fa35fe45b6e33dca8", + "hyperblockNonce": 3290320, + "hyperblockHash": "e5f332a8f2070fd1c4ff90f5dc1ee691f36e4ecb9cb5c37e8e7c8595036c3792", + "timestamp": 1714118414, + "smartContractResults": [ + { + "hash": "c0e63f1018ece1036e3e6dc405553e5f6badfe0f5d2a104f4cd4457a872d02f9", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "sender": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "data": "swapTokensFixedInput@5745474c442d613238633539@e8d4a51000", + "prevTxHash": "c6dc718c56c8795156d847f4f9768f2b1976a516d390fdce0f5b8bad1ac3cce5", + "originalTxHash": "c6dc718c56c8795156d847f4f9768f2b1976a516d390fdce0f5b8bad1ac3cce5", + "gasLimit": 99559500, + "gasPrice": 1000000000, + "callType": 0, + "originalSender": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "operation": "transfer", + "function": "swapTokensFixedInput" + }, + { + "hash": "40078cec63b6e0d0d9522ea5e6d2d0cb6f21ebae981f354de3dc3545ac2928ad", + "nonce": 0, + "value": 0, + "receiver": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "sender": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "data": "ESDTTransfer@5745474c442d613238633539@9b35e4dd3902b9", + "prevTxHash": "c6dc718c56c8795156d847f4f9768f2b1976a516d390fdce0f5b8bad1ac3cce5", + "originalTxHash": "c6dc718c56c8795156d847f4f9768f2b1976a516d390fdce0f5b8bad1ac3cce5", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "originalSender": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "logs": { + "address": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "identifier": "ESDTTransfer", + "topics": [ + "V0VHTEQtYTI4YzU5", + "", + "mzXk3TkCuQ==", + "4yr+3JBP4ZOXRq2XO+s4NWPPY2QrpmmzBA+blCil7WA=" + ], + "data": null, + "additionalData": [ + "", + "RVNEVFRyYW5zZmVy", + "V0VHTEQtYTI4YzU5", + "mzXk3TkCuQ==" + ] + }, + { + "address": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "identifier": "writeLog", + "topics": [ + "AAAAAAAAAAAFAKi6nmhia7yZP9eV6LtvR5Q7L1/6fOs=" + ], + "data": "QDZmNmI=", + "additionalData": [ + "QDZmNmI=" + ] + }, + { + "address": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "identifier": "completedTxEvent", + "topics": [ + "xtxxjFbIeVFW2Ef0+XaPKxl2pRbTkP3OD1uLrRrDzOU=" + ], + "data": null, + "additionalData": null + } + ] + }, + "tokens": [ + "WEGLD-a28c59" + ], + "esdtValues": [ + "43687878470468281" + ], + "operation": "ESDTTransfer" + }, + { + "hash": "26487a550721b8282ceafe603bb4d53ee93929ffd9ded39b08e7422adb4d8795", + "nonce": 237, + "value": 872320020000000, + "receiver": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "sender": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "data": "@6f6b@0000000c5745474c442d6132386335390000000000000000000000079b35e4dd3902b9", + "prevTxHash": "c6dc718c56c8795156d847f4f9768f2b1976a516d390fdce0f5b8bad1ac3cce5", + "originalTxHash": "c6dc718c56c8795156d847f4f9768f2b1976a516d390fdce0f5b8bad1ac3cce5", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "logs": { + "address": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "events": [ + { + "address": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "identifier": "completedTxEvent", + "topics": [ + "xtxxjFbIeVFW2Ef0+XaPKxl2pRbTkP3OD1uLrRrDzOU=" + ], + "data": null, + "additionalData": null + } + ] + }, + "operation": "transfer", + "isRefund": true + }, + { + "hash": "798ba4333a7cedb62f811d942dedb8c0c09bf9945a0d2ccede2eaed967eba135", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgqw88ux2l44eufvwz2uhvduhq03g8pxc4j0n4s0frzjz", + "sender": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "data": "ESDTTransfer@55544b2d313464353764@2d79883d2000@6465706f7369745377617046656573", + "prevTxHash": "c6dc718c56c8795156d847f4f9768f2b1976a516d390fdce0f5b8bad1ac3cce5", + "originalTxHash": "c6dc718c56c8795156d847f4f9768f2b1976a516d390fdce0f5b8bad1ac3cce5", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "originalSender": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "tokens": [ + "UTK-14d57d" + ], + "esdtValues": [ + "50000000000000" + ], + "operation": "ESDTTransfer", + "function": "depositSwapFees" + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "events": [ + { + "address": "erd1uv40ahysflse896x4ktnh6ecx43u7cmy9wnxnvcyp7deg299a4sq6vaywa", + "identifier": "ESDTTransfer", + "topics": [ + "VVRLLTE0ZDU3ZA==", + "", + "iscjBInoAAA=", + "AAAAAAAAAAAFAKi6nmhia7yZP9eV6LtvR5Q7L1/6fOs=" + ], + "data": null, + "additionalData": [ + "", + "RVNEVFRyYW5zZmVy", + "VVRLLTE0ZDU3ZA==", + "iscjBInoAAA=", + "c3dhcFRva2Vuc0ZpeGVkSW5wdXQ=", + "V0VHTEQtYTI4YzU5", + "6NSlEAA=" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "identifier": "ESDTTransfer", + "topics": [ + "VVRLLTE0ZDU3ZA==", + "", + "LXmIPSAA", + "AAAAAAAAAAAFAHHPwyv1rniWOErl2N5cD4oOE2KyfOs=" + ], + "data": "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "additionalData": [ + "RXhlY3V0ZU9uRGVzdENvbnRleHQ=", + "RVNEVFRyYW5zZmVy", + "VVRLLTE0ZDU3ZA==", + "LXmIPSAA", + "ZGVwb3NpdFN3YXBGZWVz" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgqw88ux2l44eufvwz2uhvduhq03g8pxc4j0n4s0frzjz", + "identifier": "depositSwapFees", + "topics": [ + "ZGVwb3NpdF9zd2FwX2ZlZXNfZXZlbnQ=", + "AAAAAAAAAAAFAKi6nmhia7yZP9eV6LtvR5Q7L1/6fOs=", + "ug==", + "AAAAClVUSy0xNGQ1N2QAAAAAAAAAAAAAAAYteYg9IAA=" + ], + "data": null, + "additionalData": [ + "" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "identifier": "ESDTTransfer", + "topics": [ + "V0VHTEQtYTI4YzU5", + "", + "mzXk3TkCuQ==", + "4yr+3JBP4ZOXRq2XO+s4NWPPY2QrpmmzBA+blCil7WA=" + ], + "data": "RGlyZWN0Q2FsbA==", + "additionalData": [ + "RGlyZWN0Q2FsbA==", + "RVNEVFRyYW5zZmVy", + "V0VHTEQtYTI4YzU5", + "mzXk3TkCuQ==" + ] + }, + { + "address": "erd1qqqqqqqqqqqqqpgq4zafu6rzdw7fj07hjh5tkm68jsaj7hl60n4s8py4ra", + "identifier": "swapTokensFixedInput", + "topics": [ + "c3dhcA==", + "VVRLLTE0ZDU3ZA==", + "V0VHTEQtYTI4YzU5", + "4yr+3JBP4ZOXRq2XO+s4NWPPY2QrpmmzBA+blCil7WA=", + "BVs=" + ], + "data": "4yr+3JBP4ZOXRq2XO+s4NWPPY2QrpmmzBA+blCil7WAAAAAKVVRLLTE0ZDU3ZAAAAAiKxyMEiegAAAAAAAxXRUdMRC1hMjhjNTkAAAAHmzXk3TkCuQAAAAcjhvJvwQAAAAAACwGBykedC25GCD5kAAAACgGwxHNBlOj27dQAAAAAADItnAAAAAAAAAVbAAAAAGYrXw4=", + "additionalData": [ + "4yr+3JBP4ZOXRq2XO+s4NWPPY2QrpmmzBA+blCil7WAAAAAKVVRLLTE0ZDU3ZAAAAAiKxyMEiegAAAAAAAxXRUdMRC1hMjhjNTkAAAAHmzXk3TkCuQAAAAcjhvJvwQAAAAAACwGBykedC25GCD5kAAAACgGwxHNBlOj27dQAAAAAADItnAAAAAAAAAVbAAAAAGYrXw4=" + ] + } + ] + }, + "status": "success", + "tokens": [ + "UTK-14d57d" + ], + "esdtValues": [ + "10000000000000000000" + ], + "operation": "ESDTTransfer", + "function": "swapTokensFixedInput", + "initiallyPaidFee": "1238095000000000", + "fee": "365774980000000", + "chainID": "D", + "version": 1, + "options": 0 + } + }, + "error": "", + "code": "successful" + }"#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + assert_eq!(tx_response.api_scrs.len(), 4usize); + assert!(is_out_scr(&tx_response.api_scrs.get(2).unwrap())); +} diff --git a/framework/snippets/tests/test_tx_sc_result.rs b/framework/snippets/tests/test_tx_sc_result.rs new file mode 100644 index 0000000000..b3809eb2f8 --- /dev/null +++ b/framework/snippets/tests/test_tx_sc_result.rs @@ -0,0 +1,350 @@ +use multiversx_sc_snippets::network_response; +use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; + +#[test] +fn test_with_tx_that_has_sc_result() { + // transaction data from the devnet, an artificial "10" result has been appended on the original result + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "BuiltInFunctionCall", + "processingTypeOnDestination": "SCInvoking", + "hash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", + "nonce": 30, + "round": 7639115, + "epoch": 6333, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "sender": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", + "gasPrice": 1000000000, + "gasLimit": 25500000, + "gasUsed": 15297149, + "data": "RVNEVFRyYW5zZmVyQDQ4NTQ0ZDJkNjY2NTMxNjYzNjM5QDBkZTBiNmIzYTc2NDAwMDBANzM3NzYxNzA1NDZmNmI2NTZlNzM0NjY5Nzg2NTY0NDk2ZTcwNzU3NEA1NzQ1NDc0YzQ0MmQ2NDM3NjMzNjYyNjJAMDM3Yzc3OGZjY2U5YzU1Yg==", + "signature": "e912fae4b7a9e51ddf316a5e82a0f457d453a62e3c17477f5d6175e1b33c5e92ddb187d65f54cf3131a0603321290279a0456c20778039f2ab09b54e33c60f0d", + "sourceShard": 2, + "destinationShard": 1, + "blockNonce": 7585351, + "blockHash": "e456f38f11fec78ed26d5fda068e912739dceedb2e5ce559bf17614b8386c039", + "notarizedAtSourceInMetaNonce": 7601495, + "NotarizedAtSourceInMetaHash": "e28c6011d4b3f73f3945cae70ff251e675dfea331a70077c5ab3310e3101af17", + "notarizedAtDestinationInMetaNonce": 7601499, + "notarizedAtDestinationInMetaHash": "333d4266614e981cc1c5654f85ef496038a8cddac46dfc0ad0b7c44c37ab489d", + "miniblockType": "TxBlock", + "miniblockHash": "13e041f32fde79ebf1abdcfe692e99516f9ec6778dcb917251b440daa7f1210a", + "hyperblockNonce": 7601499, + "hyperblockHash": "333d4266614e981cc1c5654f85ef496038a8cddac46dfc0ad0b7c44c37ab489d", + "timestamp": 1694386290, + "smartContractResults": [ + { + "hash": "a23faa3c80bae0b968f007ff0fad3afdec05b4e71d749c3d583dec10c6eb05a2", + "nonce": 0, + "value": 0, + "receiver": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", + "sender": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "data": "ESDTTransfer@5745474c442d643763366262@03856446ff9a304b", + "prevTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", + "originalTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "logs": { + "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "identifier": "ESDTTransfer", + "topics": [ + "V0VHTEQtZDdjNmJi", + "", + "A4VkRv+aMEs=", + "qP29NHPKNFkQzDGmOEIaNRCFYABw8ku13ZyenAuvJOY=" + ], + "data": null + }, + { + "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", + "identifier": "writeLog", + "topics": [ + "AAAAAAAAAAAFAKVe/p1dXpaw/INtyTPaxf3N3LaNfOs=" + ], + "data": "QDZmNmI=" + }, + { + "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", + "identifier": "completedTxEvent", + "topics": [ + "1AWL08E9sLFIMsfFj+Fj2y9Xn/ZUQ4BYa4on2ItKUHA=" + ], + "data": null + } + ] + }, + "tokens": [ + "WEGLD-d7c6bb" + ], + "esdtValues": [ + "253719210115084363" + ], + "operation": "ESDTTransfer" + }, + { + "hash": "b7b4d15917fd215399d8e772c3c4e732008baaedc2b8172f71c91708ba7523f0", + "nonce": 31, + "value": 102028510000000, + "receiver": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", + "sender": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "data": "@6f6b@0000000c5745474c442d64376336626200000000000000000000000803856446ff9a304b@10", + "prevTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", + "originalTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "logs": { + "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", + "events": [ + { + "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", + "identifier": "completedTxEvent", + "topics": [ + "1AWL08E9sLFIMsfFj+Fj2y9Xn/ZUQ4BYa4on2ItKUHA=" + ], + "data": null + } + ] + }, + "operation": "transfer", + "isRefund": true + }, + { + "hash": "05a766ca05d2053d1c0fbeb1797116474a06c86402a3bfd6c132c9a24cfa1bb0", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "sender": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "data": "swapTokensFixedInput@5745474c442d643763366262@037c778fcce9c55b", + "prevTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", + "originalTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", + "gasLimit": 25050500, + "gasPrice": 1000000000, + "callType": 0, + "operation": "transfer", + "function": "swapTokensFixedInput" + }, + { + "hash": "4e639c80822d5d7780c8326d683fa9cd6d59649d14122dfabc5a96dda36da527", + "nonce": 0, + "value": 0, + "receiver": "erd1qqqqqqqqqqqqqpgquu5rsa4ee6l4azz6vdu4hjp8z4p6tt8m0n4suht3dy", + "sender": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "data": "ESDTTransfer@5745474c442d643763366262@e7730d1ef1b0@737761704e6f466565416e64466f7277617264@4d45582d646332383963@0000000000000000000000000000000000000000000000000000000000000000", + "prevTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", + "originalTxHash": "d4058bd3c13db0b14832c7c58fe163db2f579ff6544380586b8a27d88b4a5070", + "gasLimit": 0, + "gasPrice": 1000000000, + "callType": 0, + "tokens": [ + "WEGLD-d7c6bb" + ], + "esdtValues": [ + "254481327387056" + ], + "operation": "ESDTTransfer", + "function": "swapNoFeeAndForward" + } + ], + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "events": [ + { + "address": "erd14r7m6drneg69jyxvxxnrsss6x5gg2cqqwreyhdwanj0fcza0ynnq5jmy4g", + "identifier": "ESDTTransfer", + "topics": [ + "SFRNLWZlMWY2OQ==", + "", + "DeC2s6dkAAA=", + "AAAAAAAAAAAFAKVe/p1dXpaw/INtyTPaxf3N3LaNfOs=" + ], + "data": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "identifier": "ESDTTransfer", + "topics": [ + "V0VHTEQtZDdjNmJi", + "", + "53MNHvGw", + "AAAAAAAAAAAFAOcoOHa5zr9eiFpjeVvIJxVDpaz7fOs=" + ], + "data": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgquu5rsa4ee6l4azz6vdu4hjp8z4p6tt8m0n4suht3dy", + "identifier": "ESDTLocalBurn", + "topics": [ + "TUVYLWRjMjg5Yw==", + "", + "AuMDPq1jy03x" + ], + "data": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgquu5rsa4ee6l4azz6vdu4hjp8z4p6tt8m0n4suht3dy", + "identifier": "swapNoFeeAndForward", + "topics": [ + "c3dhcF9ub19mZWVfYW5kX2ZvcndhcmQ=", + "TUVYLWRjMjg5Yw==", + "AAAAAAAAAAAFAKVe/p1dXpaw/INtyTPaxf3N3LaNfOs=", + "GL0=" + ], + "data": "AAAAAAAAAAAFAKVe/p1dXpaw/INtyTPaxf3N3LaNfOsAAAAMV0VHTEQtZDdjNmJiAAAABudzDR7xsAAAAApNRVgtZGMyODljAAAACQLjAz6tY8tN8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzvkcAAAAAAAAYvQAAAABk/khy" + }, + { + "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "identifier": "ESDTTransfer", + "topics": [ + "V0VHTEQtZDdjNmJi", + "", + "A4VkRv+aMEs=", + "qP29NHPKNFkQzDGmOEIaNRCFYABw8ku13ZyenAuvJOY=" + ], + "data": null + }, + { + "address": "erd1qqqqqqqqqqqqqpgq5400a82at6ttplyrdhyn8kk9lhxaed5d0n4s9s77kz", + "identifier": "swapTokensFixedInput", + "topics": [ + "c3dhcA==", + "SFRNLWZlMWY2OQ==", + "V0VHTEQtZDdjNmJi", + "qP29NHPKNFkQzDGmOEIaNRCFYABw8ku13ZyenAuvJOY=", + "GL0=" + ], + "data": "qP29NHPKNFkQzDGmOEIaNRCFYABw8ku13ZyenAuvJOYAAAAKSFRNLWZlMWY2OQAAAAgN4Lazp2QAAAAAAAxXRUdMRC1kN2M2YmIAAAAIA4VkRv+aMEsAAAAHA41+pMaAAAAAAAoofxtJRPkr8X9kAAAACgpOPCsHUu261HUAAAAAAHO+RwAAAAAAABi9AAAAAGT+SHI=" + } + ] + }, + "status": "success", + "tokens": [ + "HTM-fe1f69" + ], + "esdtValues": [ + "1000000000000000000" + ], + "operation": "ESDTTransfer", + "function": "swapTokensFixedInput", + "initiallyPaidFee": "502005000000000", + "fee": "399976490000000", + "chainID": "D", + "version": 1, + "options": 0 + } + }, + "error": "", + "code": "successful" + } + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Vec> = vec![ + hex::decode("0000000c5745474c442d64376336626200000000000000000000000803856446ff9a304b") + .unwrap(), + hex::decode("10").unwrap(), + ]; + + assert_eq!(tx_response.out, expected) +} + +#[test] +fn test_with_tx_that_has_no_sc_result() { + // transaction data from the devnet + let data = r#" + { + "data": { + "transaction": { + "type": "normal", + "processingTypeOnSource": "SCInvoking", + "processingTypeOnDestination": "SCInvoking", + "hash": "6afac3ec13c89cc56154d06efdb457a24f58361699eee00a48202a8f8adc8c8a", + "nonce": 17, + "round": 7548071, + "epoch": 6257, + "value": "0", + "receiver": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "sender": "erd1uh67c2lkhyj4vh73akv7jky9sfgvus8awwcj64uju69mmfne5u7q299t7g", + "gasPrice": 1000000000, + "gasLimit": 600000000, + "gasUsed": 600000000, + "data": "cmV0dXJuVHdvVTY0", + "signature": "f3a3ca96a78c90c9cf1b08541e1777010f0176a5e1e525e631155b2784932cbfd74c9168d03ba201fd5434d1a1b4789895ddade9883eca2ee9e0bce18468fb00", + "sourceShard": 0, + "destinationShard": 0, + "blockNonce": 7502091, + "blockHash": "5ec66c651cb1514cba200e7e80a4491880f0db678ce7631c397872e3842f0aa2", + "notarizedAtSourceInMetaNonce": 7510505, + "NotarizedAtSourceInMetaHash": "8410309ec5b988af79b4dcfb44fd4729d46874ebd796672c78e417e314409051", + "notarizedAtDestinationInMetaNonce": 7510505, + "notarizedAtDestinationInMetaHash": "8410309ec5b988af79b4dcfb44fd4729d46874ebd796672c78e417e314409051", + "miniblockType": "TxBlock", + "miniblockHash": "fb150e515449c9b658879ed06f256b429239cbe78ec2c2821deb4b283ff21554", + "hyperblockNonce": 7510505, + "hyperblockHash": "8410309ec5b988af79b4dcfb44fd4729d46874ebd796672c78e417e314409051", + "timestamp": 1693840026, + "logs": { + "address": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "events": [ + { + "address": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "identifier": "writeLog", + "topics": [ + "5fXsK/a5JVZf0e2Z6ViFglDOQP1zsS1XkuaLvaZ5pzw=", + "QHRvbyBtdWNoIGdhcyBwcm92aWRlZCBmb3IgcHJvY2Vzc2luZzogZ2FzIHByb3ZpZGVkID0gNTk5OTMyMDAwLCBnYXMgdXNlZCA9IDE4NDE2NjU=" + ], + "data": "QDZmNmJAMGFAMDIxODcxMWEwMA==" + }, + { + "address": "erd1qqqqqqqqqqqqqpgq4nlkk7jwhqgp4r08lal46tqt70jdv0685u7qrr3l2d", + "identifier": "completedTxEvent", + "topics": [ + "avrD7BPInMVhVNBu/bRXok9YNhaZ7uAKSCAqj4rcjIo=" + ], + "data": null + } + ] + }, + "status": "success", + "operation": "transfer", + "function": "returnTwoU64", + "initiallyPaidFee": "6067320000000000", + "fee": "6067320000000000", + "chainID": "D", + "version": 1, + "options": 0 + } + }, + "error": "", + "code": "successful" + } + "#; + + let tx_on_network: TransactionOnNetwork = serde_json::from_str::(data) + .unwrap() + .data + .unwrap() + .transaction; + let tx_response = network_response::parse_tx_response(tx_on_network); + + let expected: Vec> = vec![ + hex::decode("0a").unwrap(), + hex::decode("0218711a00").unwrap(), + ]; + + assert_eq!(tx_response.out, expected) +} diff --git a/framework/wasm-adapter/Cargo.toml b/framework/wasm-adapter/Cargo.toml index 4630f3d7d4..e988da7a8a 100644 --- a/framework/wasm-adapter/Cargo.toml +++ b/framework/wasm-adapter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-wasm-adapter" -version = "0.47.5" +version = "0.50.3" edition = "2021" authors = [ @@ -22,5 +22,5 @@ categories = [ ] [dependencies.multiversx-sc] -version = "=0.47.5" +version = "=0.50.3" path = "../base" diff --git a/framework/wasm-adapter/src/api/endpoint_arg_api_node.rs b/framework/wasm-adapter/src/api/endpoint_arg_api_node.rs index 48135f65ae..6c4627fa60 100644 --- a/framework/wasm-adapter/src/api/endpoint_arg_api_node.rs +++ b/framework/wasm-adapter/src/api/endpoint_arg_api_node.rs @@ -56,7 +56,7 @@ impl EndpointArgumentApiImpl for VmApiImpl { fn get_argument_boxed_bytes(&self, arg_index: i32) -> BoxedBytes { let len = self.get_argument_len(arg_index); unsafe { - let mut res = BoxedBytes::allocate(len); + let mut res = BoxedBytes::zeros(len); if len > 0 { getArgument(arg_index, res.as_mut_ptr()); } diff --git a/framework/wasm-adapter/src/api/managed_types/elliptic_curve_api_node.rs b/framework/wasm-adapter/src/api/managed_types/elliptic_curve_api_node.rs index fe35a339f9..3fb800e85f 100644 --- a/framework/wasm-adapter/src/api/managed_types/elliptic_curve_api_node.rs +++ b/framework/wasm-adapter/src/api/managed_types/elliptic_curve_api_node.rs @@ -314,7 +314,7 @@ impl EllipticCurveApiImpl for crate::api::VmApiImpl { ) -> BoxedBytes { unsafe { let byte_length = (getCurveLengthEC(ec_handle) + 7) / 8; - let mut result = BoxedBytes::allocate(1 + 2 * byte_length as usize); + let mut result = BoxedBytes::zeros(1 + 2 * byte_length as usize); marshalEC(x_pair_handle, y_pair_handle, ec_handle, result.as_mut_ptr()); result } @@ -340,7 +340,7 @@ impl EllipticCurveApiImpl for crate::api::VmApiImpl { ) -> BoxedBytes { unsafe { let byte_length = (getCurveLengthEC(ec_handle) + 7) / 8; - let mut result = BoxedBytes::allocate(1 + byte_length as usize); + let mut result = BoxedBytes::zeros(1 + byte_length as usize); marshalCompressedEC(x_pair_handle, y_pair_handle, ec_handle, result.as_mut_ptr()); result } @@ -426,7 +426,7 @@ impl EllipticCurveApiImpl for crate::api::VmApiImpl { ) -> BoxedBytes { unsafe { let priv_key_length = getPrivKeyByteLengthEC(ec_handle); - let mut private_key = BoxedBytes::allocate(priv_key_length as usize); + let mut private_key = BoxedBytes::zeros(priv_key_length as usize); generateKeyEC( x_pub_key_handle, y_pub_key_handle, diff --git a/framework/wasm-adapter/src/api/managed_types/managed_buffer_api_node.rs b/framework/wasm-adapter/src/api/managed_types/managed_buffer_api_node.rs index 120d06e734..ee0390ffb0 100644 --- a/framework/wasm-adapter/src/api/managed_types/managed_buffer_api_node.rs +++ b/framework/wasm-adapter/src/api/managed_types/managed_buffer_api_node.rs @@ -58,7 +58,7 @@ impl ManagedBufferApiImpl for crate::api::VmApiImpl { fn mb_to_boxed_bytes(&self, handle: Self::ManagedBufferHandle) -> BoxedBytes { unsafe { let len = mBufferGetLength(handle); - let mut res = BoxedBytes::allocate(len as usize); + let mut res = BoxedBytes::zeros(len as usize); if len > 0 { let _ = mBufferGetBytes(handle, res.as_mut_ptr()); } diff --git a/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs b/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs index 1350697cf6..501d53d68f 100644 --- a/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs +++ b/framework/wasm-adapter/src/api/managed_types/static_var_api_node.rs @@ -33,6 +33,7 @@ impl StaticVarApi for VmApiImpl { } impl StaticVarApiImpl for VmApiImpl { + #[allow(static_mut_refs)] fn with_lockable_static_buffer R>(&self, f: F) -> R { unsafe { f(&mut STATIC_BUFFER) } } diff --git a/framework/wasm-adapter/src/lib.rs b/framework/wasm-adapter/src/lib.rs index d105af6bcc..9bd84315c5 100644 --- a/framework/wasm-adapter/src/lib.rs +++ b/framework/wasm-adapter/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![feature(panic_info_message)] +#![allow(unknown_lints)] // Allows us to use alloc::vec::Vec; // TODO: get rid of the legacy API and also of this. diff --git a/framework/wasm-adapter/src/panic.rs b/framework/wasm-adapter/src/panic.rs index 164db2fc14..00dc658a7a 100644 --- a/framework/wasm-adapter/src/panic.rs +++ b/framework/wasm-adapter/src/panic.rs @@ -18,12 +18,10 @@ pub fn panic_fmt(_: &PanicInfo) -> ! { /// Mostly used for debugging, the additional code is normally not deemed to be worth it. pub fn panic_fmt_with_message(panic_info: &PanicInfo) -> ! { let mut panic_msg = ManagedPanicMessage::default(); - if let Some(args) = panic_info.message() { - panic_msg.append_str("panic occurred: "); - let _ = core::fmt::write(&mut panic_msg, *args); - } else { - panic_msg.append_str("unknown panic occurred"); - }; + panic_msg.append_str("panic occurred: "); + + core::fmt::write(&mut panic_msg, format_args!("{panic_info}")) + .unwrap_or_else(|_| panic_msg.append_str("unable to write panic")); VmApiImpl::error_api_impl().signal_error_from_buffer(panic_msg.buffer.get_handle()) } @@ -41,7 +39,11 @@ impl ManagedPanicMessage { impl core::fmt::Write for ManagedPanicMessage { fn write_str(&mut self, s: &str) -> core::fmt::Result { - self.append_str(s); + let file_name = match s.rfind('/') { + Some(index) => &s[index + 1..], + None => s, + }; + self.append_str(file_name); Ok(()) } } diff --git a/framework/wasm-adapter/src/wasm_alloc/leaking_allocator.rs b/framework/wasm-adapter/src/wasm_alloc/leaking_allocator.rs index 59bfa218ab..8a40b0ac68 100644 --- a/framework/wasm-adapter/src/wasm_alloc/leaking_allocator.rs +++ b/framework/wasm-adapter/src/wasm_alloc/leaking_allocator.rs @@ -19,6 +19,7 @@ pub struct LeakingAllocator { unsafe impl Sync for LeakingAllocator {} impl LeakingAllocator { + #[allow(clippy::new_without_default)] pub const fn new() -> Self { LeakingAllocator { used: UnsafeCell::new(0), diff --git a/framework/wasm-adapter/src/wasm_alloc/static_allocator.rs b/framework/wasm-adapter/src/wasm_alloc/static_allocator.rs index 0b0ae4d87e..00b7088d61 100644 --- a/framework/wasm-adapter/src/wasm_alloc/static_allocator.rs +++ b/framework/wasm-adapter/src/wasm_alloc/static_allocator.rs @@ -25,6 +25,7 @@ pub struct StaticAllocator { } impl StaticAllocator { + #[allow(clippy::new_without_default)] pub const fn new() -> Self { StaticAllocator { arena: UnsafeCell::new([0; SIZE]), diff --git a/framework/wasm-adapter/src/wasm_macros.rs b/framework/wasm-adapter/src/wasm_macros.rs index 206070a91c..0d2ae296a3 100644 --- a/framework/wasm-adapter/src/wasm_macros.rs +++ b/framework/wasm-adapter/src/wasm_macros.rs @@ -28,9 +28,6 @@ macro_rules! panic_handler { fn panic_fmt(panic_info: &multiversx_sc_wasm_adapter::panic::PanicInfo) -> ! { multiversx_sc_wasm_adapter::panic::panic_fmt(panic_info) } - - #[lang = "eh_personality"] - fn eh_personality() {} }; } @@ -41,9 +38,6 @@ macro_rules! panic_handler_with_message { fn panic_fmt(panic_info: &multiversx_sc_wasm_adapter::panic::PanicInfo) -> ! { multiversx_sc_wasm_adapter::panic::panic_fmt_with_message(panic_info) } - - #[lang = "eh_personality"] - fn eh_personality() {} }; } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 9a2458c117..292fe499e3 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "nightly-2023-12-11" +channel = "stable" diff --git a/rustfmt.toml b/rustfmt.toml index 8484a95cce..29b99b9ba4 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -12,7 +12,7 @@ # This should actually automatically be shipped with cargo fmt or rustfmt itself! # ---------------------------------------------------------------------------------- -imports_granularity="Crate" +# imports_granularity="Crate" # Use verbose output. # Default: false diff --git a/sdk/core/Cargo.toml b/sdk/core/Cargo.toml index c3f7aefd73..c8bf3c75fb 100644 --- a/sdk/core/Cargo.toml +++ b/sdk/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sdk" -version = "0.3.2" +version = "0.4.1" edition = "2021" authors = [ @@ -17,7 +17,7 @@ keywords = ["multiversx", "blockchain", "sdk", "api"] [dependencies] tokio = { version = "1.24", features = ["full"] } -reqwest = { version = "0.11.4", features = ["blocking", "json"] } +reqwest = { version = "0.12", features = ["blocking", "json"] } serde = { version = "1.0.130", features = ["derive"] } serde_json = { version = "1.0.68", features = ["preserve_order"] } serde_repr = "0.1.8" @@ -28,9 +28,10 @@ sha2 = "0.10.8" sha3 = "0.10.8" hmac = { version = "0.12.1", features = ["std"] } hex = "0.4.3" -base64 = "0.21.5" +base64 = "0.22" pbkdf2 = { version = "0.12.2", default-features = false } zeroize = "1.4.2" bech32 = "0.9" itertools = "0.12.0" pem = "3.0.2" +log = "0.4.17" diff --git a/sdk/core/examples/account.rs b/sdk/core/examples/account.rs index 2ad1d6c4cc..5e9456f4b0 100644 --- a/sdk/core/examples/account.rs +++ b/sdk/core/examples/account.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ - blockchain::{CommunicationProxy, DEVNET_GATEWAY}, data::address::Address, + gateway::{GatewayProxy, DEVNET_GATEWAY}, }; #[tokio::main] @@ -10,7 +10,7 @@ async fn main() { ) .unwrap(); - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let account = blockchain.get_account(&addr).await.unwrap(); println!("account: {account:#?}"); diff --git a/sdk/core/examples/account_storage.rs b/sdk/core/examples/account_storage.rs index 31adc7d0f9..7693c26e08 100644 --- a/sdk/core/examples/account_storage.rs +++ b/sdk/core/examples/account_storage.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ - blockchain::{CommunicationProxy, DEVNET_GATEWAY}, data::address::Address, + gateway::{GatewayProxy, DEVNET_GATEWAY}, }; #[tokio::main] @@ -10,7 +10,7 @@ async fn main() { ) .unwrap(); - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let account_storage = blockchain.get_account_storage_keys(&addr).await.unwrap(); println!("Account Storage: {account_storage:#?}"); diff --git a/sdk/core/examples/get_esdt_tokens.rs b/sdk/core/examples/get_esdt_tokens.rs index faa4debfba..fac424da27 100644 --- a/sdk/core/examples/get_esdt_tokens.rs +++ b/sdk/core/examples/get_esdt_tokens.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ - blockchain::{CommunicationProxy, DEVNET_GATEWAY}, data::address::Address, + gateway::{GatewayProxy, DEVNET_GATEWAY}, }; #[tokio::main] @@ -10,7 +10,7 @@ async fn main() { ) .unwrap(); - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let balances = blockchain.get_account_esdt_tokens(&addr).await.unwrap(); println!("{balances:#?}"); diff --git a/sdk/core/examples/get_hyper_block_by_hash.rs b/sdk/core/examples/get_hyper_block_by_hash.rs index c67b479767..1d7f969ce1 100644 --- a/sdk/core/examples/get_hyper_block_by_hash.rs +++ b/sdk/core/examples/get_hyper_block_by_hash.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::blockchain::{CommunicationProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let result = blockchain .get_hyper_block_by_hash("20b14ba0e68c465810c5ded091f220e51dad41629d7ccd87dab572206185e419") .await; diff --git a/sdk/core/examples/get_hyper_block_by_nonce.rs b/sdk/core/examples/get_hyper_block_by_nonce.rs index c3d270d2bc..575255d6c9 100644 --- a/sdk/core/examples/get_hyper_block_by_nonce.rs +++ b/sdk/core/examples/get_hyper_block_by_nonce.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::blockchain::{CommunicationProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let result = blockchain.get_hyper_block_by_nonce(7468).await; println!("block by nonce result: {result:?}") diff --git a/sdk/core/examples/get_hyper_block_latest.rs b/sdk/core/examples/get_hyper_block_latest.rs index b9ad946829..934358fdbf 100644 --- a/sdk/core/examples/get_hyper_block_latest.rs +++ b/sdk/core/examples/get_hyper_block_latest.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::blockchain::{CommunicationProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let result = blockchain.get_latest_hyper_block_nonce(false).await; println!("latest block result: {result:?}") diff --git a/sdk/core/examples/get_network_config.rs b/sdk/core/examples/get_network_config.rs index 7ca699b3c8..d53e0e7ce1 100644 --- a/sdk/core/examples/get_network_config.rs +++ b/sdk/core/examples/get_network_config.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::blockchain::{CommunicationProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let network_config = blockchain.get_network_config().await.unwrap(); println!("network_config: {network_config:#?}") diff --git a/sdk/core/examples/get_network_economics.rs b/sdk/core/examples/get_network_economics.rs index e562f3db46..bb0410c8f0 100644 --- a/sdk/core/examples/get_network_economics.rs +++ b/sdk/core/examples/get_network_economics.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::blockchain::{CommunicationProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let network_economics = blockchain.get_network_economics().await.unwrap(); println!("network_economics: {network_economics:#?}") diff --git a/sdk/core/examples/sign_tx.rs b/sdk/core/examples/sign_tx.rs index 1455061830..aa3f977321 100644 --- a/sdk/core/examples/sign_tx.rs +++ b/sdk/core/examples/sign_tx.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ - blockchain::{CommunicationProxy, DEVNET_GATEWAY}, data::transaction::Transaction, + gateway::{GatewayProxy, DEVNET_GATEWAY}, wallet::Wallet, }; @@ -11,7 +11,7 @@ async fn main() { ) .unwrap(); let addr = wl.address(); - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let network_config = blockchain.get_network_config().await.unwrap(); let arg = blockchain diff --git a/sdk/core/examples/sign_txs.rs b/sdk/core/examples/sign_txs.rs index 6a4a12a231..2860d528f7 100644 --- a/sdk/core/examples/sign_txs.rs +++ b/sdk/core/examples/sign_txs.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ - blockchain::{CommunicationProxy, DEVNET_GATEWAY}, data::transaction::Transaction, + gateway::{GatewayProxy, DEVNET_GATEWAY}, wallet::Wallet, }; @@ -11,7 +11,7 @@ async fn main() { ) .unwrap(); let addr = wl.address(); - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let network_config = blockchain.get_network_config().await.unwrap(); let arg = blockchain diff --git a/sdk/core/examples/tx_cost.rs b/sdk/core/examples/tx_cost.rs index b98cbd2e4b..a982b130ec 100644 --- a/sdk/core/examples/tx_cost.rs +++ b/sdk/core/examples/tx_cost.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ - blockchain::{CommunicationProxy, DEVNET_GATEWAY}, data::{address::Address, transaction::Transaction}, + gateway::{GatewayProxy, DEVNET_GATEWAY}, utils::base64_encode, }; @@ -26,7 +26,7 @@ async fn main() { signature: None, }; - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let cost = blockchain.request_transaction_cost(&tx).await.unwrap(); println!("tx cost: {cost:#?}"); diff --git a/sdk/core/examples/tx_default_args.rs b/sdk/core/examples/tx_default_args.rs index dad593eaf8..01b91aa5a6 100644 --- a/sdk/core/examples/tx_default_args.rs +++ b/sdk/core/examples/tx_default_args.rs @@ -1,11 +1,11 @@ use multiversx_sdk::{ - blockchain::{CommunicationProxy, DEVNET_GATEWAY}, data::address::Address, + gateway::{GatewayProxy, DEVNET_GATEWAY}, }; #[tokio::main] async fn main() { - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let network_config = blockchain.get_network_config().await.unwrap(); let addr = Address::from_bech32_string( "erd1qqqqqqqqqqqqqpgqfzydqmdw7m2vazsp6u5p95yxz76t2p9rd8ss0zp9ts", diff --git a/sdk/core/examples/tx_info.rs b/sdk/core/examples/tx_info.rs index 33c929be50..f7126daca9 100644 --- a/sdk/core/examples/tx_info.rs +++ b/sdk/core/examples/tx_info.rs @@ -1,9 +1,9 @@ -use multiversx_sdk::blockchain::{CommunicationProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; #[tokio::main] async fn main() { let tx_hash = "49edb289892a655a0e988b360c19326c21107f9696c6197b435667c6e8c6e1a3"; - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let status = blockchain.get_transaction_status(tx_hash).await; println!("tx status: {status:?}"); diff --git a/sdk/core/examples/vm_query.rs b/sdk/core/examples/vm_query.rs index 41cdfd5dbf..d07f49b856 100644 --- a/sdk/core/examples/vm_query.rs +++ b/sdk/core/examples/vm_query.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ - blockchain::{CommunicationProxy, DEVNET_GATEWAY}, data::{address::Address, vm::VmValueRequest}, + gateway::{GatewayProxy, DEVNET_GATEWAY}, wallet::Wallet, }; @@ -11,7 +11,7 @@ async fn main() { ) .unwrap(); let addr = wl.address(); - let blockchain = CommunicationProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); let req = VmValueRequest { sc_address: Address::from_bech32_string( "erd1qqqqqqqqqqqqqpgqhn3ae8dpc957t7jadn7kywtg503dy7pnj9ts3umqxx", diff --git a/sdk/core/src/blockchain.rs b/sdk/core/src/blockchain.rs deleted file mode 100644 index 73d97ef0ea..0000000000 --- a/sdk/core/src/blockchain.rs +++ /dev/null @@ -1,405 +0,0 @@ -use std::collections::HashMap; - -use crate::data::{ - account::{Account, AccountResponse}, - account_storage::AccountStorageResponse, - address::Address, - esdt::{EsdtBalance, EsdtBalanceResponse, EsdtRolesResponse}, - hyperblock::{HyperBlock, HyperBlockResponse}, - network_config::{NetworkConfig, NetworkConfigResponse}, - network_economics::{NetworkEconomics, NetworkEconomicsResponse}, - network_status::NetworkStatusResponse, - transaction::{ - ArgCreateTransaction, ResponseTxCost, SendTransactionResponse, SendTransactionsResponse, - Transaction, TransactionInfo, TransactionOnNetwork, TransactionStatus, TxCostResponseData, - }, - vm::{ResponseVmValue, VmValueRequest, VmValuesResponseData}, -}; -use anyhow::{anyhow, Result}; -use itertools::Itertools; -use reqwest::Client; - -pub const MAINNET_GATEWAY: &str = "https://gateway.multiversx.com"; -pub const TESTNET_GATEWAY: &str = "https://testnet-gateway.multiversx.com"; -pub const DEVNET_GATEWAY: &str = "https://devnet-gateway.multiversx.com"; - -// MetachainShardId will be used to identify a shard ID as metachain -pub const METACHAIN_SHARD_ID: u32 = 0xFFFFFFFF; - -const NETWORK_CONFIG_ENDPOINT: &str = "network/config"; -const NETWORK_ECONOMICS_ENDPOINT: &str = "network/economics"; -const ACCOUNT_ENDPOINT: &str = "address/"; -const KEYS_ENDPOINT: &str = "/keys/"; -const COST_TRANSACTION_ENDPOINT: &str = "transaction/cost"; -const SEND_TRANSACTION_ENDPOINT: &str = "transaction/send"; -const SEND_MULTIPLE_TRANSACTIONS_ENDPOINT: &str = "transaction/send-multiple"; -const GET_TRANSACTION_INFO_ENDPOINT: &str = "transaction/"; -const GET_HYPER_BLOCK_BY_NONCE_ENDPOINT: &str = "hyperblock/by-nonce/"; -const GET_HYPER_BLOCK_BY_HASH_ENDPOINT: &str = "hyperblock/by-hash/"; -const GET_NETWORK_STATUS_ENDPOINT: &str = "network/status"; -const WITH_RESULTS_QUERY_PARAM: &str = "?withResults=true"; -const VM_VALUES_ENDPOINT: &str = "vm-values/query"; - -#[derive(Clone, Debug)] -pub struct CommunicationProxy { - proxy_url: String, - client: Client, -} - -impl CommunicationProxy { - pub fn new(proxy_url: String) -> Self { - Self { - proxy_url, - client: Client::new(), - } - } - - fn get_endpoint(&self, endpoint: &str) -> String { - format!("{}/{}", self.proxy_url, endpoint) - } - - // get_network_config retrieves the network configuration from the proxy - pub async fn get_network_config(&self) -> Result { - let endpoint = self.get_endpoint(NETWORK_CONFIG_ENDPOINT); - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.config), - } - } - - // get_network_economics retrieves the network economics from the proxy - pub async fn get_network_economics(&self) -> Result { - let endpoint = self.get_endpoint(NETWORK_ECONOMICS_ENDPOINT); - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.metrics), - } - } - - async fn get_hyper_block(&self, endpoint: &str) -> Result { - let endpoint = self.get_endpoint(endpoint); - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.hyperblock), - } - } - - // get_hyper_block_by_hash retrieves a hyper block's info by hash from the network - pub async fn get_hyper_block_by_hash(&self, hash: &str) -> Result { - let endpoint = GET_HYPER_BLOCK_BY_HASH_ENDPOINT.to_string() + hash; - self.get_hyper_block(endpoint.as_str()).await - } - - // get_hyper_block_by_nonce retrieves a hyper block's info by nonce from the network - pub async fn get_hyper_block_by_nonce(&self, nonce: u64) -> Result { - let endpoint = GET_HYPER_BLOCK_BY_NONCE_ENDPOINT.to_string() + nonce.to_string().as_str(); - self.get_hyper_block(endpoint.as_str()).await - } - - // get_latest_hyper_block_nonce retrieves the latest hyper block (metachain) nonce from the network - pub async fn get_latest_hyper_block_nonce(&self, with_metachain: bool) -> Result { - let mut endpoint = GET_NETWORK_STATUS_ENDPOINT.to_string(); - - if with_metachain { - endpoint = format!("{GET_NETWORK_STATUS_ENDPOINT}/{METACHAIN_SHARD_ID}"); - } - - let endpoint = self.get_endpoint(endpoint.as_str()); - - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.status.nonce), - } - } - - // request_transaction_cost retrieves how many gas a transaction will consume - pub async fn request_transaction_cost(&self, tx: &Transaction) -> Result { - let endpoint = self.get_endpoint(COST_TRANSACTION_ENDPOINT); - let resp = self - .client - .post(endpoint) - .json(tx) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b), - } - } - - // get_account retrieves an account info from the network (nonce, balance) - pub async fn get_account(&self, address: &Address) -> Result { - if !address.is_valid() { - return Err(anyhow!("invalid address")); - } - - let endpoint = ACCOUNT_ENDPOINT.to_string() + address.to_string().as_str(); - let endpoint = self.get_endpoint(endpoint.as_str()); - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.account), - } - } - - // get_account_esdt_roles retrieves an all esdt roles of an account from the network - pub async fn get_account_esdt_roles( - &self, - address: &Address, - ) -> Result>> { - if !address.is_valid() { - return Err(anyhow!("invalid address")); - } - - let endpoint = ACCOUNT_ENDPOINT.to_string() + address.to_string().as_str() + "/esdts/roles"; - let endpoint = self.get_endpoint(endpoint.as_str()); - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.roles), - } - } - - // get_account_esdt_tokens retrieves an all esdt token of an account from the network - pub async fn get_account_esdt_tokens( - &self, - address: &Address, - ) -> Result> { - if !address.is_valid() { - return Err(anyhow!("invalid address")); - } - - let endpoint = ACCOUNT_ENDPOINT.to_string() + address.to_string().as_str() + "/esdt"; - let endpoint = self.get_endpoint(endpoint.as_str()); - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.esdts), - } - } - - // get_account_esdt_tokens retrieves an all esdt token of an account from the network - pub async fn get_account_storage_keys( - &self, - address: &Address, - ) -> Result> { - if !address.is_valid() { - return Err(anyhow!("invalid address")); - } - - let endpoint = ACCOUNT_ENDPOINT.to_string() + address.to_string().as_str() + KEYS_ENDPOINT; - let endpoint = self.get_endpoint(endpoint.as_str()); - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.pairs), - } - } - - async fn get_transaction_info_internal( - &self, - hash: &str, - with_results: bool, - ) -> Result { - let mut endpoint = GET_TRANSACTION_INFO_ENDPOINT.to_string() + hash; - - if with_results { - endpoint += WITH_RESULTS_QUERY_PARAM - } - - let endpoint = self.get_endpoint(endpoint.as_str()); - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.transaction), - } - } - - // get_transaction_info retrieves a transaction's details from the network - pub async fn get_transaction_info(&self, hash: &str) -> Result { - self.get_transaction_info_internal(hash, false).await - } - - // get_transaction_info_with_results retrieves a transaction's details from the network with events - pub async fn get_transaction_info_with_results( - &self, - hash: &str, - ) -> Result { - self.get_transaction_info_internal(hash, true).await - } - - // get_transaction_status retrieves a transaction's status from the network - pub async fn get_transaction_status(&self, hash: &str) -> Result { - let endpoint = format!("transaction/{hash}/status"); - let endpoint = self.get_endpoint(endpoint.as_str()); - - let resp = self - .client - .get(endpoint) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.status), - } - } - - // get_default_transaction_arguments will prepare the transaction creation argument by querying the account's info - pub async fn get_default_transaction_arguments( - &self, - address: &Address, - network_configs: &NetworkConfig, - ) -> Result { - let account = self.get_account(address).await?; - - Ok(ArgCreateTransaction { - nonce: account.nonce, - value: "".to_string(), - rcv_addr: address.clone(), - snd_addr: address.clone(), - gas_price: network_configs.min_gas_price, - gas_limit: network_configs.min_gas_limit, - data: None, - signature: "".to_string(), - chain_id: network_configs.chain_id.clone(), - version: network_configs.min_transaction_version, - options: 0, - available_balance: account.balance, - }) - } - - pub async fn send_transaction(&self, tx: &Transaction) -> Result { - let endpoint = self.get_endpoint(SEND_TRANSACTION_ENDPOINT); - let resp = self - .client - .post(endpoint) - .json(tx) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b.tx_hash), - } - } - - pub async fn send_transactions(&self, txs: &Vec) -> Result> { - let endpoint = self.get_endpoint(SEND_MULTIPLE_TRANSACTIONS_ENDPOINT); - let resp = self - .client - .post(endpoint) - .json(txs) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => { - let mut tx_hashs: Vec = vec![]; - for key in b.txs_hashes.keys().sorted() { - tx_hashs.push(b.txs_hashes[key].clone()); - } - - Ok(tx_hashs) - }, - } - } - - // execute_vmquery retrieves data from existing SC trie through the use of a VM - pub async fn execute_vmquery( - &self, - vm_request: &VmValueRequest, - ) -> Result { - let endpoint = self.get_endpoint(VM_VALUES_ENDPOINT); - let resp = self - .client - .post(endpoint) - .json(vm_request) - .send() - .await? - .json::() - .await?; - - match resp.data { - None => Err(anyhow!("{}", resp.error)), - Some(b) => Ok(b), - } - } -} diff --git a/sdk/core/src/crypto/private_key.rs b/sdk/core/src/crypto/private_key.rs index 16870e7230..58ef821974 100644 --- a/sdk/core/src/crypto/private_key.rs +++ b/sdk/core/src/crypto/private_key.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use super::edwards25519::{sc_mul_add, sc_reduce}; use crate::crypto::edwards25519::extended_group_element::ExtendedGroupElement; use anyhow::{anyhow, Result}; @@ -126,9 +128,9 @@ impl PrivateKey { } } -impl ToString for PrivateKey { - fn to_string(&self) -> String { - hex::encode(&self.0[..32]) +impl Display for PrivateKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + hex::encode(&self.0[..32]).fmt(f) } } diff --git a/sdk/core/src/crypto/public_key.rs b/sdk/core/src/crypto/public_key.rs index 3013123dbd..89b5211262 100644 --- a/sdk/core/src/crypto/public_key.rs +++ b/sdk/core/src/crypto/public_key.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use super::private_key::PrivateKey; use anyhow::Result; use bech32::{self, ToBase32, Variant}; @@ -44,9 +46,9 @@ impl<'a> From<&'a PrivateKey> for PublicKey { } } -impl ToString for PublicKey { - fn to_string(&self) -> String { - hex::encode(self.0) +impl Display for PublicKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + hex::encode(self.0).fmt(f) } } diff --git a/sdk/core/src/data/address.rs b/sdk/core/src/data/address.rs index 9612157326..f8ac4212c3 100644 --- a/sdk/core/src/data/address.rs +++ b/sdk/core/src/data/address.rs @@ -1,4 +1,4 @@ -use std::fmt::Debug; +use std::fmt::{Debug, Display}; use crate::crypto::public_key::PublicKey; use anyhow::Result; @@ -51,9 +51,9 @@ impl<'a> From<&'a PublicKey> for Address { } } -impl ToString for Address { - fn to_string(&self) -> String { - self.to_bech32_string().unwrap() +impl Display for Address { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.to_bech32_string().unwrap().as_str()) } } @@ -63,6 +63,12 @@ impl Debug for Address { } } +impl Default for Address { + fn default() -> Self { + Address::from_bytes([0u8; 32]) + } +} + impl Serialize for Address { fn serialize(&self, serializer: S) -> Result where diff --git a/sdk/core/src/data/transaction.rs b/sdk/core/src/data/transaction.rs index 452f0d3679..ed0a51b8df 100644 --- a/sdk/core/src/data/transaction.rs +++ b/sdk/core/src/data/transaction.rs @@ -48,7 +48,7 @@ pub struct ResponseTxCost { } // TransactionOnNetwork holds a transaction's info entry in a hyper block -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, Default)] #[serde(rename_all = "camelCase")] pub struct TransactionOnNetwork { #[serde(rename = "type")] @@ -67,19 +67,19 @@ pub struct TransactionOnNetwork { pub destination_shard: u32, pub block_nonce: u64, pub block_hash: String, - pub notarized_at_source_in_meta_nonce: u64, + pub notarized_at_source_in_meta_nonce: Option, #[serde(rename = "NotarizedAtSourceInMetaHash")] - pub notarized_at_source_in_meta_hash: String, - pub notarized_at_destination_in_meta_nonce: u64, - pub notarized_at_destination_in_meta_hash: String, + pub notarized_at_source_in_meta_hash: Option, + pub notarized_at_destination_in_meta_nonce: Option, + pub notarized_at_destination_in_meta_hash: Option, pub processing_type_on_destination: String, pub miniblock_type: String, pub miniblock_hash: String, pub timestamp: u64, pub data: Option, pub status: String, - pub hyperblock_nonce: u64, - pub hyperblock_hash: String, + pub hyperblock_nonce: Option, + pub hyperblock_hash: Option, pub smart_contract_results: Option>, pub logs: Option, } @@ -132,6 +132,7 @@ pub struct TransactionInfoData { // TransactionInfo holds a transaction info response from the network #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TransactionInfo { + #[serde(default)] pub error: String, pub code: String, pub data: Option, diff --git a/sdk/core/src/gateway.rs b/sdk/core/src/gateway.rs new file mode 100644 index 0000000000..35e2668b50 --- /dev/null +++ b/sdk/core/src/gateway.rs @@ -0,0 +1,15 @@ +mod gateway_account; +mod gateway_block; +mod gateway_network; +mod gateway_proxy; +mod gateway_tx; +mod gateway_tx_retrieve; + +pub use gateway_proxy::GatewayProxy; + +pub const MAINNET_GATEWAY: &str = "https://gateway.multiversx.com"; +pub const TESTNET_GATEWAY: &str = "https://testnet-gateway.multiversx.com"; +pub const DEVNET_GATEWAY: &str = "https://devnet-gateway.multiversx.com"; + +// MetachainShardId will be used to identify a shard ID as metachain +pub const METACHAIN_SHARD_ID: u32 = 0xFFFFFFFF; diff --git a/sdk/core/src/gateway/gateway_account.rs b/sdk/core/src/gateway/gateway_account.rs new file mode 100644 index 0000000000..7d72258544 --- /dev/null +++ b/sdk/core/src/gateway/gateway_account.rs @@ -0,0 +1,112 @@ +use crate::data::{ + account::{Account, AccountResponse}, + account_storage::AccountStorageResponse, + address::Address, + esdt::{EsdtBalance, EsdtBalanceResponse, EsdtRolesResponse}, +}; +use anyhow::{anyhow, Result}; +use std::collections::HashMap; + +use super::GatewayProxy; + +const ACCOUNT_ENDPOINT: &str = "address/"; +const KEYS_ENDPOINT: &str = "/keys/"; + +impl GatewayProxy { + // get_account retrieves an account info from the network (nonce, balance) + pub async fn get_account(&self, address: &Address) -> Result { + if !address.is_valid() { + return Err(anyhow!("invalid address")); + } + + let endpoint = ACCOUNT_ENDPOINT.to_string() + address.to_string().as_str(); + let endpoint = self.get_endpoint(endpoint.as_str()); + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.account), + } + } + + // get_account_esdt_roles retrieves an all esdt roles of an account from the network + pub async fn get_account_esdt_roles( + &self, + address: &Address, + ) -> Result>> { + if !address.is_valid() { + return Err(anyhow!("invalid address")); + } + + let endpoint = ACCOUNT_ENDPOINT.to_string() + address.to_string().as_str() + "/esdts/roles"; + let endpoint = self.get_endpoint(endpoint.as_str()); + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.roles), + } + } + + // get_account_esdt_tokens retrieves an all esdt token of an account from the network + pub async fn get_account_esdt_tokens( + &self, + address: &Address, + ) -> Result> { + if !address.is_valid() { + return Err(anyhow!("invalid address")); + } + + let endpoint = ACCOUNT_ENDPOINT.to_string() + address.to_string().as_str() + "/esdt"; + let endpoint = self.get_endpoint(endpoint.as_str()); + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.esdts), + } + } + + // get_account_esdt_tokens retrieves an all esdt token of an account from the network + pub async fn get_account_storage_keys( + &self, + address: &Address, + ) -> Result> { + if !address.is_valid() { + return Err(anyhow!("invalid address")); + } + + let endpoint = ACCOUNT_ENDPOINT.to_string() + address.to_string().as_str() + KEYS_ENDPOINT; + let endpoint = self.get_endpoint(endpoint.as_str()); + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.pairs), + } + } +} diff --git a/sdk/core/src/gateway/gateway_block.rs b/sdk/core/src/gateway/gateway_block.rs new file mode 100644 index 0000000000..b6daf57abb --- /dev/null +++ b/sdk/core/src/gateway/gateway_block.rs @@ -0,0 +1,66 @@ +use crate::data::{ + hyperblock::{HyperBlock, HyperBlockResponse}, + network_status::NetworkStatusResponse, +}; +use anyhow::{anyhow, Result}; + +use super::GatewayProxy; +use super::METACHAIN_SHARD_ID; + +const GET_HYPER_BLOCK_BY_NONCE_ENDPOINT: &str = "hyperblock/by-nonce/"; +const GET_HYPER_BLOCK_BY_HASH_ENDPOINT: &str = "hyperblock/by-hash/"; +const GET_NETWORK_STATUS_ENDPOINT: &str = "network/status"; + +impl GatewayProxy { + async fn get_hyper_block(&self, endpoint: &str) -> Result { + let endpoint = self.get_endpoint(endpoint); + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.hyperblock), + } + } + + // get_hyper_block_by_hash retrieves a hyper block's info by hash from the network + pub async fn get_hyper_block_by_hash(&self, hash: &str) -> Result { + let endpoint = GET_HYPER_BLOCK_BY_HASH_ENDPOINT.to_string() + hash; + self.get_hyper_block(endpoint.as_str()).await + } + + // get_hyper_block_by_nonce retrieves a hyper block's info by nonce from the network + pub async fn get_hyper_block_by_nonce(&self, nonce: u64) -> Result { + let endpoint = GET_HYPER_BLOCK_BY_NONCE_ENDPOINT.to_string() + nonce.to_string().as_str(); + self.get_hyper_block(endpoint.as_str()).await + } + + // get_latest_hyper_block_nonce retrieves the latest hyper block (metachain) nonce from the network + pub async fn get_latest_hyper_block_nonce(&self, with_metachain: bool) -> Result { + let mut endpoint = GET_NETWORK_STATUS_ENDPOINT.to_string(); + + if with_metachain { + endpoint = format!("{GET_NETWORK_STATUS_ENDPOINT}/{METACHAIN_SHARD_ID}"); + } + + let endpoint = self.get_endpoint(endpoint.as_str()); + + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.status.nonce), + } + } +} diff --git a/sdk/core/src/gateway/gateway_network.rs b/sdk/core/src/gateway/gateway_network.rs new file mode 100644 index 0000000000..8b02a57d0d --- /dev/null +++ b/sdk/core/src/gateway/gateway_network.rs @@ -0,0 +1,46 @@ +use crate::data::{ + network_config::{NetworkConfig, NetworkConfigResponse}, + network_economics::{NetworkEconomics, NetworkEconomicsResponse}, +}; +use anyhow::{anyhow, Result}; + +use super::GatewayProxy; + +const NETWORK_CONFIG_ENDPOINT: &str = "network/config"; +const NETWORK_ECONOMICS_ENDPOINT: &str = "network/economics"; + +impl GatewayProxy { + // get_network_config retrieves the network configuration from the proxy + pub async fn get_network_config(&self) -> Result { + let endpoint = self.get_endpoint(NETWORK_CONFIG_ENDPOINT); + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.config), + } + } + + // get_network_economics retrieves the network economics from the proxy + pub async fn get_network_economics(&self) -> Result { + let endpoint = self.get_endpoint(NETWORK_ECONOMICS_ENDPOINT); + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.metrics), + } + } +} diff --git a/sdk/core/src/gateway/gateway_proxy.rs b/sdk/core/src/gateway/gateway_proxy.rs new file mode 100644 index 0000000000..47925cd79f --- /dev/null +++ b/sdk/core/src/gateway/gateway_proxy.rs @@ -0,0 +1,21 @@ +use reqwest::Client; + +/// Allows communication with the MultiversX gateway API. +#[derive(Clone, Debug)] +pub struct GatewayProxy { + pub(crate) proxy_url: String, + pub(crate) client: Client, +} + +impl GatewayProxy { + pub fn new(proxy_url: String) -> Self { + Self { + proxy_url, + client: Client::new(), + } + } + + pub(crate) fn get_endpoint(&self, endpoint: &str) -> String { + format!("{}/{}", self.proxy_url, endpoint) + } +} diff --git a/sdk/core/src/gateway/gateway_tx.rs b/sdk/core/src/gateway/gateway_tx.rs new file mode 100644 index 0000000000..47aa8b5a83 --- /dev/null +++ b/sdk/core/src/gateway/gateway_tx.rs @@ -0,0 +1,184 @@ +use crate::data::{ + address::Address, + network_config::NetworkConfig, + transaction::{ + ArgCreateTransaction, ResponseTxCost, SendTransactionResponse, SendTransactionsResponse, + Transaction, TransactionInfo, TransactionOnNetwork, TransactionStatus, TxCostResponseData, + }, + vm::{ResponseVmValue, VmValueRequest, VmValuesResponseData}, +}; +use anyhow::{anyhow, Result}; +use itertools::Itertools; + +use super::GatewayProxy; + +const COST_TRANSACTION_ENDPOINT: &str = "transaction/cost"; +const SEND_TRANSACTION_ENDPOINT: &str = "transaction/send"; +const SEND_MULTIPLE_TRANSACTIONS_ENDPOINT: &str = "transaction/send-multiple"; +const GET_TRANSACTION_INFO_ENDPOINT: &str = "transaction/"; +const WITH_RESULTS_QUERY_PARAM: &str = "?withResults=true"; +const VM_VALUES_ENDPOINT: &str = "vm-values/query"; + +impl GatewayProxy { + // request_transaction_cost retrieves how many gas a transaction will consume + pub async fn request_transaction_cost(&self, tx: &Transaction) -> Result { + let endpoint = self.get_endpoint(COST_TRANSACTION_ENDPOINT); + let resp = self + .client + .post(endpoint) + .json(tx) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b), + } + } + + async fn get_transaction_info_internal( + &self, + hash: &str, + with_results: bool, + ) -> Result { + let mut endpoint = GET_TRANSACTION_INFO_ENDPOINT.to_string() + hash; + + if with_results { + endpoint += WITH_RESULTS_QUERY_PARAM + } + + let endpoint = self.get_endpoint(endpoint.as_str()); + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.transaction), + } + } + + // get_transaction_info retrieves a transaction's details from the network + pub async fn get_transaction_info(&self, hash: &str) -> Result { + self.get_transaction_info_internal(hash, false).await + } + + // get_transaction_info_with_results retrieves a transaction's details from the network with events + pub async fn get_transaction_info_with_results( + &self, + hash: &str, + ) -> Result { + self.get_transaction_info_internal(hash, true).await + } + + // get_transaction_status retrieves a transaction's status from the network + pub async fn get_transaction_status(&self, hash: &str) -> Result { + let endpoint = format!("transaction/{hash}/status"); + let endpoint = self.get_endpoint(endpoint.as_str()); + + let resp = self + .client + .get(endpoint) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.status), + } + } + + // get_default_transaction_arguments will prepare the transaction creation argument by querying the account's info + pub async fn get_default_transaction_arguments( + &self, + address: &Address, + network_configs: &NetworkConfig, + ) -> Result { + let account = self.get_account(address).await?; + + Ok(ArgCreateTransaction { + nonce: account.nonce, + value: "".to_string(), + rcv_addr: address.clone(), + snd_addr: address.clone(), + gas_price: network_configs.min_gas_price, + gas_limit: network_configs.min_gas_limit, + data: None, + signature: "".to_string(), + chain_id: network_configs.chain_id.clone(), + version: network_configs.min_transaction_version, + options: 0, + available_balance: account.balance, + }) + } + + pub async fn send_transaction(&self, tx: &Transaction) -> Result { + let endpoint = self.get_endpoint(SEND_TRANSACTION_ENDPOINT); + let resp = self + .client + .post(endpoint) + .json(tx) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b.tx_hash), + } + } + + pub async fn send_transactions(&self, txs: &Vec) -> Result> { + let endpoint = self.get_endpoint(SEND_MULTIPLE_TRANSACTIONS_ENDPOINT); + let resp = self + .client + .post(endpoint) + .json(txs) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => { + let mut tx_hashs: Vec = vec![]; + for key in b.txs_hashes.keys().sorted() { + tx_hashs.push(b.txs_hashes[key].clone()); + } + + Ok(tx_hashs) + }, + } + } + + // execute_vmquery retrieves data from existing SC trie through the use of a VM + pub async fn execute_vmquery( + &self, + vm_request: &VmValueRequest, + ) -> Result { + let endpoint = self.get_endpoint(VM_VALUES_ENDPOINT); + let resp = self + .client + .post(endpoint) + .json(vm_request) + .send() + .await? + .json::() + .await?; + + match resp.data { + None => Err(anyhow!("{}", resp.error)), + Some(b) => Ok(b), + } + } +} diff --git a/sdk/core/src/gateway/gateway_tx_retrieve.rs b/sdk/core/src/gateway/gateway_tx_retrieve.rs new file mode 100644 index 0000000000..821713f972 --- /dev/null +++ b/sdk/core/src/gateway/gateway_tx_retrieve.rs @@ -0,0 +1,63 @@ +use crate::data::transaction::TransactionOnNetwork; +use log::info; +use std::time::{Duration, Instant}; + +use super::GatewayProxy; + +const INITIAL_BACKOFF_DELAY: f32 = 1.4; +const MAX_RETRIES: usize = 8; +const MAX_BACKOFF_DELAY: Duration = Duration::from_secs(6); + +impl GatewayProxy { + /// Retrieves a transaction from the network. + pub async fn retrieve_tx_on_network(&self, tx_hash: String) -> TransactionOnNetwork { + let mut retries = 0; + let mut backoff_delay = Duration::from_secs_f32(INITIAL_BACKOFF_DELAY); + let start_time = Instant::now(); + + loop { + match self.get_transaction_status(&tx_hash).await { + Ok(status) => { + // checks if transaction status is final + match status.as_str() { + "success" | "fail" => { + // retrieve transaction info with results + let transaction_info_with_results = self + .get_transaction_info_with_results(&tx_hash) + .await + .unwrap(); + info!( + "Transaction retrieved successfully, with status {}: {:#?}", + status, transaction_info_with_results + ); + return transaction_info_with_results; + }, + _ => { + continue; + }, + } + }, + Err(err) => { + retries += 1; + if retries >= MAX_RETRIES { + info!("Transaction failed, max retries exceeded: {}", err); + println!("Transaction failed, max retries exceeded: {}", err); + break; + } + + let backoff_time = backoff_delay.min(MAX_BACKOFF_DELAY); + tokio::time::sleep(backoff_time).await; + backoff_delay *= 2; // exponential backoff + }, + } + } + + // retries have been exhausted + let elapsed_time = start_time.elapsed(); + println!( + "Fetching transaction failed and retries exhausted, returning default transaction. Total elapsed time: {:?}", + elapsed_time + ); + TransactionOnNetwork::default() + } +} diff --git a/sdk/core/src/lib.rs b/sdk/core/src/lib.rs index f37f2197e5..3a1db99fd7 100644 --- a/sdk/core/src/lib.rs +++ b/sdk/core/src/lib.rs @@ -1,5 +1,5 @@ -pub mod blockchain; pub mod crypto; pub mod data; +pub mod gateway; pub mod utils; pub mod wallet; diff --git a/sdk/scenario-format/src/value_interpreter/reconstructor.rs b/sdk/scenario-format/src/value_interpreter/reconstructor.rs index 8ff0b47bf8..6efacefba4 100644 --- a/sdk/scenario-format/src/value_interpreter/reconstructor.rs +++ b/sdk/scenario-format/src/value_interpreter/reconstructor.rs @@ -133,7 +133,7 @@ fn address_pretty(value: &[u8]) -> String { format!("address:{}", address_str.trim_end_matches('_').to_owned()) } else { let mut address_str = String::from_utf8_lossy(&value[..SC_ADDRESS_LENGTH - 1]).to_string(); - address_str = address_str.trim_end_matches('_').to_owned(); + address_str = address_str.trim_end_matches('_').to_string(); let shard_id = value[SC_ADDRESS_LENGTH - 1]; let address_expr = format!("address:{address_str}#{shard_id:02x}"); if !can_interpret_as_string(&[value[SC_ADDRESS_LENGTH - 1]]) { diff --git a/tests-coverage.sh b/tests-coverage.sh deleted file mode 100755 index 68139f8a8e..0000000000 --- a/tests-coverage.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -RUSTFLAGS="-C instrument-coverage" \ - cargo test --tests - -PROFRAW_FILES=$(find . -name "default_*.profraw") -llvm-profdata merge -sparse $PROFRAW_FILES -o tests.profdata -find . -name "default_*.profraw" -delete - -llvm-cov export \ - $( \ - for file in \ - $( \ - RUSTFLAGS="-C instrument-coverage" \ - cargo test --tests --no-run --message-format=json \ - | jq -r "select(.profile.test == true) | .filenames[]" \ - | grep -v dSYM - \ - ); \ - do \ - printf "%s %s " -object $file; \ - done \ - ) \ - --ignore-filename-regex='/.cargo/registry' \ - --ignore-filename-regex='rustc/' \ - --ignore-filename-regex='meta/src' \ - --ignore-filename-regex='wasm-adapter' \ - --ignore-filename-regex='benchmarks/' \ - --ignore-filename-regex='tests/' \ - --ignore-filename-regex='tools/coverage-renderer/' \ - --instr-profile=tests.profdata --summary-only --format=text > tests.coverage -rm ./tests.profdata - -cargo run --quiet --bin coverage-renderer ./tests.coverage > coverage.md -rm ./tests.coverage \ No newline at end of file diff --git a/tools/coverage-renderer/Cargo.toml b/tools/coverage-renderer/Cargo.toml deleted file mode 100644 index eb7a044055..0000000000 --- a/tools/coverage-renderer/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "coverage-renderer" -version = "0.1.0" -edition = "2021" - -[dependencies] -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -anyhow = "1.0.44" \ No newline at end of file diff --git a/tools/coverage-renderer/src/cargo.rs b/tools/coverage-renderer/src/cargo.rs deleted file mode 100644 index 53c67e394c..0000000000 --- a/tools/coverage-renderer/src/cargo.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::process::Command; - -use anyhow::{bail, Result}; - -pub fn get_workspace_root() -> Result { - let output = Command::new("cargo") - .args(["metadata", "--no-deps", "--format-version=1"]) - .output()?; - - let metadata: serde_json::Value = serde_json::from_slice(&output.stdout)?; - - let Some(workspace_root) = metadata["workspace_root"].as_str() else { - bail!("Failed to get workspace root"); - }; - - Ok(workspace_root.to_owned()) -} diff --git a/tools/coverage-renderer/src/llvm_cov.rs b/tools/coverage-renderer/src/llvm_cov.rs deleted file mode 100644 index ed4f40104f..0000000000 --- a/tools/coverage-renderer/src/llvm_cov.rs +++ /dev/null @@ -1,40 +0,0 @@ -use anyhow::{bail, Result}; -use serde::Deserialize; -use serde_json::Value; - -#[derive(Deserialize)] -pub struct Coverage { - pub files: Vec, - pub totals: Summary, -} - -#[derive(Deserialize)] -pub struct SummaryItem { - pub count: u64, - pub covered: u64, - pub percent: f64, -} - -#[derive(Deserialize)] -pub struct Summary { - pub functions: SummaryItem, - pub lines: SummaryItem, - pub instantiations: SummaryItem, - pub regions: SummaryItem, -} - -#[derive(Deserialize)] -pub struct FileSummary { - pub filename: String, - pub summary: Summary, -} - -pub fn parse_llvm_cov_output(output: &str) -> Result { - let llvm_cov_output: Value = serde_json::from_str(output)?; - let Some(coverage) = llvm_cov_output.get("data").and_then(|data| data.get(0)) else { - bail!("Invalid llvm-cov output"); - }; - - let coverage = serde_json::from_value(coverage.to_owned())?; - Ok(coverage) -} diff --git a/tools/coverage-renderer/src/main.rs b/tools/coverage-renderer/src/main.rs deleted file mode 100644 index 4d4234555d..0000000000 --- a/tools/coverage-renderer/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -mod cargo; -mod llvm_cov; -mod renderer; - -use anyhow::{bail, Result}; -use std::env; - -use llvm_cov::parse_llvm_cov_output; -use renderer::render_coverage; - -fn main() -> Result<()> { - let mut args = env::args(); - - if args.len() < 2 { - bail!("Usage: coverage-renderer "); - } - - let root = cargo::get_workspace_root()?; - - let input_path = args.nth(1).unwrap(); - let input = std::fs::read_to_string(input_path)?; - - let coverage = parse_llvm_cov_output(&input)?; - - render_coverage(&coverage, &root); - - Ok(()) -} diff --git a/tools/coverage-renderer/src/renderer.rs b/tools/coverage-renderer/src/renderer.rs deleted file mode 100644 index ae230d9c6c..0000000000 --- a/tools/coverage-renderer/src/renderer.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::llvm_cov::{Coverage, FileSummary, Summary}; - -pub fn render_coverage(coverage: &Coverage, root: &str) { - render_header(); - render_totals(&coverage.totals); - render_files(&coverage.files, root); -} - -fn render_header() { - println!("# Coverage Summary"); - println!(); -} - -fn render_totals(summary: &Summary) { - println!("## Totals"); - - println!("| | Count | Covered | % |"); - println!("|---|---|---|---|"); - println!( - "| Lines | {} | {} | {:.2} |", - summary.lines.count, summary.lines.covered, summary.lines.percent - ); - println!( - "| Regions | {} | {} | {:.2} |", - summary.regions.count, summary.regions.covered, summary.regions.percent - ); - println!( - "| Functions | {} | {} | {:.2} |", - summary.functions.count, summary.functions.covered, summary.functions.percent - ); - println!( - "| Instantiations | {} | {} | {:.2} |", - summary.instantiations.count, - summary.instantiations.covered, - summary.instantiations.percent - ); - - println!(); -} - -fn render_files(files: &[FileSummary], root: &str) { - println!("## Files"); - println!("
Expand\n"); - println!("| File | Lines | Regions | Functions | Instantiations |"); - println!("|---|---|---|---|---|"); - for file in files { - render_file(file, root); - } - - println!("
"); -} - -fn render_file(file: &FileSummary, root: &str) { - let summary = &file.summary; - let filename = file.filename.strip_prefix(root).unwrap(); - - println!( - "| {} | {:.2}% | {:.2}% | {:.2}% | {:.2}% |", - filename, - summary.lines.percent, - summary.regions.percent, - summary.functions.percent, - summary.instantiations.percent - ); -} diff --git a/tools/mxpy-snippet-generator/Cargo.toml b/tools/mxpy-snippet-generator/Cargo.toml index 6e7ab2d1b7..42979fd0b1 100644 --- a/tools/mxpy-snippet-generator/Cargo.toml +++ b/tools/mxpy-snippet-generator/Cargo.toml @@ -10,7 +10,7 @@ name = "mxpy-snippet-generator" path = "src/mxpy_snippet_generator.rs" [dependencies.multiversx-sc] -version = "0.47.5" +version = "0.50.3" path = "../../framework/base" [dependencies] diff --git a/tools/mxpy-snippet-generator/src/mxpy_snippet_generator.rs b/tools/mxpy-snippet-generator/src/mxpy_snippet_generator.rs index 02521cbfad..4a4f397b98 100644 --- a/tools/mxpy-snippet-generator/src/mxpy_snippet_generator.rs +++ b/tools/mxpy-snippet-generator/src/mxpy_snippet_generator.rs @@ -133,7 +133,7 @@ impl MxpySnippetGenerator { } pub fn set_egld_value(&mut self, egld_value: &num_bigint::BigUint) { - self.egld_value = egld_value.clone(); + self.egld_value.clone_from(egld_value); } pub fn add_esdt_transfer( diff --git a/tools/payload-macro-generator/.gitignore b/tools/payload-macro-generator/.gitignore new file mode 100644 index 0000000000..4ddcf592f7 --- /dev/null +++ b/tools/payload-macro-generator/.gitignore @@ -0,0 +1,2 @@ +/target +output.rs \ No newline at end of file diff --git a/tools/payload-macro-generator/Cargo.toml b/tools/payload-macro-generator/Cargo.toml new file mode 100644 index 0000000000..8a9206efdf --- /dev/null +++ b/tools/payload-macro-generator/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "payload-macro-generator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/tools/payload-macro-generator/src/main.rs b/tools/payload-macro-generator/src/main.rs new file mode 100644 index 0000000000..12a0d4c581 --- /dev/null +++ b/tools/payload-macro-generator/src/main.rs @@ -0,0 +1,25 @@ +use std::{ + fs::File, + io::{self, Write}, +}; + +const MIN: usize = 1; +const MAX_X: usize = 48; +const MAX_Y: usize = 128; + +/// Generates the payload_add! macros in the ManagedVecItem implem,entation. +/// +/// TODO: remove once generic const expressions are stabilized in Rust. +fn main() -> io::Result<()> { + let mut file = File::create("output.rs")?; + + // Generate add_sub_const_decimals! macro combinations + for x in MIN..=MAX_X { + for y in MIN..=MAX_Y { + let sum = x + y; + writeln!(file, "payload_add!({}usize, {}usize, {}usize);", x, y, sum)?; + } + } + + Ok(()) +} diff --git a/tools/rust-debugger/format-tests/Cargo.toml b/tools/rust-debugger/format-tests/Cargo.toml index 806ca531ea..611b892909 100644 --- a/tools/rust-debugger/format-tests/Cargo.toml +++ b/tools/rust-debugger/format-tests/Cargo.toml @@ -9,15 +9,15 @@ name = "format-tests" path = "src/format_tests.rs" [dependencies.multiversx-sc] -version = "=0.47.5" +version = "=0.50.3" path = "../../../framework/base" [dependencies.multiversx-sc-scenario] -version = "=0.47.5" +version = "=0.50.3" path = "../../../framework/scenario" [dependencies.multiversx-chain-vm] -version = "=0.8.3" +version = "=0.8.4" path = "../../../vm" [dev-dependencies] diff --git a/tools/rust-debugger/format-tests/src/format_tests.rs b/tools/rust-debugger/format-tests/src/format_tests.rs index 9595691c66..5df781b92b 100644 --- a/tools/rust-debugger/format-tests/src/format_tests.rs +++ b/tools/rust-debugger/format-tests/src/format_tests.rs @@ -1,14 +1,14 @@ use multiversx_sc::{ codec::multi_types::OptionalValue, - esdt::ESDTSystemSmartContractProxy, types::{ heap::{Address, BoxedBytes}, - BigFloat, BigInt, BigUint, EgldOrEsdtTokenIdentifier, EsdtTokenPayment, ManagedAddress, - ManagedBuffer, ManagedByteArray, ManagedOption, ManagedType, ManagedVec, TokenIdentifier, + BigFloat, BigInt, BigUint, ESDTSystemSCAddress, EgldOrEsdtTokenIdentifier, + EsdtTokenPayment, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedOption, + ManagedType, ManagedVec, TokenIdentifier, }, }; use multiversx_sc_scenario::{ - api::{DebugHandle, DebugApi}, + api::{DebugApi, DebugHandle}, num_bigint::{BigInt as RustBigInt, BigUint as RustBigUint}, }; @@ -65,8 +65,7 @@ fn main() { let token_identifier: TokenIdentifier = TokenIdentifier::from("MYTOK-123456"); push!(to_check, token_identifier, "\"MYTOK-123456\""); - let system_sc = ESDTSystemSmartContractProxy::::new_proxy_obj(); - let managed_address = system_sc.esdt_system_sc_address(); + let managed_address = ESDTSystemSCAddress.to_managed_address::(); push!( to_check, managed_address, diff --git a/tools/rust-debugger/format-tests/tests/run_format_tests.rs b/tools/rust-debugger/format-tests/tests/run_format_tests.rs index 489d765ef3..6d61931f39 100644 --- a/tools/rust-debugger/format-tests/tests/run_format_tests.rs +++ b/tools/rust-debugger/format-tests/tests/run_format_tests.rs @@ -1,5 +1,3 @@ -#![feature(exit_status_error)] - #[cfg(test)] use std::{io::BufRead, path::Path, process::Command}; @@ -60,10 +58,10 @@ fn run_format_tests() { .output() .expect("Failed to run debugger"); - debugger_output - .status - .exit_ok() - .expect("Debugger returned a non-zero status"); + assert!( + debugger_output.status.success(), + "Debugger returned a non-zero status" + ); let stdout_lines: Vec = debugger_output .stdout diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 2246fc453a..907308f94f 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-chain-vm" -version = "0.8.3" +version = "0.8.4" edition = "2021" authors = [ @@ -27,7 +27,7 @@ rand_seeder = "0.2.2" ed25519-dalek = "1.0.1" itertools = "0.12.0" hex-literal = "=0.4.1" -bitflags = "=2.4.2" +bitflags = "=2.5.0" colored = "2.1.0" [dependencies.multiversx-chain-vm-executor] diff --git a/vm/src/tx_execution/builtin_function_mocks/general/claim_developer_rewards_mock.rs b/vm/src/tx_execution/builtin_function_mocks/general/claim_developer_rewards_mock.rs index 82bda4fa7d..0b7e9c694f 100644 --- a/vm/src/tx_execution/builtin_function_mocks/general/claim_developer_rewards_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/general/claim_developer_rewards_mock.rs @@ -37,7 +37,7 @@ impl BuiltinFunction for ClaimDeveloperRewards { tx_cache.with_account_mut(&tx_input.to, |account| { if account.contract_owner == Some(tx_input.from.clone()) { - developer_rewards = account.developer_rewards.clone(); + developer_rewards.clone_from(&account.developer_rewards); account.developer_rewards = BigUint::zero(); caller_is_owner = true; } diff --git a/vm/src/tx_mock/tx_async_call_data.rs b/vm/src/tx_mock/tx_async_call_data.rs index f30cd9a3c2..45cbce639c 100644 --- a/vm/src/tx_mock/tx_async_call_data.rs +++ b/vm/src/tx_mock/tx_async_call_data.rs @@ -93,7 +93,9 @@ fn extract_callback_payments( if !token_transfers.is_empty() { callback_payments.esdt_values = token_transfers.transfers; } else { - callback_payments.egld_value = async_call.call_value.clone(); + callback_payments + .egld_value + .clone_from(&async_call.call_value); } break; } diff --git a/vm/src/tx_mock/tx_cache_source.rs b/vm/src/tx_mock/tx_cache_source.rs index aee7ff96c5..55540137a9 100644 --- a/vm/src/tx_mock/tx_cache_source.rs +++ b/vm/src/tx_mock/tx_cache_source.rs @@ -23,7 +23,7 @@ impl TxCacheSource for TxCache { impl TxCacheSource for BlockchainState { fn load_account(&self, address: &VMAddress) -> Option { - self.accounts.get(address).map(AccountData::clone) + self.accounts.get(address).cloned() } fn blockchain_ref(&self) -> &BlockchainState { diff --git a/vm/src/tx_mock/tx_managed_types/handle_map.rs b/vm/src/tx_mock/tx_managed_types/handle_map.rs index 62f9c04659..4473e9104b 100644 --- a/vm/src/tx_mock/tx_managed_types/handle_map.rs +++ b/vm/src/tx_mock/tx_managed_types/handle_map.rs @@ -34,14 +34,14 @@ impl HandleMap { // TODO: consider simulating the actual error from the VM self.map .get(&handle) - .unwrap_or_else(|| panic!("handle not found")) + .unwrap_or_else(|| panic!("handle not found: {handle}")) } pub fn get_mut(&mut self, handle: RawHandle) -> &mut V { // TODO: consider simulating the actual error from the VM self.map .get_mut(&handle) - .unwrap_or_else(|| panic!("handle not found")) + .unwrap_or_else(|| panic!("handle not found: {handle}")) } pub fn insert(&mut self, handle: RawHandle, value: V) { diff --git a/vm/src/world_mock/account_data.rs b/vm/src/world_mock/account_data.rs index 343c49bb8d..9268c4535c 100644 --- a/vm/src/world_mock/account_data.rs +++ b/vm/src/world_mock/account_data.rs @@ -61,13 +61,13 @@ impl fmt::Display for AccountData { write!( f, "AccountData {{ - nonce: {}, - balance: {}, - esdt: [{} ], - username: {}, - storage: [{} ], - developerRewards: {}, - }}", + nonce: {}, + balance: {}, + esdt: [{} ], + username: {}, + storage: [{} ], + developerRewards: {}, + }}", self.nonce, self.egld_balance, self.esdt, diff --git a/vm/src/world_mock/blockchain_state.rs b/vm/src/world_mock/blockchain_state.rs index 28a339f54b..6890517215 100644 --- a/vm/src/world_mock/blockchain_state.rs +++ b/vm/src/world_mock/blockchain_state.rs @@ -1,7 +1,6 @@ -use std::{collections::HashMap, fmt::Debug}; - use num_bigint::BigUint; use num_traits::Zero; +use std::{collections::HashMap, fmt::Debug}; use crate::{tx_mock::BlockchainUpdate, types::VMAddress}; diff --git a/vm/src/world_mock/esdt_instances.rs b/vm/src/world_mock/esdt_instances.rs index 7fd574fac5..74c2432281 100644 --- a/vm/src/world_mock/esdt_instances.rs +++ b/vm/src/world_mock/esdt_instances.rs @@ -57,9 +57,9 @@ impl EsdtInstances { .0 .entry(nonce) .and_modify(|instance| { - instance.balance = value.clone(); + instance.balance.clone_from(value); instance.nonce = nonce; - instance.metadata = metadata.clone(); + instance.metadata.clone_from(&metadata); }) .or_insert_with(|| EsdtInstance { nonce,