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 9439824cd6..dc0bcc8596 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -5,6 +5,7 @@ on: branches: - master pull_request: + workflow_dispatch: permissions: checks: write @@ -13,10 +14,11 @@ permissions: jobs: contracts: name: Contracts - uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v2.3.3 + uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v3.1.0 with: - rust-toolchain: nightly-2023-05-26 - vmtools-repository: "https://github.com/multiversx/mx-chain-vm-v1_4-go/archive/{TAG}.tar.gz" - vmtools-version: v1.4.89 + 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 }} + 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 c4f0419846..9aaba9eadd 100644 --- a/.github/workflows/lldb-formatter-tests.yml +++ b/.github/workflows/lldb-formatter-tests.yml @@ -5,6 +5,7 @@ on: branches: - master pull_request: + workflow_dispatch: jobs: format_tests: @@ -15,7 +16,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: default: true - toolchain: nightly-2023-05-26 + toolchain: stable - name: Download vscode-lldb uses: robinraju/release-downloader@v1.5 diff --git a/.github/workflows/plotter-test.yml b/.github/workflows/plotter-test.yml new file mode 100644 index 0000000000..d509759003 --- /dev/null +++ b/.github/workflows/plotter-test.yml @@ -0,0 +1,30 @@ +name: CI + +on: + push: + branches: + - master + pull_request: + +permissions: + checks: write + pull-requests: write + +jobs: + template_test_current: + name: Plotter tests + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-unknown + + - name: Run plotter tests + run: | + cd tools/plotter + cargo test 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 c46bd4963c..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-05-26 + toolchain: stable target: wasm32-unknown-unknown - name: Setup the PATH variable @@ -43,12 +43,6 @@ jobs: which wasm2wat which run-scenarios - - name: Install libtinfo5 - if: inputs.install-libtinfo5 - run: | - sudo apt update - sudo apt install -y libtinfo5 - - name: Build project example outputs run: | ./zip-example-wasm.sh @@ -60,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 97f5e57ea5..56382850fe 100644 --- a/.github/workflows/template-test-current.yml +++ b/.github/workflows/template-test-current.yml @@ -22,34 +22,18 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: default: true - toolchain: nightly-2023-05-26 + toolchain: stable target: wasm32-unknown-unknown - - name: Setup the PATH variable - run: | - echo "PATH=$HOME/.local/bin:$HOME/multiversx-sdk/vmtools:$PATH" >> $GITHUB_ENV - - name: Install prerequisites run: | - pip3 install multiversx-sdk-cli==v6.0.0 - mkdir $HOME/multiversx-sdk - python3 -m multiversx_sdk_cli.cli deps install vmtools --tag v1.4.60 - - wget -O binaryen.tar.gz https://github.com/WebAssembly/binaryen/releases/download/version_112/binaryen-version_112-x86_64-linux.tar.gz - tar -xf binaryen.tar.gz - cp binaryen-version_112/bin/wasm-opt $HOME/.local/bin - - sudo apt install -y wabt=1.0.27-1 + cargo install wasm-opt + cargo install --path framework/meta + sc-meta install mx-scenario-go --tag v2.0.0 which wasm-opt - which wasm2wat - which run-scenarios - - - name: Install libtinfo5 - if: inputs.install-libtinfo5 - run: | - sudo apt update - sudo apt install -y libtinfo5 + which mx-scenario-go + mx-scenario-go --version - name: Run template tool test run: | diff --git a/.github/workflows/template-test-released.yml b/.github/workflows/template-test-released.yml index 32ffaa4910..e6227765db 100644 --- a/.github/workflows/template-test-released.yml +++ b/.github/workflows/template-test-released.yml @@ -22,34 +22,18 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: default: true - toolchain: nightly-2023-05-26 + toolchain: stable target: wasm32-unknown-unknown - - name: Setup the PATH variable - run: | - echo "PATH=$HOME/.local/bin:$HOME/multiversx-sdk/vmtools:$PATH" >> $GITHUB_ENV - - name: Install prerequisites run: | - pip3 install multiversx-sdk-cli==v6.0.0 - mkdir $HOME/multiversx-sdk - python3 -m multiversx_sdk_cli.cli deps install vmtools --tag v1.4.60 - - wget -O binaryen.tar.gz https://github.com/WebAssembly/binaryen/releases/download/version_112/binaryen-version_112-x86_64-linux.tar.gz - tar -xf binaryen.tar.gz - cp binaryen-version_112/bin/wasm-opt $HOME/.local/bin - - sudo apt install -y wabt=1.0.27-1 + cargo install wasm-opt + cargo install --path framework/meta + sc-meta install mx-scenario-go --tag v2.0.0 which wasm-opt - which wasm2wat - which run-scenarios - - - name: Install libtinfo5 - if: inputs.install-libtinfo5 - run: | - sudo apt update - sudo apt install -y libtinfo5 + which mx-scenario-go + mx-scenario-go --version - name: Run template tool test run: | diff --git a/.gitignore b/.gitignore index 630f52abb6..8295450d89 100644 --- a/.gitignore +++ b/.gitignore @@ -8,18 +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 +# 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 f88e8ec907..91d7147f03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,11 @@ The `mx-sdk-rs` repo contains many crates, grouped into several families. Crates For brevity, the changelog will only mention a short version of their name. They are: -- `multiversx-sc`, in short `sc`, the smart contract framework, 6 crates + 3 for contracts/modules: +- `multiversx-sc`, in short `sc`, the smart contract framework, 7 crates + 3 for contracts/modules: - `multiversx-sc` - `multiversx-sc-derive` - `multiversx-sc-meta` + - `multiversx-sc-meta-lib` - `multiversx-sc-scenario` - `multiversx-sc-snippets` - `multiversx-sc-wasm-adapter` @@ -26,6 +27,224 @@ 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.53.0 codec 0.21.0, vm 0.10.0, sdk 0.6.0, scenario-format 0.23.0] - 2024-09-04 +- Unified syntax: + - Whitebox testing; + - Proxy fix for ManagedOption; + - TestTokenIdentifier syntactic sugar. +- New ResultHandler: `ReturnsLogs`. +- Interactor: + - Fix on API fetch process status; + - Fix on ReturnsNewTokenIdentifier edge cases solved; + - Fix on ESDTTransfer for transfer step; + - Support for Keystore + password. +- Framework API support: EI 1.4 crypto functions. +- `sc-meta`: + - New `wallet` command: PEM and keystore generator and conversions; + - New `report` command: + - Generate json or Markdown report based on size, path, allocator and panic messages; + - Compare reports; + - Convert reports. +- VecMapper update with index. +- Substitution list: AddressToIdMapper +- Dependencies updated. + +## [sc 0.52.3] - 2024-08-06 +- Pause module events. + +## [sc 0.52.2] - 2024-08-01 +- `ManagedBufferReadToEnd` extract data methods. + +## [sc 0.52.1] - 2024-07-31 +- `ManagedBufferReadToEnd` `TypeAbi` implementation. + +## [sc 0.52.0, codec 0.20.1] - 2024-07-31 +- ManagedBufferReadToEnd type, which flushed a nested data buffer. +- Fixed hex and binary formatters for byte slices. +- Added EI 1.4 and 1.5 configs. +- Dependency upgrades. + +## [sc 0.51.1] +- `sc-meta upgrade` bugfix. + +## [sc 0.51.0, codec 0.20.0, vm 0.9.0, sdk 0.5.0, scenario-format 0.22.3] - 2024-07-06 +- Major refactoring of `multiversx-sc-meta` + - Crate `multiversx-sc-meta` split in 2: + 1. `multiversx-sc-meta` remains the standalone tool. For backwards compatibility, it can still be used in contract meta crates, but a warning will be issued. + 2. `multiversx-sc-meta-lib` is the contract-only library to contract meta crates. + - The refactoring came with few code changes, but dependencies were disentangled and cleaned up. + - Account retrieval tool was merged into `sc-meta` standalone. Previously little known feature, it enables downloading the full state of an account and formatting it as a mandos set state step. Very useful for generating tests and investigating state. + - `multiversx-sdk` was also refactored, especially the gateway proxy. +- A new code report is available in the `.mxsc.json` build output. The report analyzes the wasm code after build and always offers the following information: + - `imports`: what VM hooks are used; + - `eiCheck`: if the used imports comply with the environment interface (EI, allowed VM hooks); + - `hasAllocator`: is it allocates on the heap; + - `hasPanic`: whether it produces Rust panics and formats error messages using the standard Rust formatter (a source of code bloat). +- `ManagedDecimal` and `ManagedDecimalSigned`: + - New types that encapulate a managed `BigUint` and `BigInt` respectively, but treat them as base 10 fixed point rational numbers. + - Two flavors are allowed: the number of decimals is known at compile time (e.g. EGLD always has 18 decimals), or only at runtime. + - Type `ConstDecimals` is able to resolve conversions at compile time, reducing code size and making encoding and decoding easier, since the number of decimals does not need to be encoded. + - Regular `usize` number of decimals is resolved at runtime. + - All basic arithmetic operations are implemented for these types, just like for the big integers. +- Implemented logarithms: + - Natural logarithm `ln` for `ManagedDecimal`, `BigFloat`, and `BigInt`. + - Base 2 logarithm `log2` for `ManagedDecimal`. + - Precision is about 5 decimals, largely irrespective of input. + - The operation is cheap, `ln` costs 44980 gas for managed decimals and 153772 for big floats, largely irrespective of input. +- Smart contract code on the front-end: + - Framework and contract code, together with the Rust VM as a backend, can now be compiled to WebAssembly for front-end, using `wasm-bindgen`. + - A few incompatible Rust VM features needed to be made optional for this to work. +- Reverted changes in `sc 0.50.6` (`diagnostic::on_unimplemented` & rustc 1.78 dependency). +- Bugfix: `sync_call_readonly` can now be used with proxies. + + +## [sc 0.50.6] - 2024-07-05 +- Temporarily removed dependency to rustc 1.78, to ease transition from older versions. Will be re-enabled in 0.51.0. + +## [sc 0.50.5] - 2024-06-21 +- `#[storage_mapper_from_address] annotation. +- Added missing equality operator for test addresses (`TestAddress`, `TestSCAddress`). + +## [sc 0.50.4] - 2024-06-06 +- Compiler version requirement (1.78). +- Minor imports fix. + +## [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`. + +## [sc 0.47.4, vm 0.8.3] - 2024-02-08 +- Post-build wasm report added to `.mxsc.json` file. +- Fixed a dependency issue involving ed25519-dalek (downgraded dependency). + +## [sc 0.47.3, sdk 0.3.2] - 2024-02-06 +- SDK: changed the way to retrieve the new deployed address afte deploy/ +- Support for reading from another contract for the following storage mappers: `AddressToIdMapper`, `BiDiMapper`, `LinkedListMapper`, `SetMapper`, `SingleValueMapper`, `UniqueIdMapper`, `UnorderedSetMapper`, `UserMapper`, `VecMapper`, `WhitelistMapper`. +- Additional methods to access data nodes directly in the `SetMapper` and `QueueMapper`. + +## [sc 0.47.2, codec 0.18.6, vm 0.8.2, scenario-format 0.22.2] - 2024-02-02 +- Scenario testing infrastructure: + - The Rust VM can generate mock addresses, if not specified in advance. + - The `sc:` syntax now generates addresses with VM type 0x0500, same as the latest version of mx-scenario-go. + - Rust test support for checking `code_metadata`. +- Explicit discriminants supported for enums. +- Optimized `top_encode_number` function. It no longer contains branches or loops. +- Removed reliance on Rust nightly features `is_sorted` and `slice_partition_dedup`. + +## [sc 0.47.1, codec 0.18.5, vm 0.8.1, scenario-format 0.22.1] - 2024-01-29 +- Blockchain hooks: `get_code_metadata`, `is_builtin_function`. +- Support for `mxsc:` syntax in scenarios. +- Updated dependencies. + +## [sc 0.47.0, codec 0.18.4, vm 0.8.0, scenario-format 0.22.0] - 2024-01-23 +- Added support for the code metadata in the Rust VM and Rust scenarios backend. +- `sc-meta`: + - New `mx-scenario-go` installer; + - `--nocapture` flag added in `sc-meta test` CLI; + - Framework version system refactor, +- `SetMapper` and `QueueMapper` can read from another contract. +- Fixed an edge case when generating enum encoding. + +## [sc 0.46.1] - 2024-01-10 +- Interactor: fixed parsing of newly issued token identifier. + +## [sc 0.46.0] - 2024-01-05 +- Promises callback memory allocator bugfix. +- Removed features: `promises`, `managed-map`, `back-transfers`. +- Removed `hashbrown` dependency from framework. +- Imports in output now sorted. + +## [sc 0.45.2, codec 0.18.3, vm 0.7.1, scenario-format 0.21.1, sdk 0.3.1] - 2023-12-18 +- Updated framework dependencies to the latest versions: syn, bitflags, wasmparser, base64, sha2, sha3, itertools, hmac, pem, pbkdf2, etc. +- `sc-meta` improvements: + - `overflow-checks` field in `sc-config.toml`; + - Upgrade: new `--no-check` flag, which disables the compile check after major version upgrades; + - Template: `wasm` crates no longer copied for new versions; retroactively patched missing `multiversx.json` file for older versions. + +## [sc 0.45.1, codec 0.18.2] - 2023-11-24 +- Fixed sc-meta standalone install backwards compatibility. +- Better hygiene in codec derive. + +## [sc 0.45.0, vm 0.7.0, scenario-format 0.21.0, sdk 0.3.0] - 2023-11-24 +- Replicated VM 1.5 in the Rust VM. This includes support for: + - promises, + - back-transfers, + - modified event logs. +- New endpoint annotation, `#[upgrade]`. Contract variants with upgrade endpoint, but without init now allowed. +- Build system: + - `wasm` crates now fully generated based on data from `sc-config.toml` and root `Cargo.toml`. + - Setting wasm target dir automatically, if not specified, based on workspace. + ## [sc 0.44.0, vm 0.6.0] - 2023-11-03 - Back-transfer: - API support in framework (not yet implemented in the Rust VM); diff --git a/Cargo.lock b/Cargo.lock index 388b753b00..98fd053e54 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,28 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -85,9 +91,9 @@ dependencies = [ [[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", ] @@ -106,107 +112,111 @@ name = "alloc-features-meta" version = "0.0.0" dependencies = [ "alloc-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.75" +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 = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +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.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", ] [[package]] name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.5" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -240,14 +250,25 @@ 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]] name = "bech32" -version = "0.9.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" [[package]] name = "benchmark-common" @@ -271,7 +292,7 @@ name = "big-float-features-meta" version = "0.0.0" dependencies = [ "big-float-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -295,25 +316,9 @@ checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding", - "generic-array", -] +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -324,12 +329,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bonding-curve-contract" version = "0.0.0" @@ -344,14 +343,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.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", "serde", @@ -370,14 +369,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" @@ -387,17 +386,17 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cc" -version = "1.0.83" +version = "1.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b" dependencies = [ - "libc", + "shlex", ] [[package]] @@ -421,7 +420,7 @@ name = "check-pause-meta" version = "0.0.0" dependencies = [ "check-pause", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -438,14 +437,24 @@ version = "0.0.0" dependencies = [ "child", "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", ] [[package]] name = "clap" -version = "4.4.7" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -453,9 +462,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -465,37 +474,36 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -510,8 +518,10 @@ version = "0.0.0" dependencies = [ "builtin-func-features", "forwarder", + "forwarder-legacy", "forwarder-queue", "forwarder-raw", + "multiversx-sc", "multiversx-sc-scenario", "promises-features", "proxy-test-first", @@ -522,9 +532,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "convert_case" @@ -546,9 +556,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -556,37 +566,53 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] [[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", ] [[package]] -name = "crossbeam-utils" -version = "0.8.16" +name = "crossbeam-deque" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crowdfunding-erc20" version = "0.0.0" @@ -601,7 +627,7 @@ name = "crowdfunding-erc20-meta" version = "0.0.0" dependencies = [ "crowdfunding-erc20", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -620,7 +646,7 @@ name = "crowdfunding-esdt-meta" version = "0.0.0" dependencies = [ "crowdfunding-esdt", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -636,7 +662,7 @@ name = "crypto-bubbles-meta" version = "0.0.0" dependencies = [ "crypto-bubbles", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -649,16 +675,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "crypto-zombies" version = "0.0.0" @@ -672,21 +688,29 @@ name = "crypto-zombies-meta" version = "0.0.0" dependencies = [ "crypto-zombies", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", ] [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest 0.10.7", + "digest", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -700,26 +724,28 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", ] [[package]] -name = "digest" -version = "0.9.0" +name = "derive_arbitrary" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ - "generic-array", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -728,8 +754,9 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -745,16 +772,18 @@ name = "digital-cash-meta" version = "0.0.0" dependencies = [ "digital-cash", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] -name = "ed25519" -version = "1.5.3" +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ - "signature 1.6.4", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -764,27 +793,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", - "signature 2.1.0", + "signature", ] [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", - "ed25519 2.2.3", + "ed25519", "serde", - "sha2 0.10.8", + "sha2", + "subtle", "zeroize", ] [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "empty" @@ -800,14 +830,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", ] @@ -818,17 +848,27 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" -version = "0.10.0" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ + "anstream", + "anstyle", + "env_filter", "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] @@ -860,7 +900,7 @@ name = "erc1155-marketplace-meta" version = "0.0.0" dependencies = [ "erc1155-marketplace", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -868,7 +908,7 @@ name = "erc1155-meta" version = "0.0.0" dependencies = [ "erc1155", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -884,7 +924,7 @@ name = "erc1155-user-mock-meta" version = "0.0.0" dependencies = [ "erc1155-user-mock", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -900,7 +940,7 @@ name = "erc20-meta" version = "0.0.0" dependencies = [ "erc20", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -916,17 +956,17 @@ name = "erc721-meta" version = "0.0.0" dependencies = [ "erc721", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "errno" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -952,7 +992,7 @@ name = "esdt-system-sc-mock-meta" version = "0.0.0" dependencies = [ "esdt-system-sc-mock", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -968,7 +1008,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]] @@ -984,28 +1040,28 @@ 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.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fiat-crypto" -version = "0.2.2" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a481586acf778f1b1455424c343f71124b048ffa5f4fc3f8f6ae9dc432dcb3c7" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "first-contract" @@ -1021,17 +1077,17 @@ 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.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.8.0", ] [[package]] @@ -1057,9 +1113,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1077,24 +1133,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]] @@ -1104,7 +1176,6 @@ dependencies = [ "multiversx-sc", "multiversx-sc-scenario", "multiversx-sc-wasm-adapter", - "vault", ] [[package]] @@ -1112,7 +1183,7 @@ name = "forwarder-queue-meta" version = "0.0.0" dependencies = [ "forwarder-queue", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1128,7 +1199,7 @@ name = "forwarder-raw-meta" version = "0.0.0" dependencies = [ "forwarder-raw", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1145,14 +1216,14 @@ name = "fractional-nfts-meta" version = "0.0.0" dependencies = [ "fractional-nfts", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1165,9 +1236,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -1175,15 +1246,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1192,38 +1263,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -1249,47 +1320,49 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "globset" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata", + "regex-syntax", ] [[package]] name = "h2" -version = "0.3.21" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", @@ -1298,31 +1371,25 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", - "allocator-api2", + "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.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1338,19 +1405,18 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hmac" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "crypto-mac", - "digest 0.9.0", + "digest", ] [[package]] name = "http" -version = "0.2.9" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1359,26 +1425,32 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", - "pin-project-lite", ] [[package]] -name = "httparse" -version = "1.8.0" +name = "http-body-util" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] [[package]] -name = "httpdate" -version = "1.0.3" +name = "httparse" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "humantime" @@ -1388,46 +1460,82 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", "http", "http-body", "httparse", - "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + [[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1435,39 +1543,38 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" dependencies = [ + "crossbeam-deque", "globset", - "lazy_static", "log", "memchr", - "regex", + "regex-automata", "same-file", - "thread_local", "walkdir", "winapi-util", ] [[package]] name = "indexmap" -version = "1.9.3" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "equivalent", + "hashbrown", + "serde", ] [[package]] -name = "indexmap" -version = "2.1.0" +name = "inout" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "equivalent", - "hashbrown 0.14.2", + "generic-array", ] [[package]] @@ -1475,13 +1582,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]] @@ -1491,45 +1595,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] -name = "is-terminal" -version = "0.4.9" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -1557,7 +1656,7 @@ name = "kitty-auction-meta" version = "0.0.0" dependencies = [ "kitty-auction", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1575,7 +1674,7 @@ name = "kitty-genetic-alg-meta" version = "0.0.0" dependencies = [ "kitty-genetic-alg", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1594,7 +1693,7 @@ name = "kitty-ownership-meta" version = "0.0.0" dependencies = [ "kitty-ownership", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1610,20 +1709,20 @@ name = "large-storage-meta" version = "0.0.0" dependencies = [ "large-storage", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "linked-list-repeat" @@ -1639,14 +1738,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.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-esdt-and-nft" @@ -1661,24 +1760,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.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lottery-erc20" @@ -1694,7 +1799,7 @@ name = "lottery-erc20-meta" version = "0.0.0" dependencies = [ "lottery-erc20", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1710,7 +1815,7 @@ name = "lottery-esdt-meta" version = "0.0.0" dependencies = [ "lottery-esdt", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1727,7 +1832,7 @@ name = "managed-map-features-meta" version = "0.0.0" dependencies = [ "managed-map-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1744,14 +1849,14 @@ name = "map-repeat-meta" version = "0.0.0" dependencies = [ "map-repeat", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -1761,22 +1866,32 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "mio" -version = "0.8.9" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1792,7 +1907,7 @@ name = "multi-contract-features-meta" version = "0.0.0" dependencies = [ "multi-contract-features", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] @@ -1816,6 +1931,7 @@ version = "0.0.0" dependencies = [ "clap", "multisig", + "multiversx-sc", "multiversx-sc-modules", "multiversx-sc-scenario", "multiversx-sc-snippets", @@ -1828,12 +1944,12 @@ name = "multisig-meta" version = "0.0.0" dependencies = [ "multisig", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "multiversx-chain-scenario-format" -version = "0.20.0" +version = "0.23.0" dependencies = [ "bech32", "hex", @@ -1841,14 +1957,15 @@ dependencies = [ "num-traits", "serde", "serde_json", - "sha3 0.9.1", + "sha3", ] [[package]] name = "multiversx-chain-vm" -version = "0.6.0" +version = "0.10.0" dependencies = [ - "bitflags 1.3.2", + "bitflags", + "colored", "ed25519-dalek", "hex", "hex-literal", @@ -1858,8 +1975,8 @@ dependencies = [ "num-traits", "rand", "rand_seeder", - "sha2 0.10.8", - "sha3 0.10.8", + "sha2", + "sha3", ] [[package]] @@ -1870,12 +1987,14 @@ checksum = "b59072fa0624b55ae5ae3fa6bfa91515bbeb4ac440214bc4a509e2c8806d6e9f" [[package]] name = "multiversx-price-aggregator-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "arrayvec", + "getrandom", "multiversx-sc", "multiversx-sc-modules", "multiversx-sc-scenario", + "rand", ] [[package]] @@ -1884,98 +2003,116 @@ version = "0.0.0" dependencies = [ "multiversx-price-aggregator-sc", "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", ] [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ - "bitflags 1.3.2", - "hashbrown 0.14.2", + "bitflags", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", "num-bigint", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-codec-human-readable" version = "0.1.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "multiversx-sc-scenario", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-meta" -version = "0.44.0" +version = "0.53.0" dependencies = [ + "bip39", "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.53.0" +dependencies = [ + "clap", + "colored", + "convert_case", + "hex", + "lazy_static", + "multiversx-sc", "rustc_version", + "semver", "serde", "serde_json", "toml", "wasmparser", "wasmprinter", - "zip", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-scenario" -version = "0.44.0" +version = "0.53.0" dependencies = [ - "base64 0.13.1", + "base64", "bech32", - "clap", "colored", "hex", "itertools", @@ -1984,66 +2121,71 @@ dependencies = [ "multiversx-chain-vm", "multiversx-chain-vm-executor", "multiversx-sc", - "multiversx-sc-meta", - "multiversx-sdk", + "multiversx-sc-meta-lib", "num-bigint", "num-traits", "pathdiff", "serde", "serde_json", - "sha2 0.10.8", - "tokio", + "sha2", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-snippets" -version = "0.44.0" +version = "0.53.0" dependencies = [ - "base64 0.13.1", + "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.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sdk" -version = "0.2.0" +version = "0.6.0" dependencies = [ + "aes", "anyhow", - "base64 0.13.1", + "base64", "bech32", "bip39", - "ed25519 1.5.3", + "ctr", "hex", "hmac", "itertools", + "log", "pbkdf2", "pem", "rand", "reqwest", + "scrypt", "serde", "serde_json", "serde_repr", - "sha2 0.9.9", - "sha3 0.9.1", + "sha2", + "sha3", "tokio", + "uuid", "zeroize", ] [[package]] name = "multiversx-wegld-swap-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", "multiversx-sc-modules", @@ -2055,7 +2197,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", ] @@ -2072,11 +2214,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", @@ -2100,7 +2241,7 @@ dependencies = [ name = "nft-minter-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "nft-minter", ] @@ -2116,7 +2257,7 @@ dependencies = [ name = "nft-storage-prepay-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "nft-storage-prepay", ] @@ -2133,7 +2274,7 @@ dependencies = [ name = "nft-subscription-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "nft-subscription", ] @@ -2148,72 +2289,54 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[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 = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" -version = "0.32.1" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "opaque-debug" -version = "0.3.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.59" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.4.1", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -2230,7 +2353,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] @@ -2241,9 +2364,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.95" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -2271,7 +2394,7 @@ dependencies = [ name = "pair-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "order-book-pair", ] @@ -2287,7 +2410,7 @@ dependencies = [ name = "panic-message-features-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "panic-message-features", ] @@ -2295,7 +2418,6 @@ dependencies = [ name = "parent" version = "0.0.0" dependencies = [ - "child", "multiversx-sc", "multiversx-sc-scenario", ] @@ -2305,15 +2427,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", @@ -2321,15 +2443,26 @@ 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", + "windows-targets 0.52.6", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core", + "subtle", ] [[package]] @@ -2350,39 +2483,65 @@ 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.9.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "crypto-mac", + "digest", + "hmac", ] [[package]] name = "pem" -version = "1.1.1" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64 0.13.1", + "base64", + "serde", ] [[package]] name = "percent-encoding" -version = "2.3.0" +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 = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +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" @@ -2402,7 +2561,7 @@ dependencies = [ name = "ping-pong-egld-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "ping-pong-egld", ] @@ -2418,27 +2577,24 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "platforms" -version = "3.2.0" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -2448,15 +2604,13 @@ name = "promises-features" version = "0.0.0" dependencies = [ "multiversx-sc", - "multiversx-sc-scenario", - "vault", ] [[package]] name = "promises-features-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "promises-features", ] @@ -2473,7 +2627,7 @@ dependencies = [ name = "proxy-pause-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "proxy-pause", ] @@ -2490,7 +2644,7 @@ dependencies = [ name = "proxy-test-first-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "proxy-test-first", ] @@ -2506,7 +2660,7 @@ dependencies = [ name = "proxy-test-second-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "proxy-test-second", ] @@ -2523,15 +2677,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.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -2578,9 +2732,9 @@ dependencies = [ [[package]] name = "rand_seeder" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2890aaef0aa82719a50e808de264f9484b74b442e1a3a0e5ee38243ac40bdb" +checksum = "4a9febe641d2842ffc76ee962668a17578767c4e01735e4802b21ed9a24b2e4e" dependencies = [ "rand_core", ] @@ -2605,24 +2759,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.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -2632,9 +2786,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -2643,26 +2797,30 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" -version = "0.11.22" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" dependencies = [ - "base64 0.21.5", + "base64", "bytes", "encoding_rs", + "futures-channel", "futures-core", "futures-util", "h2", "http", "http-body", + "http-body-util", "hyper", + "hyper-rustls", "hyper-tls", + "hyper-util", "ipnet", "js-sys", "log", @@ -2671,9 +2829,11 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -2682,7 +2842,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "windows-registry", ] [[package]] @@ -2698,10 +2858,25 @@ dependencies = [ name = "rewards-distribution-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "rewards-distribution", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "ruplacer" version = "0.8.2" @@ -2728,7 +2903,7 @@ dependencies = [ name = "rust-snippets-generator-test-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "rust-snippets-generator-test", ] @@ -2751,43 +2926,92 @@ 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" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ - "bitflags 2.4.1", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.23.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +dependencies = [ + "base64", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" + +[[package]] +name = "rustls-webpki" +version = "0.102.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] [[package]] name = "same-file" @@ -2798,13 +3022,29 @@ 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.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2813,6 +3053,18 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scrypt" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" +dependencies = [ + "password-hash", + "pbkdf2", + "salsa20", + "sha2", +] + [[package]] name = "second-contract" version = "0.0.0" @@ -2826,17 +3078,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.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -2845,9 +3097,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -2866,15 +3118,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.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "send-tx-repeat" @@ -2888,58 +3140,59 @@ 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.190" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ - "indexmap 2.1.0", + "indexmap", "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_repr" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -2969,23 +3222,10 @@ dependencies = [ name = "set-repeat-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "set-repeat", ] -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.10.8" @@ -2994,51 +3234,48 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest", "keccak", - "opaque-debug", ] [[package]] -name = "sha3" -version = "0.10.8" +name = "shlex" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[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", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core", +] [[package]] -name = "signature" -version = "2.1.0" +name = "simd-adler32" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "single-value-repeat" @@ -3053,7 +3290,7 @@ dependencies = [ name = "single-value-repeat-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "single-value-repeat", ] @@ -3068,35 +3305,31 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.4.10" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] -name = "socket2" -version = "0.5.5" +name = "spin" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" -dependencies = [ - "libc", - "windows-sys", -] +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -3114,27 +3347,27 @@ 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" -version = "2.4.1" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -3142,74 +3375,92 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.38" +name = "sync_wrapper" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "futures-core", ] [[package]] name = "system-configuration" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ "core-foundation-sys", "libc", ] +[[package]] +name = "system-sc-interact" +version = "0.0.0" +dependencies = [ + "clap", + "multiversx-sc-snippets", + "serde", + "toml", +] + [[package]] name = "tempfile" -version = "3.8.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "termcolor" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] -name = "thread_local" -version = "1.1.7" +name = "thiserror" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ - "cfg-if", - "once_cell", + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -3232,38 +3483,37 @@ dependencies = [ name = "token-release-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "token-release", ] [[package]] name = "tokio" -version = "1.33.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] @@ -3276,27 +3526,37 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.6" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff9e3abce27ee2c9a37f9ad37238c1bdd4e789c84ba37df76aa4d528f5072cc" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ - "indexmap 2.1.0", + "indexmap", "serde", "serde_spanned", "toml_datetime", @@ -3305,31 +3565,52 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.20.7" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.1.0", + "indexmap", "serde", "serde_spanned", "toml_datetime", "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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -3364,15 +3645,15 @@ dependencies = [ name = "transfer-role-features-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "transfer-role-features", ] [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" @@ -3382,9 +3663,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -3403,15 +3684,27 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" [[package]] name = "url" -version = "2.4.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -3423,7 +3716,7 @@ name = "use-module" version = "0.0.0" dependencies = [ "multiversx-sc", - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "multiversx-sc-modules", "multiversx-sc-scenario", ] @@ -3432,15 +3725,24 @@ dependencies = [ name = "use-module-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "use-module", ] [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", +] [[package]] name = "vault" @@ -3454,7 +3756,7 @@ dependencies = [ name = "vault-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "vault", ] @@ -3477,21 +3779,21 @@ dependencies = [ name = "vec-repeat-meta" version = "0.0.0" dependencies = [ - "multiversx-sc-meta", + "multiversx-sc-meta-lib", "vec-repeat", ] [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "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", @@ -3514,34 +3816,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.38" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -3551,9 +3854,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3561,83 +3864,96 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasmparser" -version = "0.116.0" +version = "0.216.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53290b1276c5c2d47d694fb1a920538c01f51690e7e261acbe1d10c5fc306ea1" +checksum = "bcdee6bea3619d311fb4b299721e89a986c3470f804b6d534340e412589028e3" dependencies = [ - "indexmap 2.1.0", + "ahash", + "bitflags", + "hashbrown", + "indexmap", "semver", + "serde", ] [[package]] name = "wasmprinter" -version = "0.2.71" +version = "0.216.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f98260aa20f939518bcec1fac32c78898d5c68872e7363a4651f21f791b6c7e" +checksum = "8f82916f3892e53620639217d6ec78fe15c678352a3fbf3f3745b6417d0bd70f" dependencies = [ "anyhow", + "termcolor", "wasmparser", ] [[package]] name = "web-sys" -version = "0.3.65" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "winapi-util" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-sys 0.59.0", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-registry" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] [[package]] -name = "winapi-util" -version = "0.1.6" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "winapi", + "windows-targets 0.52.6", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] [[package]] name = "windows-sys" @@ -3645,7 +3961,25 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -3654,13 +3988,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -3669,36 +4019,78 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3706,58 +4098,74 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] -name = "winnow" -version = "0.5.19" +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" -dependencies = [ - "memchr", -] +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "winreg" -version = "0.50.0" +name = "winnow" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ - "cfg-if", - "windows-sys", + "memchr", ] [[package]] name = "zerocopy" -version = "0.7.25" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.25" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zip" -version = "0.6.6" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494" 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 51f5300809..5a1a1951c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ members = [ "framework/base", "framework/derive", "framework/meta", + "framework/meta-lib", "framework/scenario", "framework/snippets", "framework/wasm-adapter", @@ -17,6 +18,9 @@ members = [ "sdk/scenario-format", "tools/mxpy-snippet-generator", + "tools/payload-macro-generator", + # "tools/plotter", + "tools/interactor-system-func-calls/", "vm", @@ -126,6 +130,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 +166,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 +182,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/build-wasm.sh b/build-wasm.sh index 0b17cd2a14..5b8eb8653a 100755 --- a/build-wasm.sh +++ b/build-wasm.sh @@ -6,4 +6,4 @@ cargo install multiversx-sc-meta TARGET_DIR=$PWD/target -sc-meta all build --target-dir $TARGET_DIR --path ./contracts +sc-meta all build --target-dir-all $TARGET_DIR --path ./contracts diff --git a/contracts/benchmarks/large-storage/Cargo.toml b/contracts/benchmarks/large-storage/Cargo.toml index 09e805b4bb..e0f6f2a93e 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/benchmarks/large-storage/meta/Cargo.toml b/contracts/benchmarks/large-storage/meta/Cargo.toml index c955b07f98..fed2155292 100644 --- a/contracts/benchmarks/large-storage/meta/Cargo.toml +++ b/contracts/benchmarks/large-storage/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.large-storage] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/large_storage.scen.json b/contracts/benchmarks/large-storage/scenarios/large_storage.scen.json index 99f9d8fb17..fab53d3199 100644 --- a/contracts/benchmarks/large-storage/scenarios/large_storage.scen.json +++ b/contracts/benchmarks/large-storage/scenarios/large_storage.scen.json @@ -22,7 +22,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/large-storage.wasm", + "contractCode": "mxsc:../output/large-storage.mxsc.json", "arguments": [], "gasLimit": "2,000,000", "gasPrice": "0" 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 ffd59d2f00..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,9 +2,8 @@ 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( - "file:output/large-storage.wasm", + "mxsc:output/large-storage.mxsc.json", large_storage::ContractBuilder, ); blockchain diff --git a/contracts/benchmarks/large-storage/wasm/Cargo.lock b/contracts/benchmarks/large-storage/wasm/Cargo.lock index f24122c5e7..fc8782c35d 100755 --- a/contracts/benchmarks/large-storage/wasm/Cargo.lock +++ b/contracts/benchmarks/large-storage/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "large-storage" @@ -82,48 +55,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/large-storage/wasm/Cargo.toml b/contracts/benchmarks/large-storage/wasm/Cargo.toml index 5a9476bb96..260910e50c 100644 --- a/contracts/benchmarks/large-storage/wasm/Cargo.toml +++ b/contracts/benchmarks/large-storage/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "large-storage-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.large-storage] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 5782040aa7..fcaf9afbee 100644 --- a/contracts/benchmarks/large-storage/wasm/src/lib.rs +++ b/contracts/benchmarks/large-storage/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 e138fb7c33..706e33d0cd 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/linked-list-repeat/Cargo.toml b/contracts/benchmarks/mappers/linked-list-repeat/Cargo.toml index 8b4f698626..8b4de1b7fb 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 8df0ef9269..507b72ffb7 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/linked-list-repeat/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.linked-list-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/linked_list_repeat.scen.json b/contracts/benchmarks/mappers/linked-list-repeat/scenarios/linked_list_repeat.scen.json index 03b37a4152..7ab02c670f 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/scenarios/linked_list_repeat.scen.json +++ b/contracts/benchmarks/mappers/linked-list-repeat/scenarios/linked_list_repeat.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/linked-list-repeat.wasm", + "contractCode": "mxsc:../output/linked-list-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/benchmarks/mappers/linked-list-repeat/scenarios/linked_list_repeat_struct.scen.json b/contracts/benchmarks/mappers/linked-list-repeat/scenarios/linked_list_repeat_struct.scen.json index af6ef7739d..951fefb3da 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/scenarios/linked_list_repeat_struct.scen.json +++ b/contracts/benchmarks/mappers/linked-list-repeat/scenarios/linked_list_repeat_struct.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/linked-list-repeat.wasm", + "contractCode": "mxsc:../output/linked-list-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" 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 2d109c8f64..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 = "file:output/linked-list-repeat.wasm"; +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 d80a517089..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,10 +2,9 @@ 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( - "file:output/linked-list-repeat.wasm", + "mxsc:output/linked-list-repeat.mxsc.json", linked_list_repeat::ContractBuilder, ); blockchain diff --git a/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.lock index 7b92f93847..abf02603ec 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.lock @@ -2,29 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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" @@ -35,15 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -51,15 +33,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -68,9 +41,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "linked-list-repeat" @@ -90,48 +63,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 b2b4d83e44..8fa4ca056c 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/linked-list-repeat/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "linked-list-repeat-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.linked-list-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 30a4118efc..1e79aa533a 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 02b871b1c1..26810eab7e 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/map-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/map-repeat/meta/Cargo.toml index 2e25e13df3..e9cce7a386 100644 --- a/contracts/benchmarks/mappers/map-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/map-repeat/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.map-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/map_repeat.scen.json b/contracts/benchmarks/mappers/map-repeat/scenarios/map_repeat.scen.json index cba04d1e94..0e3ce0eb21 100644 --- a/contracts/benchmarks/mappers/map-repeat/scenarios/map_repeat.scen.json +++ b/contracts/benchmarks/mappers/map-repeat/scenarios/map_repeat.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/map-repeat.wasm", + "contractCode": "mxsc:../output/map-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/benchmarks/mappers/map-repeat/scenarios/map_repeat_struct.scen.json b/contracts/benchmarks/mappers/map-repeat/scenarios/map_repeat_struct.scen.json index c4913245f3..f150ba550f 100644 --- a/contracts/benchmarks/mappers/map-repeat/scenarios/map_repeat_struct.scen.json +++ b/contracts/benchmarks/mappers/map-repeat/scenarios/map_repeat_struct.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/map-repeat.wasm", + "contractCode": "mxsc:../output/map-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" 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 e53c9a9601..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,9 +2,11 @@ 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("file:output/map-repeat.wasm", map_repeat::ContractBuilder); + blockchain.register_contract( + "mxsc:output/map-repeat.mxsc.json", + map_repeat::ContractBuilder, + ); blockchain } diff --git a/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.lock index 81b86a4e74..ff925fd99a 100644 --- a/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.lock @@ -2,29 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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" @@ -35,15 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -51,15 +33,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -68,9 +41,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "map-repeat" @@ -90,48 +63,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.toml index 69d9ed56e1..96a15d31d6 100644 --- a/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/map-repeat/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "map-repeat-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.map-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 b846960d7a..3d670243ff 100644 --- a/contracts/benchmarks/mappers/map-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/map-repeat/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 b5ab2f42ec..eda2f55f14 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/queue-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/queue-repeat/meta/Cargo.toml index 6439f63a35..5ebcac768f 100644 --- a/contracts/benchmarks/mappers/queue-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/queue-repeat/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.queue-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/queue_repeat.scen.json b/contracts/benchmarks/mappers/queue-repeat/scenarios/queue_repeat.scen.json index dc7bcfe5f0..5cebd6bd2e 100644 --- a/contracts/benchmarks/mappers/queue-repeat/scenarios/queue_repeat.scen.json +++ b/contracts/benchmarks/mappers/queue-repeat/scenarios/queue_repeat.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/queue-repeat.wasm", + "contractCode": "mxsc:../output/queue-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/benchmarks/mappers/queue-repeat/scenarios/queue_repeat_struct.scen.json b/contracts/benchmarks/mappers/queue-repeat/scenarios/queue_repeat_struct.scen.json index cda441928a..73afa14697 100644 --- a/contracts/benchmarks/mappers/queue-repeat/scenarios/queue_repeat_struct.scen.json +++ b/contracts/benchmarks/mappers/queue-repeat/scenarios/queue_repeat_struct.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/queue-repeat.wasm", + "contractCode": "mxsc:../output/queue-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" 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 39140f455f..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,10 +2,9 @@ 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( - "file:output/queue-repeat.wasm", + "mxsc:output/queue-repeat.mxsc.json", queue_repeat::ContractBuilder, ); blockchain diff --git a/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.lock index 838cffdea0..ba14125dc1 100644 --- a/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.lock @@ -2,29 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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" @@ -35,15 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -51,15 +33,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -68,54 +41,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,24 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -171,9 +139,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.toml index 614762dbd7..1651184bb8 100644 --- a/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/queue-repeat/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "queue-repeat-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.queue-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 7d199710dd..887fb0c6e6 100644 --- a/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 c4a99045ba..03a56f0634 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/set-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/set-repeat/meta/Cargo.toml index f314b2e65f..8e2c40a509 100644 --- a/contracts/benchmarks/mappers/set-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/set-repeat/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.set-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/set_repeat.scen.json b/contracts/benchmarks/mappers/set-repeat/scenarios/set_repeat.scen.json index 5500bf9e08..37cf2a9360 100644 --- a/contracts/benchmarks/mappers/set-repeat/scenarios/set_repeat.scen.json +++ b/contracts/benchmarks/mappers/set-repeat/scenarios/set_repeat.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/set-repeat.wasm", + "contractCode": "mxsc:../output/set-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/benchmarks/mappers/set-repeat/scenarios/set_repeat_struct.scen.json b/contracts/benchmarks/mappers/set-repeat/scenarios/set_repeat_struct.scen.json index 20b733830c..22881ee764 100644 --- a/contracts/benchmarks/mappers/set-repeat/scenarios/set_repeat_struct.scen.json +++ b/contracts/benchmarks/mappers/set-repeat/scenarios/set_repeat_struct.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/set-repeat.wasm", + "contractCode": "mxsc:../output/set-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" 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 3f94fcc907..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,9 +2,11 @@ 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("file:output/set-repeat.wasm", set_repeat::ContractBuilder); + blockchain.register_contract( + "mxsc:output/set-repeat.mxsc.json", + set_repeat::ContractBuilder, + ); blockchain } diff --git a/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.lock index 21b202ad62..3356ac1202 100644 --- a/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.lock @@ -2,29 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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" @@ -35,15 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -51,15 +33,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -68,54 +41,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.toml index 0f7a09bf34..a40d131015 100644 --- a/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/set-repeat/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "set-repeat-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.set-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 cb8be1c156..7a1a61db74 100644 --- a/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 c70dd5534a..f073d8c96b 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 0b20dec152..0a8be35063 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/single-value-repeat/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.single-value-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/single_value_repeat.scen.json b/contracts/benchmarks/mappers/single-value-repeat/scenarios/single_value_repeat.scen.json index bdd75956f0..069bc32392 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/scenarios/single_value_repeat.scen.json +++ b/contracts/benchmarks/mappers/single-value-repeat/scenarios/single_value_repeat.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/single-value-repeat.wasm", + "contractCode": "mxsc:../output/single-value-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/benchmarks/mappers/single-value-repeat/scenarios/single_value_repeat_struct.scen.json b/contracts/benchmarks/mappers/single-value-repeat/scenarios/single_value_repeat_struct.scen.json index f0d22495be..27d471c0fa 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/scenarios/single_value_repeat_struct.scen.json +++ b/contracts/benchmarks/mappers/single-value-repeat/scenarios/single_value_repeat_struct.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/single-value-repeat.wasm", + "contractCode": "mxsc:../output/single-value-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" 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 4017aa5ad1..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,10 +2,9 @@ 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( - "file:output/single-value-repeat.wasm", + "mxsc:output/single-value-repeat.mxsc.json", single_value_repeat::ContractBuilder, ); blockchain diff --git a/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.lock index 1a29c069f0..63c5909ab3 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.lock @@ -2,29 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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" @@ -35,15 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -51,15 +33,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -68,54 +41,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 51e214bf55..95c20ff1da 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/single-value-repeat/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "single-value-repeat-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.single-value-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 c95dbbcb17..0c377e4821 100644 --- a/contracts/benchmarks/mappers/single-value-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/single-value-repeat/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 c4eab8f215..d6fe62204a 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/scenario" diff --git a/contracts/benchmarks/mappers/vec-repeat/meta/Cargo.toml b/contracts/benchmarks/mappers/vec-repeat/meta/Cargo.toml index 1f97d62445..f8a721f619 100644 --- a/contracts/benchmarks/mappers/vec-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/mappers/vec-repeat/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.vec-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/vec_repeat.scen.json b/contracts/benchmarks/mappers/vec-repeat/scenarios/vec_repeat.scen.json index 44c08c9e16..f432343eb2 100644 --- a/contracts/benchmarks/mappers/vec-repeat/scenarios/vec_repeat.scen.json +++ b/contracts/benchmarks/mappers/vec-repeat/scenarios/vec_repeat.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/vec-repeat.wasm", + "contractCode": "mxsc:../output/vec-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/benchmarks/mappers/vec-repeat/scenarios/vec_repeat_struct.scen.json b/contracts/benchmarks/mappers/vec-repeat/scenarios/vec_repeat_struct.scen.json index 8e3d54983d..64069d5470 100644 --- a/contracts/benchmarks/mappers/vec-repeat/scenarios/vec_repeat_struct.scen.json +++ b/contracts/benchmarks/mappers/vec-repeat/scenarios/vec_repeat_struct.scen.json @@ -24,7 +24,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/vec-repeat.wasm", + "contractCode": "mxsc:../output/vec-repeat.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" 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 9d638d905f..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,9 +2,11 @@ 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("file:output/vec-repeat.wasm", vec_repeat::ContractBuilder); + blockchain.register_contract( + "mxsc:output/vec-repeat.mxsc.json", + vec_repeat::ContractBuilder, + ); blockchain } diff --git a/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.lock b/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.lock index 171116c2c8..fe7e401f8e 100644 --- a/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.lock @@ -2,29 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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" @@ -35,15 +23,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -51,15 +33,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -68,54 +41,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -174,26 +142,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -206,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" @@ -221,29 +184,3 @@ dependencies = [ "multiversx-sc-wasm-adapter", "vec-repeat", ] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] diff --git a/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.toml b/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.toml index ec660aa75b..787966c724 100644 --- a/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/mappers/vec-repeat/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "vec-repeat-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.vec-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 1fe740202a..6f915470d8 100644 --- a/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 be39a720c1..e1847ec686 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/benchmarks/send-tx-repeat/meta/Cargo.toml b/contracts/benchmarks/send-tx-repeat/meta/Cargo.toml index d19c5334a7..f4449db7cf 100644 --- a/contracts/benchmarks/send-tx-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/send-tx-repeat/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.send-tx-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/send_tx_repeat.scen.json b/contracts/benchmarks/send-tx-repeat/scenarios/send_tx_repeat.scen.json index 4bbb0339ac..04b860522c 100644 --- a/contracts/benchmarks/send-tx-repeat/scenarios/send_tx_repeat.scen.json +++ b/contracts/benchmarks/send-tx-repeat/scenarios/send_tx_repeat.scen.json @@ -26,7 +26,7 @@ "id": "1", "tx": { "from": "address:owner", - "contractCode": "file:../output/send-tx-repeat.wasm", + "contractCode": "mxsc:../output/send-tx-repeat.mxsc.json", "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" @@ -82,7 +82,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/send-tx-repeat.wasm" + "code": "mxsc:../output/send-tx-repeat.mxsc.json" } } } 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/tests/scenario_rs_test.rs b/contracts/benchmarks/send-tx-repeat/tests/scenario_rs_test.rs index c5261ddf82..cccbea31c1 100644 --- a/contracts/benchmarks/send-tx-repeat/tests/scenario_rs_test.rs +++ b/contracts/benchmarks/send-tx-repeat/tests/scenario_rs_test.rs @@ -3,7 +3,7 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); blockchain.register_contract( - "file:output/send-tx-repeat.wasm", + "mxsc:output/send-tx-repeat.mxsc.json", send_tx_repeat::ContractBuilder, ); blockchain diff --git a/contracts/benchmarks/send-tx-repeat/wasm/Cargo.lock b/contracts/benchmarks/send-tx-repeat/wasm/Cargo.lock index 61ec3dd20e..570969d132 100755 --- a/contracts/benchmarks/send-tx-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/send-tx-repeat/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/send-tx-repeat/wasm/Cargo.toml b/contracts/benchmarks/send-tx-repeat/wasm/Cargo.toml index af2071217e..ab091ed470 100644 --- a/contracts/benchmarks/send-tx-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/send-tx-repeat/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "send-tx-repeat-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.send-tx-repeat] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 90b851fadd..acc9b4d8da 100644 --- a/contracts/benchmarks/send-tx-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/send-tx-repeat/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 f812530245..ce14422a61 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.44.0" +version = "0.53.0" path = "../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/benchmarks/str-repeat/meta/Cargo.toml b/contracts/benchmarks/str-repeat/meta/Cargo.toml index 5aa0dee7e5..57157e5a41 100644 --- a/contracts/benchmarks/str-repeat/meta/Cargo.toml +++ b/contracts/benchmarks/str-repeat/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.str-repeat] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/str_repeat.scen.json b/contracts/benchmarks/str-repeat/scenarios/str_repeat.scen.json index 017e524385..7393d950db 100644 --- a/contracts/benchmarks/str-repeat/scenarios/str_repeat.scen.json +++ b/contracts/benchmarks/str-repeat/scenarios/str_repeat.scen.json @@ -22,7 +22,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/str-repeat.wasm", + "contractCode": "mxsc:../output/str-repeat.mxsc.json", "arguments": [], "gasLimit": "2,000,000", "gasPrice": "0" 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 d8d8856bb6..4fcef41480 100644 --- a/contracts/benchmarks/str-repeat/tests/scenario_rs_test.rs +++ b/contracts/benchmarks/str-repeat/tests/scenario_rs_test.rs @@ -2,10 +2,31 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.register_contract("file:output/str-repeat.wasm", str_repeat::ContractBuilder); + blockchain.register_contract( + "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..1da0b6b0f2 --- /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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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.53.0" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.0" +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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +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..5a367d2a25 --- /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.53.0" +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..9cf26ff656 --- /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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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.53.0" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.0" +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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +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..9b036232c0 --- /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.53.0" +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 802041f9f2..f839148dc0 100755 --- a/contracts/benchmarks/str-repeat/wasm/Cargo.lock +++ b/contracts/benchmarks/str-repeat/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -167,9 +135,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "str-repeat" @@ -188,20 +156,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/benchmarks/str-repeat/wasm/Cargo.toml b/contracts/benchmarks/str-repeat/wasm/Cargo.toml index d24faec13c..eccba0bc08 100644 --- a/contracts/benchmarks/str-repeat/wasm/Cargo.toml +++ b/contracts/benchmarks/str-repeat/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "str-repeat-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ 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.44.0" +version = "0.53.0" 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 a1575e69aa..1d059d343c 100644 --- a/contracts/benchmarks/str-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/str-repeat/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 ff7ab26714..9f8f036ea8 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.44.0" +version = "0.53.0" authors = [ "Claudiu-Marcel Bruda ", "MultiversX ", @@ -19,16 +19,18 @@ edition = "2021" path = "src/lib.rs" [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" [dependencies] -arrayvec = { version = "0.7.1", default-features = false } +arrayvec = { version = "0.7", default-features = false } +rand = { version = "0.8.5" } +getrandom = { version = "0.2", features = ["js"] } diff --git a/contracts/core/price-aggregator/meta/Cargo.toml b/contracts/core/price-aggregator/meta/Cargo.toml index 78a5ab73fd..1185345685 100644 --- a/contracts/core/price-aggregator/meta/Cargo.toml +++ b/contracts/core/price-aggregator/meta/Cargo.toml @@ -8,9 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 new file mode 100644 index 0000000000..b7355d9bb0 --- /dev/null +++ b/contracts/core/price-aggregator/scenarios/stress_submit_test.scen.json @@ -0,0 +1,2426 @@ +{ + "steps": [ + { + "step": "setState", + "accounts": { + "address:owner": { + "nonce": "1" + } + }, + "newAddresses": [ + { + "creatorAddress": "address:owner", + "creatorNonce": "1", + "newAddress": "sc:price-aggregator" + } + ], + "currentBlockInfo": { + "blockTimestamp": "100" + } + }, + { + "step": "setState", + "accounts": { + "address:oracle1": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle2": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle3": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle4": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle5": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle6": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle7": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle8": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle9": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle10": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle11": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle12": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle13": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle14": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle15": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle16": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle17": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle18": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle19": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle20": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle21": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle22": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle23": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle24": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle25": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle26": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle27": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle28": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle29": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle30": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle31": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle32": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle33": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle34": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle35": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle36": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle37": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle38": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle39": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle40": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle41": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle42": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle43": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle44": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle45": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle46": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle47": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle48": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle49": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "setState", + "accounts": { + "address:oracle50": { + "nonce": "1", + "balance": "20" + } + } + }, + { + "step": "scDeploy", + "id": "", + "tx": { + "from": "address:owner", + "contractCode": "mxsc:../output/multiversx-price-aggregator-sc.mxsc.json", + "arguments": [ + "0x45474c44", + "0x14", + "0x0a", + "0x03", + "0x32", + "0x6f7261636c65315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6535305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f" + ], + "gasLimit": "120000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle1", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle2", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle3", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle4", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle5", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle6", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle7", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle8", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle9", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle10", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle11", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle12", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle13", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle14", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle15", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle16", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle17", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle18", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle19", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle20", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle21", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle22", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle23", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle24", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle25", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle26", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle27", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle28", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle29", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle30", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle31", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle32", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle33", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle34", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle35", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle36", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle37", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle38", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle39", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle40", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle41", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle42", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle43", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle44", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle45", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle46", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle47", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle48", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle49", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle50", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:owner", + "to": "sc:price-aggregator", + "function": "setPairDecimals", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x" + ], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:owner", + "to": "sc:price-aggregator", + "function": "unpause", + "arguments": [], + "gasLimit": "5000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle1", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x5f", + "0x39cc54ac5bccf253", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle2", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xad15c7e3640a9a45", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle3", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x48b730532690eb9d", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle4", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xb1580519ab86f89d", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle5", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xe84c8277b9268830", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle6", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x4186a02ea588d794", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle7", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xa02844057524284f", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle8", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x5649e4f1f063c7", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle9", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x989609eab19ae73e", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle10", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x8acdafb19db56c6a", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle11", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x0bcc000dbabcac9a", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle12", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x8a66d435d52a6d03", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle13", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x4bbb4cbf15005933", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle14", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x958966c4d4fdd3fc", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle15", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x79a8a90448a9425f", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle16", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x2ddf6189613bf0b3", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle17", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x91f975bb55acd96e", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle18", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xb8af8386d32407df", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle19", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x8208321468b7d110", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle20", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x301fb3f9d762dd21", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle21", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x03d586d728e16c5d", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle22", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x78b007f730262c92", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle23", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x3a6d82cd1852798e", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle24", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x9a55108257d7a256", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle25", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xf3155692bc66519e", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle26", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x6283af7b2e296346", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle27", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x99d40cc696258cf6", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle28", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x310d050fec04654e", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle29", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x34a0e15c72dcba46", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle30", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x24fa6ffe3a1279d0", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle31", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x7e78d934d8cbe914", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle32", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xcab5f81fa7ed76c5", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle33", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xa1c11f307f475407", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle34", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x3d31969d1151c04f", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle35", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x70e5ba8e10447c0f", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle36", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x5878482af735946f", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle37", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x774e57e5529d626e", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle38", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x7951f44d98cad889", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle39", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x20e57ce554e6a0c8", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle40", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x431ead02eae57c1e", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle41", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x319b554fd55857a4", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle42", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xc3ee962102e52707", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle43", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x23cdd9ee77b71dc4", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle44", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x9c12effd58d699f2", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle45", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xfa52a17507278e24", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle46", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x60910991c926dfed", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle47", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x159f8fabfe3eb103", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle48", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x68e16aea50a1bb9f", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle49", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xb32212a8fecba6a0", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + }, + { + "step": "scCall", + "id": "", + "tx": { + "from": "address:oracle50", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x51b503b1e0af13b6", + "0x" + ], + "gasLimit": "7000000" + }, + "expect": { + "out": [], + "status": "0" + } + } + ] +} diff --git a/contracts/core/price-aggregator/scenarios/stress_submit_with_gas_schedule_test.scen.json b/contracts/core/price-aggregator/scenarios/stress_submit_with_gas_schedule_test.scen.json new file mode 100644 index 0000000000..efb66e491a --- /dev/null +++ b/contracts/core/price-aggregator/scenarios/stress_submit_with_gas_schedule_test.scen.json @@ -0,0 +1,2179 @@ +{ + "name": "stress-submit-with-gas-schedule", + "traceGas": true, + "gasSchedule": "v4", + "steps": [ + { + "step": "setState", + "accounts": { + "address:oracle1": { + "nonce": "1", + "balance": "20" + }, + "address:oracle10": { + "nonce": "1", + "balance": "20" + }, + "address:oracle11": { + "nonce": "1", + "balance": "20" + }, + "address:oracle12": { + "nonce": "1", + "balance": "20" + }, + "address:oracle13": { + "nonce": "1", + "balance": "20" + }, + "address:oracle14": { + "nonce": "1", + "balance": "20" + }, + "address:oracle15": { + "nonce": "1", + "balance": "20" + }, + "address:oracle16": { + "nonce": "1", + "balance": "20" + }, + "address:oracle17": { + "nonce": "1", + "balance": "20" + }, + "address:oracle18": { + "nonce": "1", + "balance": "20" + }, + "address:oracle19": { + "nonce": "1", + "balance": "20" + }, + "address:oracle2": { + "nonce": "1", + "balance": "20" + }, + "address:oracle20": { + "nonce": "1", + "balance": "20" + }, + "address:oracle21": { + "nonce": "1", + "balance": "20" + }, + "address:oracle22": { + "nonce": "1", + "balance": "20" + }, + "address:oracle23": { + "nonce": "1", + "balance": "20" + }, + "address:oracle24": { + "nonce": "1", + "balance": "20" + }, + "address:oracle25": { + "nonce": "1", + "balance": "20" + }, + "address:oracle26": { + "nonce": "1", + "balance": "20" + }, + "address:oracle27": { + "nonce": "1", + "balance": "20" + }, + "address:oracle28": { + "nonce": "1", + "balance": "20" + }, + "address:oracle29": { + "nonce": "1", + "balance": "20" + }, + "address:oracle3": { + "nonce": "1", + "balance": "20" + }, + "address:oracle30": { + "nonce": "1", + "balance": "20" + }, + "address:oracle31": { + "nonce": "1", + "balance": "20" + }, + "address:oracle32": { + "nonce": "1", + "balance": "20" + }, + "address:oracle33": { + "nonce": "1", + "balance": "20" + }, + "address:oracle34": { + "nonce": "1", + "balance": "20" + }, + "address:oracle35": { + "nonce": "1", + "balance": "20" + }, + "address:oracle36": { + "nonce": "1", + "balance": "20" + }, + "address:oracle37": { + "nonce": "1", + "balance": "20" + }, + "address:oracle38": { + "nonce": "1", + "balance": "20" + }, + "address:oracle39": { + "nonce": "1", + "balance": "20" + }, + "address:oracle4": { + "nonce": "1", + "balance": "20" + }, + "address:oracle40": { + "nonce": "1", + "balance": "20" + }, + "address:oracle41": { + "nonce": "1", + "balance": "20" + }, + "address:oracle42": { + "nonce": "1", + "balance": "20" + }, + "address:oracle43": { + "nonce": "1", + "balance": "20" + }, + "address:oracle44": { + "nonce": "1", + "balance": "20" + }, + "address:oracle45": { + "nonce": "1", + "balance": "20" + }, + "address:oracle46": { + "nonce": "1", + "balance": "20" + }, + "address:oracle47": { + "nonce": "1", + "balance": "20" + }, + "address:oracle48": { + "nonce": "1", + "balance": "20" + }, + "address:oracle49": { + "nonce": "1", + "balance": "20" + }, + "address:oracle5": { + "nonce": "1", + "balance": "20" + }, + "address:oracle50": { + "nonce": "1", + "balance": "20" + }, + "address:oracle6": { + "nonce": "1", + "balance": "20" + }, + "address:oracle7": { + "nonce": "1", + "balance": "20" + }, + "address:oracle8": { + "nonce": "1", + "balance": "20" + }, + "address:oracle9": { + "nonce": "1", + "balance": "20" + }, + "address:owner": { + "nonce": "1" + } + }, + "newAddresses": [ + { + "creatorAddress": "address:owner", + "creatorNonce": "1", + "newAddress": "sc:price-aggregator" + } + ], + "currentBlockInfo": { + "blockTimestamp": "100" + } + }, + { + "step": "scDeploy", + "tx": { + "from": "address:owner", + "contractCode": "mxsc:../output/multiversx-price-aggregator-sc.mxsc.json", + "arguments": [ + "0x45474c44", + "0x14", + "0x0a", + "0x03", + "0x32", + "0x6f7261636c65315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c65395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6531395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6532395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6533395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534315f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534325f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534335f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534345f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534355f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534365f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534375f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534385f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6534395f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f", + "0x6f7261636c6535305f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f" + ], + "gasLimit": "120,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle1", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle2", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle3", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle4", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle5", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle6", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle7", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle8", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle9", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle10", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle11", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle12", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle13", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle14", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle15", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle16", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle17", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle18", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle19", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle20", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle21", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle22", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle23", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle24", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle25", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle26", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle27", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle28", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle29", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle30", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle31", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle32", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle33", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle34", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle35", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle36", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle37", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle38", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle39", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle40", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle41", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle42", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle43", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle44", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle45", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle46", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle47", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle48", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle49", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle50", + "to": "sc:price-aggregator", + "egldValue": "20", + "function": "stake", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:owner", + "to": "sc:price-aggregator", + "function": "setPairDecimals", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x" + ], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:owner", + "to": "sc:price-aggregator", + "function": "unpause", + "arguments": [], + "gasLimit": "5,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle1", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x5f", + "0x619911dbb570258c", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle2", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x3cf8d3d3a05bf655", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle3", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x4d92440172e0bf71", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle4", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xd971ed41066daa08", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle5", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x34a9348cb04afbd1", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle6", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x6c01a77d55c0861f", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle7", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xea1e93f2b82ec0f6", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle8", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x2f067fee00bbd5bc", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle9", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x1706fe5397a21f74", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle10", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xbffd5631e9e448a8", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle11", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x1940496d3bc8934c", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle12", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xbd0af0d3aba30235", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle13", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xebcf9494ec0fac0c", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle14", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x7aeb67c3eabe498c", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle15", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x5c758d17b8445f7f", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle16", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x6978fe48b9a58974", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle17", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x8692c26f665bc7ad", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle18", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x2d3a93b7522e72b6", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle19", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x4faa49415e935688", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle20", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x5cbca2cc253dbf54", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle21", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xdd20d194dd695735", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle22", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x32f039c1765a2ec3", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle23", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x84372c9de3d535d9", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle24", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x91b23ed59de93417", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle25", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x4b81d1a55887f5f9", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle26", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xd88e348ef6679e1d", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle27", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x2557834dc8059cc7", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle28", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x22d86f8317546033", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle29", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x5a775ddd32ca5367", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle30", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x59f049471cd2662c", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle31", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xb59fdc2aedbf845f", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle32", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xab13e96eb802f883", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle33", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xf6f152ab53ad7170", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle34", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x5bae78b87d516979", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle35", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xe47859cc0fdb0abe", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle36", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x7c36ab1fa1a348b4", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle37", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x7fda3ef39b74e04b", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle38", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x461d81a84db50115", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle39", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xcc0ab8ccc363dd0c", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle40", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x11c15058c7c6c1fa", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle41", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x293b700535555d4f", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle42", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x4e8d04d2f0e53efd", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle43", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x42be3651d7b9499e", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle44", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xb82a437fc87cd8a0", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle45", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xb12ebd0d9ff3f396", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle46", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x85b4d01e5a20d445", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle47", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x92edaca582002375", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle48", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x351151b47fee6331", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle49", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0x9155d2992ceb6beb", + "0x" + ], + "gasLimit": "7,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + }, + { + "step": "scCall", + "tx": { + "from": "address:oracle50", + "to": "sc:price-aggregator", + "function": "submit", + "arguments": [ + "0x45474c44", + "0x55534443", + "0x64", + "0xdbc0895ce5855dec", + "0x" + ], + "gasLimit": "50,000,000" + }, + "expect": { + "out": [], + "status": "0", + "refund": "*" + } + } + ] +} 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/lib.rs b/contracts/core/price-aggregator/src/lib.rs index 7aae1f2a1d..1dbed54848 100644 --- a/contracts/core/price-aggregator/src/lib.rs +++ b/contracts/core/price-aggregator/src/lib.rs @@ -5,16 +5,17 @@ multiversx_sc::imports!(); mod events; pub mod median; pub mod price_aggregator_data; -pub mod staking; +use multiversx_sc_modules::staking; use price_aggregator_data::{OracleStatus, PriceFeed, TimestampedPrice, TokenPair}; const SUBMISSION_LIST_MAX_LEN: usize = 50; +const SUBMISSION_LIST_MIN_LEN: usize = 3; const FIRST_SUBMISSION_TIMESTAMP_MAX_DIFF_SECONDS: u64 = 30; pub const MAX_ROUND_DURATION_SECONDS: u64 = 1_800; // 30 minutes -static PAUSED_ERROR_MSG: &[u8] = b"Contract is paused"; -static PAIR_DECIMALS_NOT_CONFIGURED_ERROR: &[u8] = b"pair decimals not configured"; -static WRONG_NUMBER_OF_DECIMALS_ERROR: &[u8] = b"wrong number of decimals"; +const PAUSED_ERROR_MSG: &[u8] = b"Contract is paused"; +const PAIR_DECIMALS_NOT_CONFIGURED_ERROR: &[u8] = b"pair decimals not configured"; +const WRONG_NUMBER_OF_DECIMALS_ERROR: &[u8] = b"wrong number of decimals"; #[multiversx_sc::contract] pub trait PriceAggregator: @@ -46,6 +47,39 @@ pub trait PriceAggregator: self.set_paused(true); } + #[only_owner] + #[endpoint(changeAmounts)] + fn change_amounts(&self, staking_amount: BigUint, slash_amount: BigUint) { + require!( + staking_amount > 0 && slash_amount > 0, + "Staking and slash amount cannot be 0" + ); + require!( + slash_amount <= staking_amount, + "Slash amount cannot be higher than required stake" + ); + + let user_whitelist = self.user_whitelist(); + let slash_quorum = self.slash_quorum().get(); + + let mut users_owning_new_amount = 0; + for user in user_whitelist.iter() { + if staking_amount < self.staked_amount(&user).get() { + users_owning_new_amount += 1; + } + if users_owning_new_amount > slash_quorum { + break; + } + } + + require!( + users_owning_new_amount > slash_quorum, + "New staking amount is too big compared to members staked amount" + ); + self.required_stake_amount().set(staking_amount); + self.slash_amount().set(slash_amount); + } + #[only_owner] #[endpoint(addOracles)] fn add_oracles(&self, oracles: MultiValueEncoded) { @@ -204,7 +238,7 @@ pub trait PriceAggregator: fn require_valid_submission_count(&self, submission_count: usize) { require!( - submission_count >= 1 + submission_count >= SUBMISSION_LIST_MIN_LEN && submission_count <= self.oracle_status().len() && submission_count <= SUBMISSION_LIST_MAX_LEN, "Invalid submission count" @@ -269,16 +303,16 @@ pub trait PriceAggregator: &self, from: ManagedBuffer, to: ManagedBuffer, - ) -> SCResult> { - require_old!(self.not_paused(), PAUSED_ERROR_MSG); + ) -> MultiValue6 { + require!(self.not_paused(), PAUSED_ERROR_MSG); let token_pair = TokenPair { from, to }; let round_values = self .rounds() .get(&token_pair) - .ok_or("token pair not found")?; + .unwrap_or_else(|| sc_panic!("token pair not found")); let feed = self.make_price_feed(token_pair, round_values); - Ok(( + ( feed.round_id, feed.from, feed.to, @@ -286,7 +320,7 @@ pub trait PriceAggregator: feed.price, feed.decimals, ) - .into()) + .into() } #[view(latestPriceFeedOptional)] @@ -295,7 +329,7 @@ pub trait PriceAggregator: from: ManagedBuffer, to: ManagedBuffer, ) -> OptionalValue> { - self.latest_price_feed(from, to).ok().into() + Some(self.latest_price_feed(from, to)).into() } #[only_owner] 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/src/staking.rs b/contracts/core/price-aggregator/src/staking.rs deleted file mode 100644 index 4ec2a25a00..0000000000 --- a/contracts/core/price-aggregator/src/staking.rs +++ /dev/null @@ -1,176 +0,0 @@ -// TODO: Replace with the one from multiversx_sc_modules on next release - -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); - -#[derive(TopEncode, TopDecode)] -pub struct TokenAmountPair { - pub token_id: EgldOrEsdtTokenIdentifier, - pub amount: BigUint, -} - -static NOT_ENOUGH_STAKE_ERR_MSG: &[u8] = b"Not enough stake"; - -#[multiversx_sc::module] -pub trait StakingModule { - fn init_staking_module( - &self, - staking_token: &EgldOrEsdtTokenIdentifier, - staking_amount: &BigUint, - slash_amount: &BigUint, - slash_quorum: usize, - user_whitelist: &ManagedVec, - ) { - let nr_board_members = user_whitelist.len(); - require!(nr_board_members > 0, "No board members"); - require!( - slash_quorum <= nr_board_members, - "Quorum higher than total possible board members" - ); - require!( - staking_amount > &0 && slash_amount > &0, - "Staking and slash amount cannot be 0" - ); - require!( - slash_amount <= staking_amount, - "Slash amount cannot be higher than required stake" - ); - - self.staking_token().set(staking_token); - self.required_stake_amount().set(staking_amount); - self.slash_amount().set(slash_amount); - self.slash_quorum().set(slash_quorum); - - for user in user_whitelist { - let _ = self.user_whitelist().insert(user); - } - } - - #[payable("*")] - #[endpoint] - fn stake(&self) { - let (payment_token, payment_amount) = self.call_value().egld_or_single_fungible_esdt(); - let staking_token = self.staking_token().get(); - require!(payment_token == staking_token, "Invalid payment token"); - - let caller = self.blockchain().get_caller(); - require!( - self.user_whitelist().contains(&caller), - "Only whitelisted members can stake" - ); - - self.staked_amount(&caller) - .update(|amt| *amt += payment_amount); - } - - #[endpoint] - fn unstake(&self, unstake_amount: BigUint) { - let caller = self.blockchain().get_caller(); - let staked_amount_mapper = self.staked_amount(&caller); - let staked_amount = staked_amount_mapper.get(); - require!(unstake_amount <= staked_amount, NOT_ENOUGH_STAKE_ERR_MSG); - - let leftover_amount = &staked_amount - &unstake_amount; - let required_stake_amount = self.required_stake_amount().get(); - if self.user_whitelist().contains(&caller) { - require!( - leftover_amount >= required_stake_amount, - NOT_ENOUGH_STAKE_ERR_MSG - ); - } - - staked_amount_mapper.set(&leftover_amount); - - let staking_token = self.staking_token().get(); - self.send() - .direct(&caller, &staking_token, 0, &unstake_amount); - } - - #[endpoint(voteSlashMember)] - fn vote_slash_member(&self, member_to_slash: ManagedAddress) { - require!( - self.is_staked_board_member(&member_to_slash), - "Voted user is not a staked board member" - ); - - let caller = self.blockchain().get_caller(); - require!( - self.is_staked_board_member(&caller), - NOT_ENOUGH_STAKE_ERR_MSG - ); - - let _ = self - .slashing_proposal_voters(&member_to_slash) - .insert(caller); - } - - #[endpoint(slashMember)] - fn slash_member(&self, member_to_slash: ManagedAddress) { - let quorum = self.slash_quorum().get(); - let mut slashing_voters_mapper = self.slashing_proposal_voters(&member_to_slash); - require!(slashing_voters_mapper.len() >= quorum, "Quorum not reached"); - - let slash_amount = self.slash_amount().get(); - self.staked_amount(&member_to_slash) - .update(|amt| *amt -= &slash_amount); - self.total_slashed_amount() - .update(|total| *total += slash_amount); - - slashing_voters_mapper.clear(); - } - - fn is_staked_board_member(&self, user: &ManagedAddress) -> bool { - let required_stake = self.required_stake_amount().get(); - let user_stake = self.staked_amount(user).get(); - - self.user_whitelist().contains(user) && user_stake >= required_stake - } - - #[inline] - fn add_board_member(&self, user: ManagedAddress) { - let _ = self.user_whitelist().insert(user); - } - - fn remove_board_member(&self, user: &ManagedAddress) { - let mut whitelist_mapper = self.user_whitelist(); - let was_whitelisted = whitelist_mapper.swap_remove(user); - if !was_whitelisted { - return; - } - - // remove user's votes as well - for board_member in whitelist_mapper.iter() { - let _ = self - .slashing_proposal_voters(&board_member) - .swap_remove(user); - } - self.slashing_proposal_voters(user).clear(); - } - - #[storage_mapper("staking_module:stakingToken")] - fn staking_token(&self) -> SingleValueMapper; - - #[storage_mapper("staking_module:requiredStakeAmount")] - fn required_stake_amount(&self) -> SingleValueMapper; - - #[storage_mapper("staking_module:userWhitelist")] - fn user_whitelist(&self) -> UnorderedSetMapper; - - #[storage_mapper("staking_module:stakedAmount")] - fn staked_amount(&self, user: &ManagedAddress) -> SingleValueMapper; - - #[storage_mapper("staking_module:slashingProposalVoters")] - fn slashing_proposal_voters( - &self, - slash_address: &ManagedAddress, - ) -> UnorderedSetMapper; - - #[storage_mapper("staking_module:slashQuorum")] - fn slash_quorum(&self) -> SingleValueMapper; - - #[storage_mapper("staking_module:slashAmount")] - fn slash_amount(&self) -> SingleValueMapper; - - #[storage_mapper("staking_module:totalSlashedAmount")] - fn total_slashed_amount(&self) -> SingleValueMapper; -} 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 bc1078bb06..a312b0ca1f 100644 --- a/contracts/core/price-aggregator/tests/price_aggregator_blackbox_test.rs +++ b/contracts/core/price-aggregator/tests/price_aggregator_blackbox_test.rs @@ -1,40 +1,31 @@ use multiversx_price_aggregator_sc::{ price_aggregator_data::{OracleStatus, TimestampedPrice, TokenPair}, - staking::ProxyTrait as _, - ContractObj, PriceAggregator, ProxyTrait as _, MAX_ROUND_DURATION_SECONDS, -}; -use multiversx_sc::{ - codec::multi_types::MultiValueVec, - types::{Address, EgldOrEsdtTokenIdentifier}, -}; -use multiversx_sc_modules::pause::ProxyTrait; -use multiversx_sc_scenario::{ - api::StaticApi, - managed_address, managed_biguint, managed_buffer, - scenario_model::{Account, AddressValue, ScCallStep, ScDeployStep, SetStateStep, TxExpect}, - ContractInfo, DebugApi, ScenarioWorld, WhiteboxContract, + 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 = "file:output/multiversx-price-aggregator-sc.wasm"; const SLASH_AMOUNT: u64 = 10; -const SLASH_QUORUM: usize = 2; +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, ); @@ -44,50 +35,31 @@ 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(); - 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, - multiversx_price_aggregator_sc::contract_obj, - ); - - Self { - world, - oracles, - price_aggregator_contract, - price_aggregator_whitebox, - } + Self { world, oracles } } 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() @@ -95,59 +67,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( @@ -157,27 +139,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(); } } @@ -207,9 +193,10 @@ fn test_price_aggregator_submit() { state.submit(&state.oracles[0].clone(), 95, 100); let current_timestamp = 100; - state - .world - .whitebox_query(&state.price_aggregator_whitebox, |sc| { + + state.world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { let token_pair = TokenPair { from: managed_buffer!(EGLD_TICKER), to: managed_buffer!(USD_TICKER), @@ -241,14 +228,15 @@ fn test_price_aggregator_submit() { accepted_submissions: 1 } ); - }); + }, + ); // first oracle submit again - submission not accepted state.submit(&state.oracles[0].clone(), 95, 100); - state - .world - .whitebox_query(&state.price_aggregator_whitebox, |sc| { + state.world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { assert_eq!( sc.oracle_status() .get(&managed_address!(&state.oracles[0].to_address())) @@ -258,7 +246,8 @@ fn test_price_aggregator_submit() { accepted_submissions: 1 } ); - }); + }, + ); } #[test] @@ -278,7 +267,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); @@ -286,12 +276,11 @@ fn test_price_aggregator_submit_round_ok() { // submit third state.submit(&state.oracles[2].clone(), 105, 12_000); - state - .world - .whitebox_query(&state.price_aggregator_whitebox, |sc| { - let result = sc - .latest_price_feed(managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER)) - .unwrap(); + state.world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { + let result = + sc.latest_price_feed(managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER)); let (round_id, from, to, timestamp, price, decimals) = result.into_tuple(); assert_eq!(round_id, 1); @@ -316,7 +305,8 @@ fn test_price_aggregator_submit_round_ok() { decimals } ); - }); + }, + ); } #[test] @@ -336,14 +326,15 @@ 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); - state - .world - .whitebox_query(&state.price_aggregator_whitebox, |sc| { + state.world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { let token_pair = TokenPair { from: managed_buffer!(EGLD_TICKER), to: managed_buffer!(USD_TICKER), @@ -356,7 +347,8 @@ fn test_price_aggregator_discarded_round() { .unwrap(), managed_biguint!(11_000) ); - }); + }, + ); } #[test] @@ -369,14 +361,16 @@ fn test_price_aggregator_slashing() { state.vote_slash_member(&state.oracles[0].clone(), state.oracles[1].to_address()); 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_scenario_go_test.rs b/contracts/core/price-aggregator/tests/price_aggregator_scenario_go_test.rs new file mode 100644 index 0000000000..87df4169f3 --- /dev/null +++ b/contracts/core/price-aggregator/tests/price_aggregator_scenario_go_test.rs @@ -0,0 +1,10 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} + +#[test] +fn price_aggregator_stress_submit_go() { + world().run("scenarios/stress_submit_with_gas_schedule_test.scen.json"); +} diff --git a/contracts/core/price-aggregator/tests/price_aggregator_stress_blackbox.rs b/contracts/core/price-aggregator/tests/price_aggregator_stress_blackbox.rs new file mode 100644 index 0000000000..be457448b5 --- /dev/null +++ b/contracts/core/price-aggregator/tests/price_aggregator_stress_blackbox.rs @@ -0,0 +1,212 @@ +use multiversx_price_aggregator_sc::{ + price_aggregator_data::{OracleStatus, TokenPair}, + PriceAggregator, +}; + +use multiversx_sc_scenario::imports::*; + +const DECIMALS: u8 = 0; +const EGLD_TICKER: &[u8] = b"EGLD"; +const NR_ORACLES: usize = 50; +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"; + +mod price_aggregator_proxy; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + PRICE_AGGREGATOR_PATH, + multiversx_price_aggregator_sc::ContractBuilder, + ); + + blockchain +} + +struct PriceAggregatorTestState { + world: ScenarioWorld, + oracles: Vec, +} + +impl PriceAggregatorTestState { + fn new() -> Self { + let mut world = world(); + world.start_trace(); + + 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!("oracle{}", i); + let address: TestAddress = TestAddress::new(address_expr.as_str()); + let address_value = AddressValue::from(address.eval_to_expr().as_str()); + + world.account(address).nonce(1).balance(STAKE_AMOUNT); + + oracles.push(address_value); + } + + Self { world, oracles } + } + + fn deploy(&mut self) -> &mut Self { + let oracles = MultiValueVec::from( + self.oracles + .iter() + .map(|oracle| oracle.to_address()) + .collect::>(), + ); + + 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 + .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 + .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 + .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 + .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(); + } +} + +#[test] +fn test_price_aggregator_submit() { + let mut state = PriceAggregatorTestState::new(); + state.deploy(); + + // configure the number of decimals + state.set_pair_decimals(); + + // unpause + state.unpause_endpoint(); + + // submit first + state.submit(&state.oracles[0].clone(), 95, rand::random::()); + + // submit ok + for index in 1..SUBMISSION_COUNT - 1 { + state.submit(&state.oracles[index].clone(), 100, rand::random::()); + } + + let current_timestamp = 100; + state.world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { + let blockchain_timestamp = sc.blockchain().get_block_timestamp(); + + let token_pair = TokenPair { + from: managed_buffer!(EGLD_TICKER), + to: managed_buffer!(USD_TICKER), + }; + assert_eq!(blockchain_timestamp, current_timestamp); + + let submission_count = sc.submission_count().get(); + + assert_eq!(submission_count, SUBMISSION_COUNT); + assert_eq!( + sc.first_submission_timestamp(&token_pair).get(), + current_timestamp + ); + assert_eq!( + sc.last_submission_timestamp(&token_pair).get(), + current_timestamp + ); + + let submissions = sc.submissions().get(&token_pair).unwrap(); + assert_eq!(submissions.len(), SUBMISSION_COUNT - 1); + + for index in 0..SUBMISSION_COUNT - 1 { + assert_eq!( + sc.oracle_status() + .get(&managed_address!(&state.oracles[index].to_address())) + .unwrap(), + OracleStatus { + total_submissions: 1, + accepted_submissions: 1 + } + ); + } + }, + ); + + // submit last that resets the round + state.submit( + &state.oracles[SUBMISSION_COUNT - 1].clone(), + 100, + rand::random::(), + ); + state + .world + .write_scenario_trace("scenarios/stress_submit_test.scen.json"); +} 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 a2ab56a22a..46ce6f52c3 100644 --- a/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs +++ b/contracts/core/price-aggregator/tests/price_aggregator_whitebox_test.rs @@ -1,31 +1,30 @@ use multiversx_price_aggregator_sc::{ price_aggregator_data::{OracleStatus, TimestampedPrice, TokenPair}, - staking::EndpointWrappers as StakingEndpointWrappers, PriceAggregator, MAX_ROUND_DURATION_SECONDS, }; -use multiversx_sc::types::{EgldOrEsdtTokenIdentifier, MultiValueEncoded}; -use multiversx_sc_modules::pause::EndpointWrappers as PauseEndpointWrappers; -use multiversx_sc_scenario::{ - managed_address, managed_biguint, managed_buffer, scenario_model::*, WhiteboxContract, *, +use multiversx_sc_modules::{ + pause::EndpointWrappers as PauseEndpointWrappers, + staking::{EndpointWrappers as StakingEndpointWrappers, StakingModule}, }; +use multiversx_sc_scenario::imports::*; pub const DECIMALS: u8 = 0; pub const EGLD_TICKER: &[u8] = b"EGLD"; pub const NR_ORACLES: usize = 4; pub const SLASH_AMOUNT: u64 = 10; -pub const SLASH_QUORUM: usize = 2; +pub const SLASH_QUORUM: usize = 3; pub const STAKE_AMOUNT: u64 = 20; pub const SUBMISSION_COUNT: usize = 3; pub const USD_TICKER: &[u8] = b"USDC"; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const PRICE_AGGREGATOR_ADDRESS_EXPR: &str = "sc:price-aggregator"; -const PRICE_AGGREGATOR_PATH_EXPR: &str = "file:output/multiversx-price-aggregator-sc.wasm"; +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const PRICE_AGGREGATOR_ADDRESS: TestSCAddress = TestSCAddress::new("price-aggregator"); +const PRICE_AGGREGATOR_PATH_EXPR: MxscPath = + MxscPath::new("mxsc: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, multiversx_price_aggregator_sc::ContractBuilder, @@ -37,31 +36,27 @@ fn world() -> ScenarioWorld { #[test] fn test_price_aggregator_submit() { let (mut world, oracles) = setup(); - let price_aggregator_whitebox = WhiteboxContract::new( - PRICE_AGGREGATOR_ADDRESS_EXPR, - multiversx_price_aggregator_sc::contract_obj, - ); // configure the number of decimals - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.set_pair_decimals( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), DECIMALS, ) - }, - ); + }); // try submit while paused - world.whitebox_call_check( - &price_aggregator_whitebox, - ScCallStep::new() - .from(&oracles[0]) - .expect(TxExpect::user_error("str:Contract is paused")), - |sc| { + world + .tx() + .from(&oracles[0]) + .to(PRICE_AGGREGATOR_ADDRESS) + .returns(ExpectError(4u64, "Contract is paused")) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -69,22 +64,24 @@ fn test_price_aggregator_submit() { managed_biguint!(100), DECIMALS, ) - }, - |r| r.assert_user_error("Contract is paused"), - ); + }); // unpause - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| sc.call_unpause_endpoint(), - ); + world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.call_unpause_endpoint(); + }); // submit first timestamp too old - world.whitebox_call_check( - &price_aggregator_whitebox, - ScCallStep::new().from(&oracles[0]).no_expect(), - |sc| { + world + .tx() + .from(&oracles[0]) + .to(PRICE_AGGREGATOR_ADDRESS) + .returns(ExpectError(4u64, "First submission too old")) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -92,17 +89,14 @@ fn test_price_aggregator_submit() { managed_biguint!(100), DECIMALS, ) - }, - |r| { - r.assert_user_error("First submission too old"); - }, - ); + }); // submit ok - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(&oracles[0]), - |sc| { + world + .tx() + .from(&oracles[0]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -110,49 +104,50 @@ fn test_price_aggregator_submit() { managed_biguint!(100), DECIMALS, ) - }, - ); + }); let current_timestamp = 100; - world.whitebox_query(&price_aggregator_whitebox, |sc| { - let token_pair = TokenPair { - from: managed_buffer!(EGLD_TICKER), - to: managed_buffer!(USD_TICKER), - }; - assert_eq!( - sc.first_submission_timestamp(&token_pair).get(), - current_timestamp - ); - assert_eq!( - sc.last_submission_timestamp(&token_pair).get(), - current_timestamp - ); - - let submissions = sc.submissions().get(&token_pair).unwrap(); - assert_eq!(submissions.len(), 1); - assert_eq!( - submissions - .get(&managed_address!(&oracles[0].to_address())) - .unwrap(), - managed_biguint!(100) - ); - - assert_eq!( - sc.oracle_status() - .get(&managed_address!(&oracles[0].to_address())) - .unwrap(), - OracleStatus { - total_submissions: 1, - accepted_submissions: 1 - } - ); - }); + world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { + let token_pair = TokenPair { + from: managed_buffer!(EGLD_TICKER), + to: managed_buffer!(USD_TICKER), + }; + assert_eq!( + sc.first_submission_timestamp(&token_pair).get(), + current_timestamp + ); + assert_eq!( + sc.last_submission_timestamp(&token_pair).get(), + current_timestamp + ); + + let submissions = sc.submissions().get(&token_pair).unwrap(); + assert_eq!(submissions.len(), 1); + assert_eq!( + submissions.get(&ManagedAddress::from(&oracles[0])).unwrap(), + managed_biguint!(100) + ); + + assert_eq!( + sc.oracle_status() + .get(&ManagedAddress::from(&oracles[0])) + .unwrap(), + OracleStatus { + total_submissions: 1, + accepted_submissions: 1 + } + ); + }, + ); // first oracle submit again - submission not accepted - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(&oracles[0]), - |sc| { + world + .tx() + .from(&oracles[0]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -160,55 +155,56 @@ fn test_price_aggregator_submit() { managed_biguint!(100), DECIMALS, ) + }); + + world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { + assert_eq!( + sc.oracle_status() + .get(&ManagedAddress::from(&oracles[0])) + .unwrap(), + OracleStatus { + total_submissions: 2, + accepted_submissions: 1 + } + ); }, ); - - world.whitebox_query(&price_aggregator_whitebox, |sc| { - assert_eq!( - sc.oracle_status() - .get(&managed_address!(&oracles[0].to_address())) - .unwrap(), - OracleStatus { - total_submissions: 2, - accepted_submissions: 1 - } - ); - }); } #[test] fn test_price_aggregator_submit_round_ok() { let (mut world, oracles) = setup(); - let price_aggregator_whitebox = WhiteboxContract::new( - PRICE_AGGREGATOR_ADDRESS_EXPR, - multiversx_price_aggregator_sc::contract_obj, - ); // configure the number of decimals - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.set_pair_decimals( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), DECIMALS, ) - }, - ); + }); // unpause - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| sc.call_unpause_endpoint(), - ); + world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.call_unpause_endpoint(); + }); // submit first - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(&oracles[0]), - |sc| { + world + .tx() + .from(&oracles[0]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -216,17 +212,17 @@ fn test_price_aggregator_submit_round_ok() { managed_biguint!(10_000), DECIMALS, ) - }, - ); + }); let current_timestamp = 110; - world.set_state_step(SetStateStep::new().block_timestamp(current_timestamp)); + world.current_block().block_timestamp(current_timestamp); // submit second - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(&oracles[1]), - |sc| { + world + .tx() + .from(&oracles[1]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -234,14 +230,14 @@ fn test_price_aggregator_submit_round_ok() { managed_biguint!(11_000), DECIMALS, ) - }, - ); + }); // submit third - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(&oracles[2]), - |sc| { + world + .tx() + .from(&oracles[2]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -249,73 +245,73 @@ fn test_price_aggregator_submit_round_ok() { managed_biguint!(12_000), DECIMALS, ) + }); + + world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { + let result = + sc.latest_price_feed(managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER)); + + let (round_id, from, to, timestamp, price, decimals) = result.into_tuple(); + assert_eq!(round_id, 1); + assert_eq!(from, managed_buffer!(EGLD_TICKER)); + assert_eq!(to, managed_buffer!(USD_TICKER)); + assert_eq!(timestamp, current_timestamp); + assert_eq!(price, managed_biguint!(11_000)); + assert_eq!(decimals, DECIMALS); + + // submissions are deleted after round is created + let token_pair = TokenPair { from, to }; + let submissions = sc.submissions().get(&token_pair).unwrap(); + assert_eq!(submissions.len(), 0); + + let rounds = sc.rounds().get(&token_pair).unwrap(); + assert_eq!(rounds.len(), 1); + assert_eq!( + rounds.get(1), + TimestampedPrice { + timestamp, + price, + decimals + } + ); }, ); - - world.whitebox_query(&price_aggregator_whitebox, |sc| { - let result = sc - .latest_price_feed(managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER)) - .unwrap(); - - let (round_id, from, to, timestamp, price, decimals) = result.into_tuple(); - assert_eq!(round_id, 1); - assert_eq!(from, managed_buffer!(EGLD_TICKER)); - assert_eq!(to, managed_buffer!(USD_TICKER)); - assert_eq!(timestamp, current_timestamp); - assert_eq!(price, managed_biguint!(11_000)); - assert_eq!(decimals, DECIMALS); - - // submissions are deleted after round is created - let token_pair = TokenPair { from, to }; - let submissions = sc.submissions().get(&token_pair).unwrap(); - assert_eq!(submissions.len(), 0); - - let rounds = sc.rounds().get(&token_pair).unwrap(); - assert_eq!(rounds.len(), 1); - assert_eq!( - rounds.get(1), - TimestampedPrice { - timestamp, - price, - decimals - } - ); - }); } #[test] fn test_price_aggregator_discarded_round() { let (mut world, oracles) = setup(); - let price_aggregator_whitebox = WhiteboxContract::new( - PRICE_AGGREGATOR_ADDRESS_EXPR, - multiversx_price_aggregator_sc::contract_obj, - ); // configure the number of decimals - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.set_pair_decimals( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), DECIMALS, ) - }, - ); + }); // unpause - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| sc.call_unpause_endpoint(), - ); + world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.call_unpause_endpoint(); + }); // submit first - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(&oracles[0]), - |sc| { + world + .tx() + .from(&oracles[0]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -323,17 +319,17 @@ fn test_price_aggregator_discarded_round() { managed_biguint!(10_000), DECIMALS, ) - }, - ); + }); let current_timestamp = 100 + MAX_ROUND_DURATION_SECONDS + 1; - world.set_state_step(SetStateStep::new().block_timestamp(current_timestamp)); + world.current_block().block_timestamp(current_timestamp); // submit second - this will discard the previous submission - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(&oracles[1]), - |sc| { + world + .tx() + .from(&oracles[1]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -341,69 +337,100 @@ fn test_price_aggregator_discarded_round() { managed_biguint!(11_000), DECIMALS, ) + }); + + world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { + let token_pair = TokenPair { + from: managed_buffer!(EGLD_TICKER), + to: managed_buffer!(USD_TICKER), + }; + let submissions = sc.submissions().get(&token_pair).unwrap(); + assert_eq!(submissions.len(), 1); + assert_eq!( + submissions.get(&managed_address!(&oracles[1])).unwrap(), + managed_biguint!(11_000) + ); }, ); - - world.whitebox_query(&price_aggregator_whitebox, |sc| { - let token_pair = TokenPair { - from: managed_buffer!(EGLD_TICKER), - to: managed_buffer!(USD_TICKER), - }; - let submissions = sc.submissions().get(&token_pair).unwrap(); - assert_eq!(submissions.len(), 1); - assert_eq!( - submissions - .get(&managed_address!(&oracles[1].to_address())) - .unwrap(), - managed_biguint!(11_000) - ); - }); } #[test] fn test_price_aggregator_slashing() { let (mut world, oracles) = setup(); - let price_aggregator_whitebox = WhiteboxContract::new( - PRICE_AGGREGATOR_ADDRESS_EXPR, - multiversx_price_aggregator_sc::contract_obj, - ); - // unpause - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| sc.call_unpause_endpoint(), - ); - - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new() - .from(&oracles[0]) - .argument(BytesValue::from(oracles[1].to_address().as_bytes())), - |sc| sc.call_vote_slash_member(), - ); + // configure the number of decimals + world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.set_pair_decimals( + managed_buffer!(EGLD_TICKER), + managed_buffer!(USD_TICKER), + DECIMALS, + ) + }); - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new() - .from(&oracles[2]) - .argument(BytesValue::from(oracles[1].to_address().as_bytes())), - |sc| sc.call_vote_slash_member(), + // unpause + world + .tx() + .from(OWNER_ADDRESS) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.call_unpause_endpoint(); + }); + + world + .tx() + .from(&oracles[0]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.vote_slash_member(ManagedAddress::from(&oracles[1])); + }); + + world + .tx() + .from(&oracles[2]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.vote_slash_member(ManagedAddress::from(&oracles[1])) + }); + + world + .tx() + .from(&oracles[3]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.vote_slash_member(ManagedAddress::from(&oracles[1])); + }); + + world.query().to(PRICE_AGGREGATOR_ADDRESS).whitebox( + multiversx_price_aggregator_sc::contract_obj, + |sc| { + let list = sc.slashing_proposal_voters(&ManagedAddress::from(&oracles[1])); + assert!(list.contains(&ManagedAddress::from(&oracles[0]))); + assert!(list.contains(&ManagedAddress::from(&oracles[2]))); + assert!(list.contains(&ManagedAddress::from(&oracles[3]))); + }, ); - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new() - .from(&oracles[0]) - .argument(BytesValue::from(oracles[1].to_address().as_bytes())), - |sc| sc.call_slash_member(), - ); + world + .tx() + .from(&oracles[0]) + .to(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.slash_member(ManagedAddress::from(&oracles[1])); + }); // oracle 1 try submit after slashing - world.whitebox_call_check( - &price_aggregator_whitebox, - ScCallStep::new().from(&oracles[1]).no_expect(), - |sc| { + world + .tx() + .from(&oracles[1]) + .to(PRICE_AGGREGATOR_ADDRESS) + .returns(ExpectError(4u64, "only oracles allowed")) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { sc.submit( managed_buffer!(EGLD_TICKER), managed_buffer!(USD_TICKER), @@ -411,49 +438,37 @@ fn test_price_aggregator_slashing() { managed_biguint!(10_000), DECIMALS, ) - }, - |r| { - r.assert_user_error("only oracles allowed"); - }, - ); + }); } -fn setup() -> (ScenarioWorld, Vec) { +fn setup() -> (ScenarioWorld, Vec
) { // setup let mut world = world(); - let price_aggregator_whitebox = WhiteboxContract::new( - PRICE_AGGREGATOR_ADDRESS_EXPR, - multiversx_price_aggregator_sc::contract_obj, - ); - let price_aggregator_code = world.code_expression(PRICE_AGGREGATOR_PATH_EXPR); - 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); let mut oracles = Vec::new(); for i in 1..=NR_ORACLES { - let oracle_address_expr = format!("address:oracle{i}"); - let oracle_address = AddressValue::from(oracle_address_expr.as_str()); - - set_state_step = set_state_step.put_account( - oracle_address_expr.as_str(), - Account::new().nonce(1).balance(STAKE_AMOUNT), - ); - oracles.push(oracle_address); + let oracle_address_expr = format!("oracle{i}"); + let oracle_address = TestAddress::new(&oracle_address_expr); + + world.account(oracle_address).nonce(1).balance(STAKE_AMOUNT); + + oracles.push(oracle_address.to_address()); } // init price aggregator - world.set_state_step(set_state_step).whitebox_deploy( - &price_aggregator_whitebox, - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(price_aggregator_code), - |sc| { + world + .tx() + .from(OWNER_ADDRESS) + .raw_deploy() + .code(PRICE_AGGREGATOR_PATH_EXPR) + .new_address(PRICE_AGGREGATOR_ADDRESS) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { let mut oracle_args = MultiValueEncoded::new(); for oracle_address in &oracles { - oracle_args.push(managed_address!(&oracle_address.to_address())); + oracle_args.push(ManagedAddress::from(oracle_address)); } sc.init( @@ -464,17 +479,17 @@ fn setup() -> (ScenarioWorld, Vec) { SUBMISSION_COUNT, oracle_args, ) - }, - ); + }); for oracle_address in &oracles { - world.whitebox_call( - &price_aggregator_whitebox, - ScCallStep::new() - .from(oracle_address) - .egld_value(STAKE_AMOUNT), - |sc| sc.call_stake(), - ); + world + .tx() + .from(oracle_address) + .to(PRICE_AGGREGATOR_ADDRESS) + .egld(STAKE_AMOUNT) + .whitebox(multiversx_price_aggregator_sc::contract_obj, |sc| { + sc.call_stake(); + }); } (world, oracles) diff --git a/contracts/core/price-aggregator/wasm/Cargo.lock b/contracts/core/price-aggregator/wasm/Cargo.lock index 88fcbd715b..745a1d281d 100644 --- a/contracts/core/price-aggregator/wasm/Cargo.lock +++ b/contracts/core/price-aggregator/wasm/Cargo.lock @@ -2,35 +2,35 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bumpalo" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cfg-if" @@ -45,12 +45,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] -name = "hashbrown" -version = "0.13.2" +name = "getrandom" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ - "ahash", + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", ] [[package]] @@ -61,17 +65,40 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "js-sys" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "multiversx-price-aggregator-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "arrayvec", + "getrandom", "multiversx-sc", "multiversx-sc-modules", + "rand", ] [[package]] @@ -84,55 +111,56 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -148,33 +176,42 @@ 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 = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,27 +227,46 @@ dependencies = [ ] [[package]] -name = "smallvec" -version = "1.11.1" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] [[package]] -name = "syn" -version = "1.0.109" +name = "rand_chacha" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", ] +[[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.38" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -224,27 +280,89 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "zerocopy" -version = "0.7.24" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.24" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] diff --git a/contracts/core/price-aggregator/wasm/Cargo.toml b/contracts/core/price-aggregator/wasm/Cargo.toml index 874009fd5e..902a185621 100644 --- a/contracts/core/price-aggregator/wasm/Cargo.toml +++ b/contracts/core/price-aggregator/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "multiversx-price-aggregator-sc-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.multiversx-price-aggregator-sc] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 9dbe38b27d..667c425afd 100644 --- a/contracts/core/price-aggregator/wasm/src/lib.rs +++ b/contracts/core/price-aggregator/wasm/src/lib.rs @@ -1,20 +1,16 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 19 +// Endpoints: 21 // Async Callback (empty): 1 -// Total number of exported functions: 21 +// Total number of exported functions: 23 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,6 +18,7 @@ multiversx_sc_wasm_adapter::endpoints! { multiversx_price_aggregator_sc ( init => init + changeAmounts => change_amounts addOracles => add_oracles removeOracles => remove_oracles submit => submit @@ -40,6 +37,7 @@ multiversx_sc_wasm_adapter::endpoints! { stake => stake unstake => unstake voteSlashMember => vote_slash_member + cancelVoteSlashMember => cancel_vote_slash_member slashMember => slash_member ) } diff --git a/contracts/core/wegld-swap/Cargo.toml b/contracts/core/wegld-swap/Cargo.toml index 2716104f6d..c7e75847e4 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.44.0" +version = "0.53.0" authors = [ "Dorin Iancu ", @@ -20,13 +20,13 @@ edition = "2021" path = "src/wegld.rs" [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/core/wegld-swap/meta/Cargo.toml b/contracts/core/wegld-swap/meta/Cargo.toml index b4eb51d6e3..705431fb06 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,9 +11,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/unwrap_egld.scen.json b/contracts/core/wegld-swap/scenarios/unwrap_egld.scen.json index 6adf64d201..70bc39b26d 100644 --- a/contracts/core/wegld-swap/scenarios/unwrap_egld.scen.json +++ b/contracts/core/wegld-swap/scenarios/unwrap_egld.scen.json @@ -62,7 +62,7 @@ "storage": { "str:wrappedEgldTokenId": "str:EGLD-abcdef" }, - "code": "file:../output/multiversx-wegld-swap-sc.wasm" + "code": "mxsc:../output/multiversx-wegld-swap-sc.mxsc.json" } } } diff --git a/contracts/core/wegld-swap/scenarios/wrap_egld.scen.json b/contracts/core/wegld-swap/scenarios/wrap_egld.scen.json index 2fca296af1..d9f3eddfc1 100644 --- a/contracts/core/wegld-swap/scenarios/wrap_egld.scen.json +++ b/contracts/core/wegld-swap/scenarios/wrap_egld.scen.json @@ -29,7 +29,7 @@ "storage": { "str:wrappedEgldTokenId": "str:EGLD-abcdef" }, - "code": "file:../output/multiversx-wegld-swap-sc.wasm" + "code": "mxsc:../output/multiversx-wegld-swap-sc.mxsc.json" } } }, @@ -86,7 +86,7 @@ "storage": { "str:wrappedEgldTokenId": "str:EGLD-abcdef" }, - "code": "file:../output/multiversx-wegld-swap-sc.wasm" + "code": "mxsc:../output/multiversx-wegld-swap-sc.mxsc.json" } } } 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 29b8456daf..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,10 +2,9 @@ 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( - "file:output/multiversx-wegld-swap-sc.wasm", + "mxsc:output/multiversx-wegld-swap-sc.mxsc.json", multiversx_wegld_swap_sc::ContractBuilder, ); blockchain diff --git a/contracts/core/wegld-swap/wasm/Cargo.toml b/contracts/core/wegld-swap/wasm/Cargo.toml index e376a9fe50..e03cd9feb2 100644 --- a/contracts/core/wegld-swap/wasm/Cargo.toml +++ b/contracts/core/wegld-swap/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "multiversx-wegld-swap-sc-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.multiversx-wegld-swap-sc] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 8da5946179..efb2e9bd60 100644 --- a/contracts/core/wegld-swap/wasm/src/lib.rs +++ b/contracts/core/wegld-swap/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 939efc2294..d2027938b2 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" -path = "../../../framework/scenario" +version = "0.53.0" +path = "../../../framework/scenario" \ No newline at end of file diff --git a/contracts/examples/adder/interact/.gitignore b/contracts/examples/adder/interact/.gitignore index ea1b920080..336fa10df0 100644 --- a/contracts/examples/adder/interact/.gitignore +++ b/contracts/examples/adder/interact/.gitignore @@ -1,5 +1,7 @@ # Pem files are used for interactions, but shouldn't be committed *.pem +*.json +!adder-owner.pem # Temporary storage of deployed contract address, so we can preserve the context between executions. state.toml diff --git a/contracts/examples/adder/interact/Cargo.toml b/contracts/examples/adder/interact/Cargo.toml index 8771785c3f..b9c18b391b 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.44.0" +version = "0.53.0" path = "../../../../framework/snippets" diff --git a/contracts/examples/adder/interact/adder-owner.pem b/contracts/examples/adder/interact/adder-owner.pem new file mode 100644 index 0000000000..66f04c2160 --- /dev/null +++ b/contracts/examples/adder/interact/adder-owner.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY for erd1s0a83vp2wmsvgphplkn8amkn8tnfd777zlut3e2lazgdzdu6z46qpgx3vz----- +MWIyYTQ3ZmIzMzcxODUxZTE3Njk5N2M0NTNmZDY1ODFkM2U5NjlhYmM1ODMzMTI0 +MjNkYzAyNGI3YzZlNmVlNjgzZmE3OGIwMmE3NmUwYzQwNmUxZmRhNjdlZWVkMzNh +ZTY5NmZiZGUxN2Y4YjhlNTVmZTg5MGQxMzc5YTE1NzQ= +-----END PRIVATE KEY for erd1s0a83vp2wmsvgphplkn8amkn8tnfd777zlut3e2lazgdzdu6z46qpgx3vz----- \ No newline at end of file diff --git a/contracts/examples/adder/interact/alice.json b/contracts/examples/adder/interact/alice.json new file mode 100644 index 0000000000..8f1a81514e --- /dev/null +++ b/contracts/examples/adder/interact/alice.json @@ -0,0 +1,23 @@ +{ + "version": 4, + "kind": "secretKey", + "id": "f2c5e236-9039-46cd-8df5-1efcd9466ead", + "address": "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1", + "bech32": "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + "crypto": { + "ciphertext": "45de5198c6c477725abc17d26c6b5fc88b1ff22a67a8c4784b297d426d351cf5c891a4c92d63e04cf23f602f660b7b606ed1c5293c85ff40216d9e53c9a07c23", + "cipherparams": { + "iv": "d6442fb1d4c49106152baeb3c539ed2c" + }, + "cipher": "aes-128-ctr", + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "salt": "dd69d88742b9d27a0438a4554d4180b070d9af224ea8ff8225fdf74c8e272adb", + "n": 4096, + "r": 8, + "p": 1 + }, + "mac": "b277984f71d0e9b4a6597911775c0ee6d598002645b29f22021e595c2725d204" + } +} 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 3102752c22..0000000000 --- a/contracts/examples/adder/interact/src/adder_interact.rs +++ /dev/null @@ -1,199 +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("file:../output/adder.wasm", &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..454060eb0d --- /dev/null +++ b/contracts/examples/adder/interact/src/basic_interact.rs @@ -0,0 +1,298 @@ +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"; + +const ADDER_CODE_PATH: MxscPath = MxscPath::new("../output/adder.mxsc.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)) => { + if args.count == 1 { + basic_interact.add(args.value).await; + } else { + basic_interact.multi_add(args.value, args.count).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; + }, + Some(basic_interact_cli::InteractCliCommand::Upgrade(args)) => { + let owner_address = basic_interact.adder_owner_address.clone(); + basic_interact + .upgrade(args.value, &owner_address, None) + .await + }, + None => {}, + } +} + +#[allow(unused)] +struct AdderInteract { + interactor: Interactor, + adder_owner_address: Bech32Address, + wallet_address: Bech32Address, + 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 adder_owner_address = + interactor.register_wallet(Wallet::from_pem_file("adder-owner.pem").unwrap()); + // PASSWORD: "alice" + // InsertPassword::Plaintext("alice".to_string()) || InsertPassword::StandardInput + let wallet_address = interactor.register_wallet( + Wallet::from_keystore_secret( + "alice.json", + InsertPassword::Plaintext("alice".to_string()), + ) + .unwrap(), + ); + + Self { + interactor, + adder_owner_address: adder_owner_address.into(), + wallet_address: wallet_address.into(), + state: State::load_state(), + } + } + + async fn set_state(&mut self) { + println!("wallet address: {}", self.wallet_address); + self.interactor + .retrieve_account(&self.adder_owner_address) + .await; + 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.adder_owner_address) + .gas(6_000_000) + .typed(adder_proxy::AdderProxy) + .init(0u32) + .code(ADDER_CODE_PATH) + .code_metadata(CodeMetadata::UPGRADEABLE) + .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: usize) { + 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(ADDER_CODE_PATH) + .gas(6_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 multi_add(&mut self, value: u32, count: usize) { + self.set_state().await; + println!("calling contract {count} times..."); + + let mut buffer = self.interactor.homogenous_call_buffer(); + for _ in 0..count { + buffer.push_tx(|tx| { + tx.from(&self.wallet_address) + .to(self.state.current_adder_address()) + .typed(adder_proxy::AdderProxy) + .add(value) + .gas(6_000_000) + }); + } + + let _ = buffer.run().await; + + println!("successfully performed add {count} times"); + } + + 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: u32) { + self.interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_adder_address()) + .gas(6_000_000) + .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}"); + } + + async fn upgrade( + &mut self, + new_value: u32, + sender: &Bech32Address, + expected_result: Option<(u64, &str)>, + ) { + match expected_result { + Some((code, msg)) => { + let response = self + .interactor + .tx() + .from(sender) + .to(self.state.current_adder_address()) + .gas(6_000_000) + .typed(adder_proxy::AdderProxy) + .upgrade(new_value) + .code_metadata(CodeMetadata::UPGRADEABLE) + .code(ADDER_CODE_PATH) + .returns(ExpectError(code, msg)) + .prepare_async() + .run() + .await; + + println!("response: {response:?}"); + }, + None => { + self.interactor + .tx() + .from(sender) + .to(self.state.current_adder_address()) + .gas(6_000_000) + .typed(adder_proxy::AdderProxy) + .upgrade(new_value) + .code_metadata(CodeMetadata::UPGRADEABLE) + .code(ADDER_CODE_PATH) + .prepare_async() + .run() + .await; + + let sum = self + .interactor + .query() + .to(self.state.current_adder_address()) + .typed(adder_proxy::AdderProxy) + .sum() + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + assert_eq!(sum, RustBigUint::from(new_value)); + }, + } + } +} + +#[tokio::test] +#[ignore = "run on demand"] +async fn upgrade_test() { + let mut basic_interact = AdderInteract::init().await; + let wallet_address = basic_interact.wallet_address.clone(); + let adder_owner_address = basic_interact.adder_owner_address.clone(); + let error_not_owner = (4, "upgrade is allowed only for owner"); + + basic_interact.deploy().await; + basic_interact.add(1u32).await; + + // Sum will be 1 + basic_interact.print_sum().await; + + basic_interact + .upgrade(7u32, &adder_owner_address, None) + .await; + + // Sum will be the updated value of 7 + basic_interact.print_sum().await; + + basic_interact + .upgrade(10u32, &wallet_address, Some(error_not_owner)) + .await; + + // Sum will remain 7 + basic_interact.print_sum().await; +} diff --git a/contracts/examples/adder/interact/src/adder_interact_cli.rs b/contracts/examples/adder/interact/src/basic_interact_cli.rs similarity index 66% rename from contracts/examples/adder/interact/src/adder_interact_cli.rs rename to contracts/examples/adder/interact/src/basic_interact_cli.rs index 8818c1bb60..6766981802 100644 --- a/contracts/examples/adder/interact/src/adder_interact_cli.rs +++ b/contracts/examples/adder/interact/src/basic_interact_cli.rs @@ -22,18 +22,31 @@ pub enum InteractCliCommand { MultiDeploy(MultiDeployArgs), #[command(name = "sum", about = "Print sum")] Sum, + #[command(name = "upgrade", about = "Upgrade contract")] + Upgrade(UpgradeArgs), } #[derive(Default, Clone, PartialEq, Eq, Debug, Args)] pub struct AddArgs { /// The value to add - #[arg(short = 'v', long = "value", verbatim_doc_comment)] - pub value: u64, + #[arg(short = 'v', long = "value")] + pub value: u32, + + /// Repeat this number of times + #[arg(short = 'c', long = "count", default_value = "1")] + pub count: usize, +} + +#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] +pub struct UpgradeArgs { + /// The value to add + #[arg(short = 'v', long = "value")] + pub value: u32, } #[derive(Default, Clone, PartialEq, Eq, Debug, Args)] pub struct MultiDeployArgs { /// The number of contracts to deploy - #[arg(short = 'c', long = "count", verbatim_doc_comment)] - pub count: u8, + #[arg(short = 'c', long = "count")] + pub count: usize, } 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 13056eb08d..7113e2566f 100644 --- a/contracts/examples/adder/meta/Cargo.toml +++ b/contracts/examples/adder/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.adder] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 538afb1137..490557cc50 100644 --- a/contracts/examples/adder/mxsc-template.toml +++ b/contracts/examples/adder/mxsc-template.toml @@ -12,8 +12,13 @@ files_include = [ "scenarios", "src", "tests", - "wasm/Cargo.toml", "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/scenarios/adder.scen.json b/contracts/examples/adder/scenarios/adder.scen.json index cccfbaf22b..08ecb79e3f 100644 --- a/contracts/examples/adder/scenarios/adder.scen.json +++ b/contracts/examples/adder/scenarios/adder.scen.json @@ -24,7 +24,7 @@ "id": "1", "tx": { "from": "address:owner", - "contractCode": "file:../output/adder.wasm", + "contractCode": "mxsc:../output/adder.mxsc.json", "arguments": [ "5" ], @@ -91,7 +91,7 @@ "storage": { "str:sum": "8" }, - "code": "file:../output/adder.wasm" + "code": "mxsc:../output/adder.mxsc.json" } } } diff --git a/contracts/examples/adder/scenarios/interactor_trace.scen.json b/contracts/examples/adder/scenarios/interactor_trace.scen.json index bb20201bac..e0824697fe 100644 --- a/contracts/examples/adder/scenarios/interactor_trace.scen.json +++ b/contracts/examples/adder/scenarios/interactor_trace.scen.json @@ -11,8 +11,7 @@ "str:CAN-2abf4b": "1000", "str:CAN-6d39e6": "1000", "str:CAN-ac1592": "1000" - }, - "username": "" + } } } }, @@ -28,23 +27,21 @@ }, { "step": "scDeploy", - "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", - "contractCode": "file:../output/adder.wasm", + "contractCode": "mxsc:../output/adder.mxsc.json", "arguments": [ "0x00" ], - "gasLimit": "70,000,000", - "gasPrice": "" + "gasLimit": "70,000,000" }, "expect": { + "out": [], "status": "0" } }, { "step": "scCall", - "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", "to": "0x0000000000000000050028600ceb73ac22ec0b6f257aff7bed74dffa3ebfed60", @@ -52,16 +49,15 @@ "arguments": [ "0x07" ], - "gasLimit": "70,000,000", - "gasPrice": "" + "gasLimit": "70,000,000" }, "expect": { + "out": [], "status": "0" } }, { "step": "scCall", - "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", "to": "0x0000000000000000050028600ceb73ac22ec0b6f257aff7bed74dffa3ebfed60", @@ -69,12 +65,12 @@ "arguments": [ "0x05" ], - "gasLimit": "70,000,000", - "gasPrice": "" + "gasLimit": "70,000,000" }, "expect": { + "out": [], "status": "0" } } ] -} \ No newline at end of file +} diff --git a/contracts/examples/adder/src/adder.rs b/contracts/examples/adder/src/adder.rs index f7c47ab01a..307f4112f5 100644 --- a/contracts/examples/adder/src/adder.rs +++ b/contracts/examples/adder/src/adder.rs @@ -1,6 +1,8 @@ #![no_std] -multiversx_sc::imports!(); +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. @@ -15,6 +17,11 @@ pub trait Adder { 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) { 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 3d2e166582..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 = "file:output/adder.wasm"; +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 62173c5cce..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 = "file:output/adder.wasm"; - -fn world() -> ScenarioWorld { - let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/adder"); - - blockchain.register_contract("file:output/adder.wasm", 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 a92de289ff..f9ee7a3a1c 100644 --- a/contracts/examples/adder/tests/adder_scenario_rs_test.rs +++ b/contracts/examples/adder/tests/adder_scenario_rs_test.rs @@ -2,9 +2,8 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/adder"); - blockchain.register_contract("file:output/adder.wasm", adder::ContractBuilder); + 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 97916d4ec4..c609b08302 100644 --- a/contracts/examples/adder/tests/adder_whitebox_test.rs +++ b/contracts/examples/adder/tests/adder_whitebox_test.rs @@ -1,50 +1,50 @@ use adder::*; -use multiversx_sc_scenario::{scenario_model::*, *}; +use multiversx_sc_scenario::imports::*; -const ADDER_PATH_EXPR: &str = "file:output/adder.wasm"; +const OWNER: TestAddress = TestAddress::new("owner"); +const ADDER_ADDRESS: TestSCAddress = TestSCAddress::new("adder"); +const CODE_PATH: MxscPath = MxscPath::new("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("file:output/adder.wasm", adder::ContractBuilder); + blockchain.register_contract(CODE_PATH, adder::ContractBuilder); blockchain } #[test] fn adder_whitebox() { let mut world = world(); - let adder_whitebox = WhiteboxContract::new("sc:adder", adder::contract_obj); - let adder_code = world.code_expression(ADDER_PATH_EXPR); + + world.account(OWNER).nonce(1); + + let new_address = world + .tx() + .from(OWNER) + .raw_deploy() + .code(CODE_PATH) + .new_address(ADDER_ADDRESS) + .returns(ReturnsNewBech32Address) + .whitebox(adder::contract_obj, |sc| { + sc.init(BigUint::from(3u64)); + }); + + assert_eq!(new_address, ADDER_ADDRESS.to_address().into()); world - .set_state_step( - SetStateStep::new() - .put_account("address:owner", Account::new().nonce(1)) - .new_address("address:owner", 1, "sc:adder"), - ) - .whitebox_deploy( - &adder_whitebox, - ScDeployStep::new().from("address:owner").code(adder_code), - |sc| { - sc.init(5u32.into()); - }, - ) - .whitebox_query(&adder_whitebox, |sc| { - let sum_value = sc.sum(); - assert_eq!(sum_value.get(), 5u32); - }) - .whitebox_call( - &adder_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"), - ), - ); + .tx() + .from(OWNER) + .to(ADDER_ADDRESS) + .whitebox(adder::contract_obj, |sc| { + sc.add(BigUint::from(5u64)); + }); + + let _raw_response = world + .query() + .to(ADDER_ADDRESS) + .returns(ReturnsRawResult) + .whitebox(adder::contract_obj, |sc| { + let sum = sc.sum().get(); + assert_eq!(sum, BigUint::from(8u64)); + }); } diff --git a/contracts/examples/adder/wasm/Cargo.lock b/contracts/examples/adder/wasm/Cargo.lock index ce7beeabe9..a83e0f4f08 100755 --- a/contracts/examples/adder/wasm/Cargo.lock +++ b/contracts/examples/adder/wasm/Cargo.lock @@ -17,47 +17,23 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -65,16 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" -dependencies = [ - "ahash", - "allocator-api2", -] - [[package]] name = "hex" version = "0.4.3" @@ -89,48 +55,49 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -146,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -189,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" - -[[package]] -name = "syn" -version = "1.0.109" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.38" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -222,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/adder/wasm/Cargo.toml b/contracts/examples/adder/wasm/Cargo.toml index 3a78d11702..9eb819a0e9 100644 --- a/contracts/examples/adder/wasm/Cargo.toml +++ b/contracts/examples/adder/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "adder-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.adder] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/adder/wasm/src/lib.rs b/contracts/examples/adder/wasm/src/lib.rs index 9fef05476a..19ea33c7e1 100644 --- a/contracts/examples/adder/wasm/src/lib.rs +++ b/contracts/examples/adder/wasm/src/lib.rs @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// 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: 4 +// Total number of exported functions: 5 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { adder ( init => init + 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 06ef5e4d57..02c5fa9459 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/bonding-curve-contract/meta/Cargo.toml b/contracts/examples/bonding-curve-contract/meta/Cargo.toml index a30043d140..c8763270ce 100644 --- a/contracts/examples/bonding-curve-contract/meta/Cargo.toml +++ b/contracts/examples/bonding-curve-contract/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.bonding-curve-contract] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/buy.scen.json b/contracts/examples/bonding-curve-contract/scenarios/buy.scen.json index bfc8467305..10a48ef194 100644 --- a/contracts/examples/bonding-curve-contract/scenarios/buy.scen.json +++ b/contracts/examples/bonding-curve-contract/scenarios/buy.scen.json @@ -266,7 +266,7 @@ "str:owned_tokens|address:artist2|str:.node_id|nested:str:MFSFT-246802": "1", "str:owned_tokens|address:artist2|str:.value|u32:1": "str:MFSFT-246802" }, - "code": "file:../output/bonding-curve-contract.wasm" + "code": "mxsc:../output/bonding-curve-contract.mxsc.json" } } } diff --git a/contracts/examples/bonding-curve-contract/scenarios/claim.scen.json b/contracts/examples/bonding-curve-contract/scenarios/claim.scen.json index 64a3c21721..7fa50cf4ab 100644 --- a/contracts/examples/bonding-curve-contract/scenarios/claim.scen.json +++ b/contracts/examples/bonding-curve-contract/scenarios/claim.scen.json @@ -173,7 +173,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/bonding-curve-contract.wasm" + "code": "mxsc:../output/bonding-curve-contract.mxsc.json" } } } diff --git a/contracts/examples/bonding-curve-contract/scenarios/deploy.scen.json b/contracts/examples/bonding-curve-contract/scenarios/deploy.scen.json index ec9af18cc5..a8e651128a 100644 --- a/contracts/examples/bonding-curve-contract/scenarios/deploy.scen.json +++ b/contracts/examples/bonding-curve-contract/scenarios/deploy.scen.json @@ -106,7 +106,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/bonding-curve-contract.wasm", + "contractCode": "mxsc:../output/bonding-curve-contract.mxsc.json", "arguments": [], "gasLimit": "15,000,000", "gasPrice": "0" @@ -212,7 +212,7 @@ "sc:bonding-curve-contract": { "nonce": "0", "balance": "0", - "code": "file:../output/bonding-curve-contract.wasm" + "code": "mxsc:../output/bonding-curve-contract.mxsc.json" } } } diff --git a/contracts/examples/bonding-curve-contract/scenarios/deposit.scen.json b/contracts/examples/bonding-curve-contract/scenarios/deposit.scen.json index 3d9affc8f6..15fb02032f 100644 --- a/contracts/examples/bonding-curve-contract/scenarios/deposit.scen.json +++ b/contracts/examples/bonding-curve-contract/scenarios/deposit.scen.json @@ -437,7 +437,7 @@ "str:owned_tokens|address:artist2|str:.node_id|nested:str:MFSFT-246802": "1", "str:owned_tokens|address:artist2|str:.value|u32:1": "str:MFSFT-246802" }, - "code": "file:../output/bonding-curve-contract.wasm" + "code": "mxsc:../output/bonding-curve-contract.mxsc.json" } } } diff --git a/contracts/examples/bonding-curve-contract/scenarios/deposit_more_view.scen.json b/contracts/examples/bonding-curve-contract/scenarios/deposit_more_view.scen.json index 1fe5b3028a..f63833ccd5 100644 --- a/contracts/examples/bonding-curve-contract/scenarios/deposit_more_view.scen.json +++ b/contracts/examples/bonding-curve-contract/scenarios/deposit_more_view.scen.json @@ -187,7 +187,7 @@ "str:owned_tokens|address:artist2|str:.node_id|nested:str:MFSFT-246802": "1", "str:owned_tokens|address:artist2|str:.value|u32:1": "str:MFSFT-246802" }, - "code": "file:../output/bonding-curve-contract.wasm" + "code": "mxsc:../output/bonding-curve-contract.mxsc.json" } } }, diff --git a/contracts/examples/bonding-curve-contract/scenarios/sell.scen.json b/contracts/examples/bonding-curve-contract/scenarios/sell.scen.json index 0e845a950e..5d46d9fdef 100644 --- a/contracts/examples/bonding-curve-contract/scenarios/sell.scen.json +++ b/contracts/examples/bonding-curve-contract/scenarios/sell.scen.json @@ -210,7 +210,7 @@ "str:owned_tokens|address:artist2|str:.node_id|nested:str:MFSFT-246802": "1", "str:owned_tokens|address:artist2|str:.value|u32:1": "str:MFSFT-246802" }, - "code": "file:../output/bonding-curve-contract.wasm" + "code": "mxsc:../output/bonding-curve-contract.mxsc.json" } } } diff --git a/contracts/examples/bonding-curve-contract/scenarios/set_bonding_curve.scen.json b/contracts/examples/bonding-curve-contract/scenarios/set_bonding_curve.scen.json index bc3f43f8c7..72606bab3e 100644 --- a/contracts/examples/bonding-curve-contract/scenarios/set_bonding_curve.scen.json +++ b/contracts/examples/bonding-curve-contract/scenarios/set_bonding_curve.scen.json @@ -236,7 +236,7 @@ "str:owned_tokens|address:artist2|str:.node_id|nested:str:MFSFT-246802": "1", "str:owned_tokens|address:artist2|str:.value|u32:1": "str:MFSFT-246802" }, - "code": "file:../output/bonding-curve-contract.wasm" + "code": "mxsc:../output/bonding-curve-contract.mxsc.json" } } } diff --git a/contracts/examples/bonding-curve-contract/src/bonding_curve_contract.rs b/contracts/examples/bonding-curve-contract/src/bonding_curve_contract.rs index 2b9acedf7c..6ab29068d3 100644 --- a/contracts/examples/bonding-curve-contract/src/bonding_curve_contract.rs +++ b/contracts/examples/bonding-curve-contract/src/bonding_curve_contract.rs @@ -1,7 +1,6 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; use function_selector::FunctionSelector; use multiversx_sc_modules::{ diff --git a/contracts/examples/bonding-curve-contract/src/function_selector.rs b/contracts/examples/bonding-curve-contract/src/function_selector.rs index 94a8831e5a..218a490c9c 100644 --- a/contracts/examples/bonding-curve-contract/src/function_selector.rs +++ b/contracts/examples/bonding-curve-contract/src/function_selector.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; use crate::bonding_curve::{ curves::{curve_function::CurveFunction, linear_function::LinearFunction}, diff --git a/contracts/examples/bonding-curve-contract/tests/bonding_curve_scenario_rs_test.rs b/contracts/examples/bonding-curve-contract/tests/bonding_curve_scenario_rs_test.rs index 576ed07983..81a143734b 100644 --- a/contracts/examples/bonding-curve-contract/tests/bonding_curve_scenario_rs_test.rs +++ b/contracts/examples/bonding-curve-contract/tests/bonding_curve_scenario_rs_test.rs @@ -3,7 +3,7 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); blockchain.register_contract( - "file:output/bonding-curve-contract.wasm", + "mxsc:output/bonding-curve-contract.mxsc.json", bonding_curve_contract::ContractBuilder, ); blockchain diff --git a/contracts/examples/bonding-curve-contract/wasm/Cargo.lock b/contracts/examples/bonding-curve-contract/wasm/Cargo.lock index a1c180a8ac..ece227a9c0 100644 --- a/contracts/examples/bonding-curve-contract/wasm/Cargo.lock +++ b/contracts/examples/bonding-curve-contract/wasm/Cargo.lock @@ -2,35 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bonding-curve-contract" @@ -48,27 +36,12 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "endian-type" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -77,61 +50,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/bonding-curve-contract/wasm/Cargo.toml b/contracts/examples/bonding-curve-contract/wasm/Cargo.toml index de23cf6a3f..baa6def885 100644 --- a/contracts/examples/bonding-curve-contract/wasm/Cargo.toml +++ b/contracts/examples/bonding-curve-contract/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "bonding-curve-contract-wasm" version = "0.0.0" -authors = ["Alin Cruceat "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.bonding-curve-contract] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 c2e6df3377..9c9061f01f 100644 --- a/contracts/examples/bonding-curve-contract/wasm/src/lib.rs +++ b/contracts/examples/bonding-curve-contract/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 98b482ee37..ca805cfd9f 100644 --- a/contracts/examples/check-pause/Cargo.toml +++ b/contracts/examples/check-pause/Cargo.toml @@ -9,17 +9,17 @@ publish = false path = "src/check_pause.rs" [dev-dependencies] -num-bigint = "0.4.2" +num-bigint = "0.4" [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/check-pause/meta/Cargo.toml b/contracts/examples/check-pause/meta/Cargo.toml index cff9cdcce2..9e3bd8d12f 100644 --- a/contracts/examples/check-pause/meta/Cargo.toml +++ b/contracts/examples/check-pause/meta/Cargo.toml @@ -8,6 +8,7 @@ authors = ["Alin Cruceat "] [dependencies.check-pause] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/src/check_pause.rs b/contracts/examples/check-pause/src/check_pause.rs index 82f5ba55a9..c5b4742d52 100644 --- a/contracts/examples/check-pause/src/check_pause.rs +++ b/contracts/examples/check-pause/src/check_pause.rs @@ -1,6 +1,6 @@ #![no_std] -multiversx_sc::imports!(); +use multiversx_sc::imports::*; use multiversx_sc_modules::pause; @@ -10,7 +10,7 @@ pub trait CheckPauseContract: pause::PauseModule { fn init(&self) {} #[endpoint(checkPause)] - fn check_pause(&self) -> SCResult { - Ok(self.is_paused()) + fn check_pause(&self) -> bool { + self.is_paused() } } diff --git a/contracts/examples/check-pause/wasm/Cargo.lock b/contracts/examples/check-pause/wasm/Cargo.lock index 1aa7a37392..d25d2b3daa 100644 --- a/contracts/examples/check-pause/wasm/Cargo.lock +++ b/contracts/examples/check-pause/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "check-pause" @@ -60,15 +42,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -77,61 +50,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/check-pause/wasm/Cargo.toml b/contracts/examples/check-pause/wasm/Cargo.toml index 89090c06a3..fbdd44a72b 100644 --- a/contracts/examples/check-pause/wasm/Cargo.toml +++ b/contracts/examples/check-pause/wasm/Cargo.toml @@ -1,17 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "check-pause-wasm" version = "0.0.0" edition = "2021" -authors = ["Alin Cruceat "] publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = [".",] - -[dev-dependencies] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -19,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.check-pause] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/check-pause/wasm/src/lib.rs b/contracts/examples/check-pause/wasm/src/lib.rs index 5ce44c370a..5bf4ed5b95 100644 --- a/contracts/examples/check-pause/wasm/src/lib.rs +++ b/contracts/examples/check-pause/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 6d9196cc84..e803967225 100644 --- a/contracts/examples/crowdfunding-esdt/Cargo.toml +++ b/contracts/examples/crowdfunding-esdt/Cargo.toml @@ -9,14 +9,14 @@ publish = false path = "src/crowdfunding_esdt.rs" [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" [dev-dependencies] -num-bigint = "0.4.2" +num-bigint = "0.4" num-traits = "0.2" hex = "0.4" diff --git a/contracts/examples/crowdfunding-esdt/meta/Cargo.toml b/contracts/examples/crowdfunding-esdt/meta/Cargo.toml index 810bfe8264..cb3b9f3c75 100644 --- a/contracts/examples/crowdfunding-esdt/meta/Cargo.toml +++ b/contracts/examples/crowdfunding-esdt/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.crowdfunding-esdt] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/_generated_fund.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/_generated_fund.scen.json index 3959ce0723..6485ff115f 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/_generated_fund.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/_generated_fund.scen.json @@ -29,7 +29,7 @@ "accounts": { "0x0000000000000000d720a08b839a004c2e6386f5aecc19ec74807d1920cb6aeb": { "balance": "0", - "code": "file:../output/crowdfunding-esdt.wasm", + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json", "owner": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925" } } @@ -89,7 +89,7 @@ "str:target": "0x07d0", "str:tokenIdentifier": "0x43524f57442d313233343536" }, - "code": "file:../output/crowdfunding-esdt.wasm", + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json", "owner": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925", "developerRewards": "0" } @@ -109,7 +109,7 @@ ], "function": "fund", "arguments": [], - "gasLimit": "18446744073709551615", + "gasLimit": "100,000,000", "gasPrice": "0" }, "expect": { diff --git a/contracts/examples/crowdfunding-esdt/scenarios/_generated_init.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/_generated_init.scen.json index 08b369285e..e8e2095c23 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/_generated_init.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/_generated_init.scen.json @@ -29,7 +29,7 @@ "accounts": { "0x0000000000000000d720a08b839a004c2e6386f5aecc19ec74807d1920cb6aeb": { "balance": "0", - "code": "file:../output/crowdfunding-esdt.wasm", + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json", "owner": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925" } } @@ -89,7 +89,7 @@ "str:target": "0x07d0", "str:tokenIdentifier": "0x43524f57442d313233343536" }, - "code": "file:../output/crowdfunding-esdt.wasm", + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json", "owner": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925", "developerRewards": "0" } diff --git a/contracts/examples/crowdfunding-esdt/scenarios/_generated_query_status.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/_generated_query_status.scen.json index c78a0a799f..26b52d5818 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/_generated_query_status.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/_generated_query_status.scen.json @@ -29,7 +29,7 @@ "accounts": { "0x0000000000000000d720a08b839a004c2e6386f5aecc19ec74807d1920cb6aeb": { "balance": "0", - "code": "file:../output/crowdfunding-esdt.wasm", + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json", "owner": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925" } } @@ -89,7 +89,7 @@ "str:target": "0x07d0", "str:tokenIdentifier": "0x43524f57442d313233343536" }, - "code": "file:../output/crowdfunding-esdt.wasm", + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json", "owner": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925", "developerRewards": "0" } diff --git a/contracts/examples/crowdfunding-esdt/scenarios/_generated_sc_err.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/_generated_sc_err.scen.json index b820dc1521..d68623c3d3 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/_generated_sc_err.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/_generated_sc_err.scen.json @@ -29,7 +29,7 @@ "accounts": { "0x0000000000000000d720a08b839a004c2e6386f5aecc19ec74807d1920cb6aeb": { "balance": "0", - "code": "file:../output/crowdfunding-esdt.wasm", + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json", "owner": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925" } } @@ -89,7 +89,7 @@ "str:target": "0x07d0", "str:tokenIdentifier": "0x43524f57442d313233343536" }, - "code": "file:../output/crowdfunding-esdt.wasm", + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json", "owner": "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925", "developerRewards": "0" } @@ -126,7 +126,7 @@ "egldValue": "1000", "function": "fund", "arguments": [], - "gasLimit": "18446744073709551615", + "gasLimit": "100,000,000", "gasPrice": "0" }, "expect": { diff --git a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-claim-failed.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-claim-failed.scen.json index 81472c075d..5ec115d7d8 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-claim-failed.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-claim-failed.scen.json @@ -79,7 +79,7 @@ "str:deposit|address:donor1": "250,000,000,000", "str:deposit|address:donor2": "200,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } }, @@ -113,7 +113,7 @@ "250,000,000,000", "address:donor1" ], - "data": "" + "data": "*" } ], "gas": "*", @@ -144,7 +144,7 @@ "200,000,000,000", "address:donor2" ], - "data": "" + "data": "*" } ], "gas": "*", @@ -188,7 +188,7 @@ "str:deposit|address:donor1": "0", "str:deposit|address:donor2": "0" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } } diff --git a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-claim-successful.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-claim-successful.scen.json index 9d56c80a08..b4e8cab085 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-claim-successful.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-claim-successful.scen.json @@ -78,7 +78,7 @@ "str:deposit|address:donor1": "250,000,000,000", "str:deposit|address:donor2": "250,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } }, @@ -131,7 +131,7 @@ "500,000,000,000", "address:my_address" ], - "data": "" + "data": "*" } ], "gas": "*", @@ -178,7 +178,7 @@ "str:deposit|address:donor1": "250,000,000,000", "str:deposit|address:donor2": "250,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } } diff --git a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-fund-too-late.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-fund-too-late.scen.json index 8f81de1359..1320619c8a 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-fund-too-late.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-fund-too-late.scen.json @@ -64,7 +64,7 @@ "str:tokenIdentifier": "str:CROWD-123456", "str:deposit|address:donor1": "250,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } }, diff --git a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-fund.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-fund.scen.json index ee01c19883..2a4a348f54 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-fund.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-fund.scen.json @@ -69,7 +69,7 @@ "str:tokenIdentifier": "str:CROWD-123456", "str:deposit|address:donor1": "250,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } } diff --git a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-init.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-init.scen.json index 8ad105d802..cdf4424b2d 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-init.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/crowdfunding-init.scen.json @@ -22,7 +22,7 @@ "id": "deploy", "tx": { "from": "address:my_address", - "contractCode": "file:../output/crowdfunding-esdt.wasm", + "contractCode": "mxsc:../output/crowdfunding-esdt.mxsc.json", "arguments": [ "500,000,000,000", "123,000", @@ -54,7 +54,7 @@ "str:deadline": "123,000", "str:tokenIdentifier": "str:CROWD-123456" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } } diff --git a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-claim-failed.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-claim-failed.scen.json index eaab2ea110..be2df15dcd 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-claim-failed.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-claim-failed.scen.json @@ -61,7 +61,7 @@ "str:deposit|address:donor1": "250,000,000,000", "str:deposit|address:donor2": "200,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } }, @@ -135,7 +135,7 @@ "str:deposit|address:donor1": "0", "str:deposit|address:donor2": "0" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } } diff --git a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-claim-successful.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-claim-successful.scen.json index 398aa58de9..4d911a34dc 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-claim-successful.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-claim-successful.scen.json @@ -61,7 +61,7 @@ "str:deposit|address:donor1": "250,000,000,000", "str:deposit|address:donor2": "250,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } }, @@ -136,7 +136,7 @@ "str:deposit|address:donor1": "250,000,000,000", "str:deposit|address:donor2": "250,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } } diff --git a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-fund-too-late.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-fund-too-late.scen.json index 8cbb37c69d..021c8ebaa6 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-fund-too-late.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-fund-too-late.scen.json @@ -53,7 +53,7 @@ "str:tokenIdentifier": "str:EGLD", "str:deposit|address:donor1": "250,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } }, diff --git a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-fund.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-fund.scen.json index 17985d48d8..207b282c5f 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-fund.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-fund.scen.json @@ -55,7 +55,7 @@ "str:tokenIdentifier": "str:EGLD", "str:deposit|address:donor1": "250,000,000,000" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } } diff --git a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-init.scen.json b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-init.scen.json index 533e8abe19..4d89bcc06a 100644 --- a/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-init.scen.json +++ b/contracts/examples/crowdfunding-esdt/scenarios/egld-crowdfunding-init.scen.json @@ -22,7 +22,7 @@ "id": "deploy", "tx": { "from": "address:my_address", - "contractCode": "file:../output/crowdfunding-esdt.wasm", + "contractCode": "mxsc:../output/crowdfunding-esdt.mxsc.json", "arguments": [ "500,000,000,000", "123,000", @@ -54,7 +54,7 @@ "str:deadline": "123,000", "str:tokenIdentifier": "str:EGLD" }, - "code": "file:../output/crowdfunding-esdt.wasm" + "code": "mxsc:../output/crowdfunding-esdt.mxsc.json" } } } diff --git a/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs b/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs index 625cd24487..1dea493562 100644 --- a/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs +++ b/contracts/examples/crowdfunding-esdt/src/crowdfunding_esdt.rs @@ -1,9 +1,10 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +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, @@ -74,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(); @@ -85,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 57b3ef2dd7..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 = "file:output/crowdfunding-esdt.wasm"; -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 2d1ff391e4..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,12 +2,12 @@ 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( - "file:output/crowdfunding-esdt.wasm", + "mxsc:output/crowdfunding-esdt.mxsc.json", crowdfunding_esdt::ContractBuilder, ); + blockchain } diff --git a/contracts/examples/crowdfunding-esdt/wasm/Cargo.lock b/contracts/examples/crowdfunding-esdt/wasm/Cargo.lock index 8a1910f612..4f405ac8b5 100644 --- a/contracts/examples/crowdfunding-esdt/wasm/Cargo.lock +++ b/contracts/examples/crowdfunding-esdt/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "crowdfunding-esdt" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/crowdfunding-esdt/wasm/Cargo.toml b/contracts/examples/crowdfunding-esdt/wasm/Cargo.toml index 8e51c3d294..e348761989 100644 --- a/contracts/examples/crowdfunding-esdt/wasm/Cargo.toml +++ b/contracts/examples/crowdfunding-esdt/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "crowdfunding-esdt-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.crowdfunding-esdt] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 44468e838e..eb3d65740b 100644 --- a/contracts/examples/crowdfunding-esdt/wasm/src/lib.rs +++ b/contracts/examples/crowdfunding-esdt/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 fac4e5886b..bf23c6dcd9 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/crypto-bubbles/meta/Cargo.toml b/contracts/examples/crypto-bubbles/meta/Cargo.toml index ddfaa8b38a..b16e54906e 100644 --- a/contracts/examples/crypto-bubbles/meta/Cargo.toml +++ b/contracts/examples/crypto-bubbles/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.crypto-bubbles] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/balanceOf.scen.json b/contracts/examples/crypto-bubbles/scenarios/balanceOf.scen.json index dac65aff9a..c7df4d91d5 100644 --- a/contracts/examples/crypto-bubbles/scenarios/balanceOf.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/balanceOf.scen.json @@ -15,7 +15,7 @@ "storage": { "str:playerBalance|address:acc2": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "0", @@ -84,7 +84,7 @@ "storage": { "str:playerBalance|address:acc2": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "2", diff --git a/contracts/examples/crypto-bubbles/scenarios/create.scen.json b/contracts/examples/crypto-bubbles/scenarios/create.scen.json index 017adddce6..29b58f0ef4 100644 --- a/contracts/examples/crypto-bubbles/scenarios/create.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/create.scen.json @@ -23,7 +23,7 @@ "id": "1", "tx": { "from": "address:crypto_bubbles_owner", - "contractCode": "file:../output/crypto-bubbles.wasm", + "contractCode": "mxsc:../output/crypto-bubbles.mxsc.json", "arguments": [], "gasLimit": "0x100000", "gasPrice": "0x01" @@ -49,7 +49,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" } } } diff --git a/contracts/examples/crypto-bubbles/scenarios/exceptions.scen.json b/contracts/examples/crypto-bubbles/scenarios/exceptions.scen.json index f8caed348c..cb6668f202 100644 --- a/contracts/examples/crypto-bubbles/scenarios/exceptions.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/exceptions.scen.json @@ -12,7 +12,7 @@ "sc:crypto_bubbles": { "nonce": "0", "balance": "0x1300", - "code": "file:../output/crypto-bubbles.wasm", + "code": "mxsc:../output/crypto-bubbles.mxsc.json", "owner": "address:crypto_bubbles_owner" } } @@ -76,7 +76,7 @@ "nonce": "0", "balance": "0x1300", "storage": {}, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" } } } diff --git a/contracts/examples/crypto-bubbles/scenarios/joinGame.scen.json b/contracts/examples/crypto-bubbles/scenarios/joinGame.scen.json index aa224802ae..6c61b9304e 100644 --- a/contracts/examples/crypto-bubbles/scenarios/joinGame.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/joinGame.scen.json @@ -16,7 +16,7 @@ "str:playerBalance|address:acc1": "0x311", "str:playerBalance|address:acc2": "0x422" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "0", @@ -53,7 +53,9 @@ "str:top_up", "address:acc1" ], - "data": "0x0200" + "data": [ + "0x0200" + ] }, { "address": "sc:crypto_bubbles", @@ -63,7 +65,9 @@ "0x12", "address:acc1" ], - "data": "0x200" + "data": [ + "0x200" + ] } ], "gas": "*", @@ -95,7 +99,9 @@ "str:top_up", "address:acc2" ], - "data": "0x150" + "data": [ + "0x150" + ] }, { "address": "sc:crypto_bubbles", @@ -105,7 +111,9 @@ "0x12", "address:acc2" ], - "data": "0x150" + "data": [ + "0x150" + ] } ], "gas": "*", @@ -137,7 +145,9 @@ "str:top_up", "address:acc2" ], - "data": "0x2000" + "data": [ + "0x2000" + ] }, { "address": "sc:crypto_bubbles", @@ -147,7 +157,9 @@ "0x12", "address:acc2" ], - "data": "0x2000" + "data": [ + "0x2000" + ] } ], "gas": "*", @@ -170,7 +182,7 @@ "str:playerBalance|address:acc1": "0x311", "str:playerBalance|address:acc2": "0x422" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "1", diff --git a/contracts/examples/crypto-bubbles/scenarios/rewardAndSendToWallet.scen.json b/contracts/examples/crypto-bubbles/scenarios/rewardAndSendToWallet.scen.json index 57680af622..36225608ae 100644 --- a/contracts/examples/crypto-bubbles/scenarios/rewardAndSendToWallet.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/rewardAndSendToWallet.scen.json @@ -16,7 +16,7 @@ "str:playerBalance|address:acc1": "0x100", "str:playerBalance|address:acc2": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm", + "code": "mxsc:../output/crypto-bubbles.mxsc.json", "owner": "address:crypto_bubbles_owner" }, "address:acc1": { @@ -52,17 +52,18 @@ "0x12", "address:acc1" ], - "data": "0x200" + "data": [ + "0x200" + ] }, { - "address": "*", + "address": "sc:crypto_bubbles", "endpoint": "str:transferValueOnly", "topics": [ - "sc:crypto_bubbles", - "address:acc1", - "0x0200" + "0x0200", + "address:acc1" ], - "data": "" + "data": "*" }, { "address": "sc:crypto_bubbles", @@ -71,7 +72,9 @@ "str:withdraw", "address:acc1" ], - "data": "0x200" + "data": [ + "0x200" + ] } ], "gas": "*", @@ -94,7 +97,7 @@ "str:playerBalance|address:acc1": "0x100", "str:playerBalance|address:acc2": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "0", diff --git a/contracts/examples/crypto-bubbles/scenarios/rewardWinner.scen.json b/contracts/examples/crypto-bubbles/scenarios/rewardWinner.scen.json index e81668a0d4..294da838bd 100644 --- a/contracts/examples/crypto-bubbles/scenarios/rewardWinner.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/rewardWinner.scen.json @@ -16,7 +16,7 @@ "str:playerBalance|address:acc1": "0x100", "str:playerBalance|address:acc2": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm", + "code": "mxsc:../output/crypto-bubbles.mxsc.json", "owner": "address:crypto_bubbles_owner" } } @@ -48,7 +48,9 @@ "0x12", "address:acc1" ], - "data": "0x200" + "data": [ + "0x200" + ] } ], "gas": "*", @@ -71,7 +73,7 @@ "str:playerBalance|address:acc1": "0x300", "str:playerBalance|address:acc2": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" } } } diff --git a/contracts/examples/crypto-bubbles/scenarios/rewardWinner_Last.scen.json b/contracts/examples/crypto-bubbles/scenarios/rewardWinner_Last.scen.json index aa20252361..a605ee2d62 100644 --- a/contracts/examples/crypto-bubbles/scenarios/rewardWinner_Last.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/rewardWinner_Last.scen.json @@ -16,7 +16,7 @@ "str:playerBalance|address:acc1": "0x100", "str:playerBalance|address:acc2": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm", + "code": "mxsc:../output/crypto-bubbles.mxsc.json", "owner": "address:crypto_bubbles_owner" } } @@ -48,7 +48,9 @@ "0x12", "address:acc1" ], - "data": "0x1000" + "data": [ + "0x1000" + ] } ], "gas": "*", @@ -71,7 +73,7 @@ "str:playerBalance|address:acc1": "0x1100", "str:playerBalance|address:acc2": "0x0100" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" } } } diff --git a/contracts/examples/crypto-bubbles/scenarios/topUp_ok.scen.json b/contracts/examples/crypto-bubbles/scenarios/topUp_ok.scen.json index 40ca3ee88d..8494d7b2c8 100644 --- a/contracts/examples/crypto-bubbles/scenarios/topUp_ok.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/topUp_ok.scen.json @@ -12,7 +12,7 @@ "sc:crypto_bubbles": { "nonce": "0", "balance": "0", - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "0", @@ -47,7 +47,9 @@ "str:top_up", "address:acc1" ], - "data": "0x0100" + "data": [ + "0x0100" + ] } ], "gas": "*", @@ -77,7 +79,9 @@ "str:top_up", "address:acc2" ], - "data": "0x0100" + "data": [ + "0x0100" + ] } ], "gas": "*", @@ -100,7 +104,7 @@ "str:playerBalance|address:acc1": "0x100", "str:playerBalance|address:acc2": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "1", diff --git a/contracts/examples/crypto-bubbles/scenarios/topUp_withdraw.scen.json b/contracts/examples/crypto-bubbles/scenarios/topUp_withdraw.scen.json index bbcd965745..31ceb5ae4e 100644 --- a/contracts/examples/crypto-bubbles/scenarios/topUp_withdraw.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/topUp_withdraw.scen.json @@ -12,7 +12,7 @@ "sc:crypto_bubbles": { "nonce": "0", "balance": "0", - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "0", @@ -43,7 +43,9 @@ "str:top_up", "address:acc1" ], - "data": "0x4000000" + "data": [ + "0x4000000" + ] } ], "gas": "*", @@ -68,14 +70,13 @@ "status": "", "logs": [ { - "address": "*", + "address": "sc:crypto_bubbles", "endpoint": "str:transferValueOnly", "topics": [ - "sc:crypto_bubbles", - "address:acc1", - "0x4000000" + "0x4000000", + "address:acc1" ], - "data": "" + "data": "*" }, { "address": "sc:crypto_bubbles", @@ -84,7 +85,9 @@ "str:withdraw", "address:acc1" ], - "data": "0x4000000" + "data": [ + "0x4000000" + ] } ], "gas": "*", @@ -104,7 +107,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "2", diff --git a/contracts/examples/crypto-bubbles/scenarios/withdraw_Ok.scen.json b/contracts/examples/crypto-bubbles/scenarios/withdraw_Ok.scen.json index 1db8bf7ea7..9518b57654 100644 --- a/contracts/examples/crypto-bubbles/scenarios/withdraw_Ok.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/withdraw_Ok.scen.json @@ -15,7 +15,7 @@ "storage": { "str:playerBalance|address:acc1": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "0", @@ -41,14 +41,13 @@ "status": "", "logs": [ { - "address": "*", + "address": "sc:crypto_bubbles", "endpoint": "str:transferValueOnly", "topics": [ - "sc:crypto_bubbles", - "address:acc1", - "0x10" + "0x10", + "address:acc1" ], - "data": "" + "data": "*" }, { "address": "sc:crypto_bubbles", @@ -57,7 +56,9 @@ "str:withdraw", "address:acc1" ], - "data": "0x10" + "data": [ + "0x10" + ] } ], "gas": "*", @@ -79,7 +80,7 @@ "storage": { "str:playerBalance|address:acc1": "0xf0" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "1", diff --git a/contracts/examples/crypto-bubbles/scenarios/withdraw_TooMuch.scen.json b/contracts/examples/crypto-bubbles/scenarios/withdraw_TooMuch.scen.json index 3523be8bf2..dc7779817c 100644 --- a/contracts/examples/crypto-bubbles/scenarios/withdraw_TooMuch.scen.json +++ b/contracts/examples/crypto-bubbles/scenarios/withdraw_TooMuch.scen.json @@ -15,7 +15,7 @@ "storage": { "str:playerBalance|address:acc1": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "0", @@ -60,7 +60,7 @@ "storage": { "str:playerBalance|address:acc1": "0x100" }, - "code": "file:../output/crypto-bubbles.wasm" + "code": "mxsc:../output/crypto-bubbles.mxsc.json" }, "address:acc1": { "nonce": "1", diff --git a/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs b/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs index 75af47f65c..35b687f2cc 100644 --- a/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs +++ b/contracts/examples/crypto-bubbles/src/crypto_bubbles.rs @@ -1,6 +1,6 @@ #![no_std] -multiversx_sc::imports!(); +use multiversx_sc::imports::*; #[multiversx_sc::contract] pub trait CryptoBubbles { @@ -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 3f54c45a4f..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,10 +2,9 @@ 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( - "file:output/crypto-bubbles.wasm", + "mxsc:output/crypto-bubbles.mxsc.json", crypto_bubbles::ContractBuilder, ); blockchain diff --git a/contracts/examples/crypto-bubbles/wasm/Cargo.lock b/contracts/examples/crypto-bubbles/wasm/Cargo.lock index 81c9afc9c1..73a4b219ec 100755 --- a/contracts/examples/crypto-bubbles/wasm/Cargo.lock +++ b/contracts/examples/crypto-bubbles/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "crypto-bubbles" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/crypto-bubbles/wasm/Cargo.toml b/contracts/examples/crypto-bubbles/wasm/Cargo.toml index 0026097348..bce34c10bd 100644 --- a/contracts/examples/crypto-bubbles/wasm/Cargo.toml +++ b/contracts/examples/crypto-bubbles/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "crypto-bubbles-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.crypto-bubbles] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 addf606a0a..925de32570 100644 --- a/contracts/examples/crypto-bubbles/wasm/src/lib.rs +++ b/contracts/examples/crypto-bubbles/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 2b08bb831e..35970fba03 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.44.0" +version = "0.53.0" 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 32b273d754..37a97b1dfc 100644 --- a/contracts/examples/crypto-kitties/common/kitty/src/color.rs +++ b/contracts/examples/crypto-kitties/common/kitty/src/color.rs @@ -1,8 +1,9 @@ -multiversx_sc::derive_imports!(); +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 b0906860e8..61d6623bf9 100644 --- a/contracts/examples/crypto-kitties/common/kitty/src/kitty_genes.rs +++ b/contracts/examples/crypto-kitties/common/kitty/src/kitty_genes.rs @@ -1,9 +1,10 @@ -multiversx_sc::derive_imports!(); +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 5c385d01de..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] -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 6fd25727ad..fa771af925 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.44.0" +version = "0.53.0" path = "../../../../../framework/base" diff --git a/contracts/examples/crypto-kitties/kitty-auction/Cargo.toml b/contracts/examples/crypto-kitties/kitty-auction/Cargo.toml index 430b3a3b92..377c0e15d3 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 a6f07fe46c..74bbbd6677 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/meta/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-auction/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.kitty-auction] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/bid_first.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_first.scen.json index 1e1d86c2c8..091d1d691e 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_first.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_first.scen.json @@ -61,7 +61,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -73,7 +73,7 @@ "str:genZeroKittyAuctionDuration": "100,000", "str:auction|u32:1": "u8:0|u32:1|u8:100|u32:2|u16:500|u64:223456|sc:kitty_auction_contract|u32:1|u8:200|address:bidder1" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_max.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_max.scen.json index 0c37af6a11..60bfca350f 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_max.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_max.scen.json @@ -66,7 +66,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -78,7 +78,7 @@ "str:genZeroKittyAuctionDuration": "100,000", "str:auction|u32:1": "u8:0|u32:1|u8:100|u32:2|u16:500|u64:223456|sc:kitty_auction_contract|u32:2|u16:500|address:bidder2" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_ok.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_ok.scen.json index af86f5c919..e4e956c0bc 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_ok.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_ok.scen.json @@ -66,7 +66,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -78,7 +78,7 @@ "str:genZeroKittyAuctionDuration": "100,000", "str:auction|u32:1": "u8:0|u32:1|u8:100|u32:2|u16:500|u64:223456|sc:kitty_auction_contract|u32:1|u8:250|address:bidder2" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_too_low.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_too_low.scen.json index 471a88c676..cefc49a9f0 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_too_low.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_second_too_low.scen.json @@ -66,7 +66,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -78,7 +78,7 @@ "str:genZeroKittyAuctionDuration": "100,000", "str:auction|u32:1": "u8:0|u32:1|u8:100|u32:2|u16:500|u64:223456|sc:kitty_auction_contract|u32:1|u8:200|address:bidder1" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_siring_auction.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_siring_auction.scen.json index 9ac802d7f1..2d455bb169 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_siring_auction.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/bid_siring_auction.scen.json @@ -57,7 +57,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -69,7 +69,7 @@ "str:genZeroKittyAuctionDuration": "100,000", "str:auction|u32:1": "u8:1|u32:2|u16:1000|u32:2|u16:5000|u64:200000|address:bidder2|u32:2|u16:5000|address:bidder1" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_and_auction_gen_zero_kitty.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_and_auction_gen_zero_kitty.scen.json index 55249c347a..8700555bd3 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_and_auction_gen_zero_kitty.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_and_auction_gen_zero_kitty.scen.json @@ -54,7 +54,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -66,7 +66,7 @@ "str:genZeroKittyAuctionDuration": "100,000", "str:auction|u32:1": "u8:0|u32:1|u8:100|u32:2|u16:500|u64:223456|sc:kitty_auction_contract|u32:0|u64:0|u64:0|u64:0|u64:0" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_sale_auction_not_owner.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_sale_auction_not_owner.scen.json index 8c1a565100..f68c0a726f 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_sale_auction_not_owner.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_sale_auction_not_owner.scen.json @@ -65,7 +65,7 @@ "str:nrOwnedKitties|address:bidder2": "1", "str:owner|u32:1": "address:bidder2" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -76,7 +76,7 @@ "str:genZeroKittyEndingPrice": "500", "str:genZeroKittyAuctionDuration": "100,000" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_sale_auction_ok.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_sale_auction_ok.scen.json index 581cb3fac6..80043e0699 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_sale_auction_ok.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_sale_auction_ok.scen.json @@ -66,7 +66,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -78,7 +78,7 @@ "str:genZeroKittyAuctionDuration": "100,000", "str:auction|u32:1": "u8:0|u32:2|u16:1000|u32:2|u16:5000|u64:200000|address:bidder2|u32:0|u64:0|u64:0|u64:0|u64:0" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_siring_auction_not_owner.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_siring_auction_not_owner.scen.json index c81e72b3ed..817f4cf9b9 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_siring_auction_not_owner.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_siring_auction_not_owner.scen.json @@ -65,7 +65,7 @@ "str:nrOwnedKitties|address:bidder2": "1", "str:owner|u32:1": "address:bidder2" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -76,7 +76,7 @@ "str:genZeroKittyEndingPrice": "500", "str:genZeroKittyAuctionDuration": "100,000" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_siring_auction_ok.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_siring_auction_ok.scen.json index 9c3c3f4afd..6266eaeba2 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_siring_auction_ok.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/create_siring_auction_ok.scen.json @@ -66,7 +66,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -78,7 +78,7 @@ "str:genZeroKittyAuctionDuration": "100,000", "str:auction|u32:1": "u8:1|u32:2|u16:1000|u32:2|u16:5000|u64:200000|address:bidder2|u32:0|u64:0|u64:0|u64:0|u64:0" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_no_bids.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_no_bids.scen.json index 3d495703b1..be0825e884 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_no_bids.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_no_bids.scen.json @@ -52,7 +52,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -63,7 +63,7 @@ "str:genZeroKittyEndingPrice": "500", "str:genZeroKittyAuctionDuration": "100,000" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_max_early.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_max_early.scen.json index 29a1b81d01..c52cb665dd 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_max_early.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_max_early.scen.json @@ -57,7 +57,7 @@ "str:nrOwnedKitties|address:bidder2": "1", "str:owner|u32:1": "address:bidder2" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -68,7 +68,7 @@ "str:genZeroKittyEndingPrice": "500", "str:genZeroKittyAuctionDuration": "100,000" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_ok_early.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_ok_early.scen.json index 06f3477bc1..a347a943dd 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_ok_early.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_ok_early.scen.json @@ -56,7 +56,7 @@ "str:nrOwnedKitties|sc:kitty_auction_contract": "1", "str:owner|u32:1": "sc:kitty_auction_contract" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -68,7 +68,7 @@ "str:genZeroKittyAuctionDuration": "100,000", "str:auction|u32:1": "u8:0|u32:1|u8:100|u32:2|u16:500|u64:223456|sc:kitty_auction_contract|u32:1|u8:250|address:bidder2" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_ok_late.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_ok_late.scen.json index c2dacd9820..b9c71069a3 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_ok_late.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_auction_second_bid_ok_late.scen.json @@ -63,7 +63,7 @@ "str:nrOwnedKitties|address:bidder2": "1", "str:owner|u32:1": "address:bidder2" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -74,7 +74,7 @@ "str:genZeroKittyEndingPrice": "500", "str:genZeroKittyAuctionDuration": "100,000" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_siring_auction.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_siring_auction.scen.json index 86f22d97a2..b8bdfe64d2 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_siring_auction.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/end_siring_auction.scen.json @@ -58,7 +58,7 @@ "str:owner|u32:1": "address:bidder2", "str:sireAllowedAddress|u32:1": "address:bidder1" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -69,7 +69,7 @@ "str:genZeroKittyEndingPrice": "500", "str:genZeroKittyAuctionDuration": "100,000" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/scenarios/init.scen.json b/contracts/examples/crypto-kitties/kitty-auction/scenarios/init.scen.json index 032deab851..21f46736a4 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/scenarios/init.scen.json +++ b/contracts/examples/crypto-kitties/kitty-auction/scenarios/init.scen.json @@ -29,7 +29,7 @@ "comment": "we don't care about autoBirthFee in this test, so we set it to 0", "tx": { "from": "address:my_address", - "contractCode": "file:../../kitty-ownership/output/kitty-ownership.wasm", + "contractCode": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json", "arguments": [ "0" ], @@ -49,7 +49,7 @@ "id": "deploy - kitty auction contract", "tx": { "from": "address:my_address", - "contractCode": "file:../output/kitty-auction.wasm", + "contractCode": "mxsc:../output/kitty-auction.mxsc.json", "arguments": [ "100", "500", @@ -104,7 +104,7 @@ "str:totalKitties": "1", "str:kitty|u32:0": "u8:0|u8:0|u8:0|u8:0|u8:0|u8:0|u8:0|u64:0|u64:0|u32:0|u32:0|u32:0|u16:0|u16:0" }, - "code": "file:../../kitty-ownership/output/kitty-ownership.wasm" + "code": "mxsc:../../kitty-ownership/output/kitty-ownership.mxsc.json" }, "sc:kitty_auction_contract": { "nonce": "0", @@ -115,7 +115,7 @@ "str:genZeroKittyEndingPrice": "500", "str:genZeroKittyAuctionDuration": "100,000" }, - "code": "file:../output/kitty-auction.wasm" + "code": "mxsc:../output/kitty-auction.mxsc.json" } } } diff --git a/contracts/examples/crypto-kitties/kitty-auction/src/auction.rs b/contracts/examples/crypto-kitties/kitty-auction/src/auction.rs index c71aeac0a8..261def0cf0 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/src/auction.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/src/auction.rs @@ -1,4 +1,4 @@ -multiversx_sc::derive_imports!(); +use multiversx_sc::derive_imports::*; use multiversx_sc::{ api::ManagedTypeApi, @@ -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 b371268418..60a30c382e 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/src/lib.rs @@ -1,9 +1,10 @@ #![no_std] -multiversx_sc::imports!(); +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/tests/kitty_auction_scenario_rs_test.rs b/contracts/examples/crypto-kitties/kitty-auction/tests/kitty_auction_scenario_rs_test.rs index 110acd8da4..e7fce12ce1 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/tests/kitty_auction_scenario_rs_test.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/tests/kitty_auction_scenario_rs_test.rs @@ -4,11 +4,11 @@ fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); blockchain.register_contract( - "file:../kitty-ownership/output/kitty-ownership.wasm", + "mxsc:../kitty-ownership/output/kitty-ownership.mxsc.json", kitty_ownership::ContractBuilder, ); blockchain.register_contract( - "file:output/kitty-auction.wasm", + "mxsc:output/kitty-auction.mxsc.json", kitty_auction::ContractBuilder, ); diff --git a/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.lock b/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.lock index 626173fed6..73087aff8c 100755 --- a/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.lock +++ b/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "kitty" @@ -111,48 +84,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -168,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -218,26 +186,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -251,27 +208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 84aba96790..3526a48644 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-auction/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "kitty-auction-wasm" version = "0.0.0" @@ -5,10 +11,7 @@ edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = ["."] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -16,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.kitty-auction] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../../framework/wasm-adapter" + +[workspace] +members = ["."] 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 d4dc345a46..6d115b6c92 100644 --- a/contracts/examples/crypto-kitties/kitty-auction/wasm/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-auction/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 974e89d7c7..2ea3296283 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 5f488283a8..3deffa8b6c 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.kitty-genetic-alg] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/init.scen.json b/contracts/examples/crypto-kitties/kitty-genetic-alg/scenarios/init.scen.json index a88e88a6ed..a86c5930e2 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/scenarios/init.scen.json +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/scenarios/init.scen.json @@ -23,7 +23,7 @@ "id": "deploy", "tx": { "from": "address:my_address", - "contractCode": "file:../output/kitty-genetic-alg.wasm", + "contractCode": "mxsc:../output/kitty-genetic-alg.mxsc.json", "arguments": [], "gasLimit": "1,000,000", "gasPrice": "0" @@ -47,7 +47,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/kitty-genetic-alg.wasm" + "code": "mxsc:../output/kitty-genetic-alg.mxsc.json" } } } 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 f2571fda2c..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,8 +1,6 @@ #![no_std] -multiversx_sc::imports!(); - -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/tests/kitty_genetic_alg_scenario_rs_test.rs b/contracts/examples/crypto-kitties/kitty-genetic-alg/tests/kitty_genetic_alg_scenario_rs_test.rs index 8389bb81bd..08672d2f0c 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/tests/kitty_genetic_alg_scenario_rs_test.rs +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/tests/kitty_genetic_alg_scenario_rs_test.rs @@ -3,7 +3,7 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); blockchain.register_contract( - "file:output/kitty-genetic-alg.wasm", + "mxsc:output/kitty-genetic-alg.mxsc.json", kitty_genetic_alg::ContractBuilder, ); blockchain 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 8115175f74..809b74b818 100755 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.lock +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "kitty" @@ -92,48 +65,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -149,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -199,26 +167,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -232,27 +189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 ea6a35ef1d..1ce273b242 100644 --- a/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-genetic-alg/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "kitty-genetic-alg-wasm" version = "0.0.0" @@ -5,10 +11,7 @@ edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = ["."] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -16,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.kitty-genetic-alg] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../../framework/wasm-adapter" + +[workspace] +members = ["."] 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 8f754d1cb5..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 cc1de09a53..83021af48b 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 d8567bbbe8..4d1e67e66a 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/meta/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-ownership/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.kitty-ownership] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/approve_siring.scen.json b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/approve_siring.scen.json index 12a184998c..bf0e9ab06f 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/scenarios/approve_siring.scen.json +++ b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/approve_siring.scen.json @@ -48,7 +48,7 @@ "str:nrOwnedKitties|address:acc2": "1", "str:sireAllowedAddress|u32:1": "address:acc2" }, - "code": "file:../output/kitty-ownership.wasm" + "code": "mxsc:../output/kitty-ownership.mxsc.json" }, "+": "" } diff --git a/contracts/examples/crypto-kitties/kitty-ownership/scenarios/breed_ok.scen.json b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/breed_ok.scen.json index d206470490..6dc16cf766 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/scenarios/breed_ok.scen.json +++ b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/breed_ok.scen.json @@ -63,7 +63,7 @@ "str:nrOwnedKitties|address:acc1": "1", "str:nrOwnedKitties|address:acc2": "1" }, - "code": "file:../output/kitty-ownership.wasm" + "code": "mxsc:../output/kitty-ownership.mxsc.json" }, "+": "" } diff --git a/contracts/examples/crypto-kitties/kitty-ownership/scenarios/give_birth.scen.json b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/give_birth.scen.json index 45271172cf..8e355e6aa4 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/scenarios/give_birth.scen.json +++ b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/give_birth.scen.json @@ -78,7 +78,7 @@ "str:nrOwnedKitties|address:acc1": "1", "str:nrOwnedKitties|address:acc2": "2" }, - "code": "file:../output/kitty-ownership.wasm" + "code": "mxsc:../output/kitty-ownership.mxsc.json" }, "+": "" } diff --git a/contracts/examples/crypto-kitties/kitty-ownership/scenarios/init.scen.json b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/init.scen.json index 32fcb5bb60..0dee3d0fd4 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/scenarios/init.scen.json +++ b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/init.scen.json @@ -31,7 +31,7 @@ "id": "deploy - kitty genetic alg contract", "tx": { "from": "address:my_address", - "contractCode": "file:../../kitty-genetic-alg/output/kitty-genetic-alg.wasm", + "contractCode": "mxsc:../../kitty-genetic-alg/output/kitty-genetic-alg.mxsc.json", "arguments": [], "gasLimit": "1,000,000", "gasPrice": "0" @@ -49,7 +49,7 @@ "id": "deploy - kitty ownership contract", "tx": { "from": "address:my_address", - "contractCode": "file:../output/kitty-ownership.wasm", + "contractCode": "mxsc:../output/kitty-ownership.mxsc.json", "arguments": [ "10", "sc:kitty_genetic_alg", @@ -84,7 +84,7 @@ "str:totalKitties": "1", "str:kitty|u32:0": "u8:0|u8:0|u8:0|u8:0|u8:0|u8:0|u8:0|u64:0|u64:0|u32:0|u32:0|u32:0|u16:0|u16:0" }, - "code": "file:../output/kitty-ownership.wasm" + "code": "mxsc:../output/kitty-ownership.mxsc.json" }, "+": "" } diff --git a/contracts/examples/crypto-kitties/kitty-ownership/scenarios/setup_accounts.scen.json b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/setup_accounts.scen.json index f5a843b61b..830fc1b8d7 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/scenarios/setup_accounts.scen.json +++ b/contracts/examples/crypto-kitties/kitty-ownership/scenarios/setup_accounts.scen.json @@ -41,7 +41,7 @@ "str:nrOwnedKitties|address:acc1": "1", "str:nrOwnedKitties|address:acc2": "1" }, - "code": "file:../output/kitty-ownership.wasm" + "code": "mxsc:../output/kitty-ownership.mxsc.json" } }, "currentBlockInfo": { 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 e3fd696b65..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)] -multiversx_sc::imports!(); +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/tests/kitty_ownership_scenario_rs_test.rs b/contracts/examples/crypto-kitties/kitty-ownership/tests/kitty_ownership_scenario_rs_test.rs index 9101ffbf0d..238a3f8fce 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/tests/kitty_ownership_scenario_rs_test.rs +++ b/contracts/examples/crypto-kitties/kitty-ownership/tests/kitty_ownership_scenario_rs_test.rs @@ -4,11 +4,11 @@ fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); blockchain.register_contract( - "file:../kitty-genetic-alg/output/kitty-genetic-alg.wasm", + "mxsc:../kitty-genetic-alg/output/kitty-genetic-alg.mxsc.json", kitty_genetic_alg::ContractBuilder, ); blockchain.register_contract( - "file:output/kitty-ownership.wasm", + "mxsc:output/kitty-ownership.mxsc.json", kitty_ownership::ContractBuilder, ); diff --git a/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.lock b/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.lock index f0e28bf790..d00573ddbe 100755 --- a/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.lock +++ b/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "kitty" @@ -102,48 +75,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -159,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -209,26 +177,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -242,27 +199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 f4d5eb059b..60aa30b00a 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.toml +++ b/contracts/examples/crypto-kitties/kitty-ownership/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "kitty-ownership-wasm" version = "0.0.0" @@ -5,10 +11,7 @@ edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = ["."] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -16,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.kitty-ownership] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../../framework/wasm-adapter" + +[workspace] +members = ["."] 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 f739b7ee7c..9a5ffdaba8 100644 --- a/contracts/examples/crypto-kitties/kitty-ownership/wasm/src/lib.rs +++ b/contracts/examples/crypto-kitties/kitty-ownership/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 8d9b9c36e8..4ef64950ba 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/crypto-zombies/meta/Cargo.toml b/contracts/examples/crypto-zombies/meta/Cargo.toml index 050741e87f..f17443b66f 100644 --- a/contracts/examples/crypto-zombies/meta/Cargo.toml +++ b/contracts/examples/crypto-zombies/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.crypto-zombies] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/mxsc-template.toml b/contracts/examples/crypto-zombies/mxsc-template.toml index 38ef0ca7f5..ef01adab57 100644 --- a/contracts/examples/crypto-zombies/mxsc-template.toml +++ b/contracts/examples/crypto-zombies/mxsc-template.toml @@ -7,7 +7,6 @@ files_include = [ "scenarios", "src", "tests", - "wasm/Cargo.toml", "Cargo.toml", "multiversx.json", ] 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/kitty_obj.rs b/contracts/examples/crypto-zombies/src/kitty_obj.rs new file mode 100644 index 0000000000..5ba10f51e5 --- /dev/null +++ b/contracts/examples/crypto-zombies/src/kitty_obj.rs @@ -0,0 +1,42 @@ +use multiversx_sc::derive_imports::*; +#[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. +} + +#[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 +} + +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct Color { + pub r: u8, + pub g: u8, + pub b: u8, +} + +impl KittyGenes { + pub fn get_as_u64(&self) -> u64 { + (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) << 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 6afd060d4f..a79de4fcb0 100644 --- a/contracts/examples/crypto-zombies/src/lib.rs +++ b/contracts/examples/crypto-zombies/src/lib.rs @@ -1,8 +1,10 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; +pub mod kitty_obj; +pub mod kitty_ownership_proxy; +pub mod proxy_crypto_zombies; mod storage; mod zombie; mod zombie_attack; @@ -26,6 +28,9 @@ pub trait CryptoZombies: self.cooldown_time().set(86400u64); } + #[upgrade] + fn upgrade(&self) {} + #[only_owner] #[endpoint] fn set_crypto_kitties_sc_address(&self, address: ManagedAddress) { 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 e6361efd65..6670547064 100644 --- a/contracts/examples/crypto-zombies/src/storage.rs +++ b/contracts/examples/crypto-zombies/src/storage.rs @@ -1,44 +1,43 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; 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 3d814b9e3a..bfe3fd22ad 100644 --- a/contracts/examples/crypto-zombies/src/zombie.rs +++ b/contracts/examples/crypto-zombies/src/zombie.rs @@ -1,7 +1,7 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +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_attack.rs b/contracts/examples/crypto-zombies/src/zombie_attack.rs index 7678947365..e4bebdeca4 100644 --- a/contracts/examples/crypto-zombies/src/zombie_attack.rs +++ b/contracts/examples/crypto-zombies/src/zombie_attack.rs @@ -1,4 +1,4 @@ -multiversx_sc::imports!(); +use multiversx_sc::imports::*; use crate::{storage, zombie_factory, zombie_feeding, zombie_helper}; diff --git a/contracts/examples/crypto-zombies/src/zombie_factory.rs b/contracts/examples/crypto-zombies/src/zombie_factory.rs index 0a637880eb..996c339e82 100644 --- a/contracts/examples/crypto-zombies/src/zombie_factory.rs +++ b/contracts/examples/crypto-zombies/src/zombie_factory.rs @@ -1,12 +1,11 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; 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, @@ -41,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 07edcbe4e4..8061e5f7f6 100644 --- a/contracts/examples/crypto-zombies/src/zombie_feeding.rs +++ b/contracts/examples/crypto-zombies/src/zombie_feeding.rs @@ -1,33 +1,6 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; -use crate::{storage, zombie_factory, zombie_helper}; -use crypto_kitties_proxy::Kitty; - -mod crypto_kitties_proxy { - multiversx_sc::imports!(); - multiversx_sc::derive_imports!(); - - #[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] - pub struct Kitty { - pub is_gestating: bool, - pub is_ready: bool, - pub cooldown_index: u64, - pub next_action_at: u64, - pub siring_with_id: u64, - pub birth_time: u64, - pub matron_id: u64, - pub sire_id: u64, - pub generation: u64, - pub genes: u64, - } - - #[multiversx_sc::proxy] - pub trait CryptoKitties { - #[endpoint] - fn get_kitty(&self, id: usize) -> Kitty; - } -} +use crate::{kitty_obj::Kitty, kitty_ownership_proxy, storage, zombie_factory, zombie_helper}; #[multiversx_sc::module] pub trait ZombieFeeding: @@ -70,7 +43,7 @@ pub trait ZombieFeeding: ) { match result { ManagedAsyncCallResult::Ok(kitty) => { - let kitty_dna = kitty.genes; + let kitty_dna = kitty.genes.get_as_u64(); self.feed_and_multiply(zombie_id, kitty_dna, ManagedBuffer::from(b"kitty")); }, ManagedAsyncCallResult::Err(_) => {}, @@ -78,14 +51,13 @@ pub trait ZombieFeeding: } #[endpoint] - fn feed_on_kitty(&self, zombie_id: usize, kitty_id: usize) { + 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) - .get_kitty(kitty_id) - .async_call() - .with_callback(self.callbacks().get_kitty_callback(zombie_id)) - .call_and_exit(); + self.tx() + .to(&crypto_kitties_sc_address) + .typed(kitty_ownership_proxy::KittyOwnershipProxy) + .get_kitty_by_id_endpoint(kitty_id) + .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 20d1263bf3..c38edc9ea0 100644 --- a/contracts/examples/crypto-zombies/src/zombie_helper.rs +++ b/contracts/examples/crypto-zombies/src/zombie_helper.rs @@ -1,4 +1,4 @@ -multiversx_sc::imports!(); +use multiversx_sc::imports::*; use crate::storage; @@ -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 d2c4310c96..639b402b18 100755 --- a/contracts/examples/crypto-zombies/wasm/Cargo.lock +++ b/contracts/examples/crypto-zombies/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "crypto-zombies" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/crypto-zombies/wasm/Cargo.toml b/contracts/examples/crypto-zombies/wasm/Cargo.toml index f73d9e26a6..8073db84b3 100644 --- a/contracts/examples/crypto-zombies/wasm/Cargo.toml +++ b/contracts/examples/crypto-zombies/wasm/Cargo.toml @@ -1,24 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "crypto-zombies-wasm" version = "0.0.0" -authors = ["Alin Cruceat "] 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.crypto-zombies] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 b6dcbb65cf..932b3865a6 100644 --- a/contracts/examples/crypto-zombies/wasm/src/lib.rs +++ b/contracts/examples/crypto-zombies/wasm/src/lib.rs @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 +// Upgrade: 1 // Endpoints: 17 // Async Callback: 1 -// Total number of exported functions: 19 +// Total number of exported functions: 20 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,13 +19,14 @@ multiversx_sc_wasm_adapter::endpoints! { crypto_zombies ( init => init + upgrade => upgrade set_crypto_kitties_sc_address => set_crypto_kitties_sc_address generate_random_dna => generate_random_dna create_random_zombie => create_random_zombie 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 c7e5fd954e..67a03c685d 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/digital-cash/meta/Cargo.toml b/contracts/examples/digital-cash/meta/Cargo.toml index 991e62aa8c..1e9dd45feb 100644 --- a/contracts/examples/digital-cash/meta/Cargo.toml +++ b/contracts/examples/digital-cash/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.digital-cash] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/claim-egld.scen.json b/contracts/examples/digital-cash/scenarios/claim-egld.scen.json index c9c70411c9..b14fefe155 100644 --- a/contracts/examples/digital-cash/scenarios/claim-egld.scen.json +++ b/contracts/examples/digital-cash/scenarios/claim-egld.scen.json @@ -169,7 +169,7 @@ "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1", "str:collectedFees|nested:str:EGLD": "10" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", diff --git a/contracts/examples/digital-cash/scenarios/claim-esdt.scen.json b/contracts/examples/digital-cash/scenarios/claim-esdt.scen.json index 8c0931423b..f7db9967d0 100644 --- a/contracts/examples/digital-cash/scenarios/claim-esdt.scen.json +++ b/contracts/examples/digital-cash/scenarios/claim-esdt.scen.json @@ -168,7 +168,7 @@ "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1", "str:collectedFees|nested:str:EGLD": "10" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "7", diff --git a/contracts/examples/digital-cash/scenarios/claim-fees.scen.json b/contracts/examples/digital-cash/scenarios/claim-fees.scen.json index 78611be938..35fd7afa2b 100644 --- a/contracts/examples/digital-cash/scenarios/claim-fees.scen.json +++ b/contracts/examples/digital-cash/scenarios/claim-fees.scen.json @@ -12,6 +12,7 @@ "from": "address:acc2", "to": "sc:the_digital_cash_contract", "function": "claimFees", + "arguments": [], "gasLimit": "500,000,000", "gasPrice": "0" }, @@ -41,6 +42,7 @@ "from": "address:digital_cash_owner_address", "to": "sc:the_digital_cash_contract", "function": "claimFees", + "arguments": [], "gasLimit": "500,000,000", "gasPrice": "0" }, @@ -103,7 +105,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", diff --git a/contracts/examples/digital-cash/scenarios/claim-multi-esdt.scen.json b/contracts/examples/digital-cash/scenarios/claim-multi-esdt.scen.json index 301d037ab7..df27c31521 100644 --- a/contracts/examples/digital-cash/scenarios/claim-multi-esdt.scen.json +++ b/contracts/examples/digital-cash/scenarios/claim-multi-esdt.scen.json @@ -166,7 +166,7 @@ "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1", "str:collectedFees|nested:str:EGLD": "30" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", diff --git a/contracts/examples/digital-cash/scenarios/forward.scen.json b/contracts/examples/digital-cash/scenarios/forward.scen.json index 44721e7f2f..ab5a4443d7 100644 --- a/contracts/examples/digital-cash/scenarios/forward.scen.json +++ b/contracts/examples/digital-cash/scenarios/forward.scen.json @@ -11,7 +11,6 @@ "tx": { "from": "address:acc2", "to": "sc:the_digital_cash_contract", - "egldValue": "0", "function": "forward", "arguments": [ "0xdb474a3a065d3f0c0a62ae680ef6435e48eb482899d2ae30ff7a3a4b0ef19c60", @@ -59,7 +58,6 @@ "tx": { "from": "address:acc2", "to": "sc:the_digital_cash_contract", - "egldValue": "0", "function": "forward", "arguments": [ "0xdb474a3a065d3f0c0a62ae680ef6435e48eb482899d2ae30ff7a3a4b0ef19c60", @@ -106,8 +104,8 @@ "tx": { "from": "address:acc2", "to": "sc:the_digital_cash_contract", - "function": "forward", "egldValue": "500", + "function": "forward", "arguments": [ "0x885532043a061e0c779e4064b85193f72cffd22c5bcc208c209128e60f21bf0d", "0x885532043a061e0c779e4064b85193f72cffd22c5bcc208c209128e60f21bf0d", @@ -131,8 +129,8 @@ "tx": { "from": "address:acc2", "to": "sc:the_digital_cash_contract", - "function": "forward", "egldValue": "500", + "function": "forward", "arguments": [ "0x885532043a061e0c779e4064b85193f72cffd22c5bcc208c209128e60f21bf0d", "0x8dc17613990e9b7476401a36d112d1a4d31190dec21e7e9a3c933872a27613ee", @@ -216,7 +214,7 @@ "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1", "str:collectedFees|nested:str:EGLD": "40" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", diff --git a/contracts/examples/digital-cash/scenarios/fund-egld-and-esdt.scen.json b/contracts/examples/digital-cash/scenarios/fund-egld-and-esdt.scen.json index b30b5a2b97..594a3339ed 100644 --- a/contracts/examples/digital-cash/scenarios/fund-egld-and-esdt.scen.json +++ b/contracts/examples/digital-cash/scenarios/fund-egld-and-esdt.scen.json @@ -106,7 +106,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", @@ -237,7 +237,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", @@ -458,7 +458,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", diff --git a/contracts/examples/digital-cash/scenarios/pay-fee-and-fund-egld.scen.json b/contracts/examples/digital-cash/scenarios/pay-fee-and-fund-egld.scen.json index 83e5d386e5..4c66d33df3 100644 --- a/contracts/examples/digital-cash/scenarios/pay-fee-and-fund-egld.scen.json +++ b/contracts/examples/digital-cash/scenarios/pay-fee-and-fund-egld.scen.json @@ -90,7 +90,7 @@ "str:allTimeFeeTokens|str:.index|nested:str:CASHTOKEN-778899": "2", "str:allTimeFeeTokens|str:.index|nested:str:ESDT-778899": "3" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "0", diff --git a/contracts/examples/digital-cash/scenarios/pay-fee-and-fund-esdt.scen.json b/contracts/examples/digital-cash/scenarios/pay-fee-and-fund-esdt.scen.json index 6848eb9cd1..6786587fe8 100644 --- a/contracts/examples/digital-cash/scenarios/pay-fee-and-fund-esdt.scen.json +++ b/contracts/examples/digital-cash/scenarios/pay-fee-and-fund-esdt.scen.json @@ -11,7 +11,6 @@ "tx": { "from": "address:acc3", "to": "sc:the_digital_cash_contract", - "function": "payFeeAndFundESDT", "esdtValue": [ { "tokenIdentifier": "str:CASHTOKEN-445566", @@ -22,6 +21,7 @@ "value": "50" } ], + "function": "payFeeAndFundESDT", "arguments": [ "0xdb474a3a065d3f0c0a62ae680ef6435e48eb482899d2ae30ff7a3a4b0ef19c60", "u64:100" @@ -44,7 +44,6 @@ "tx": { "from": "address:acc3", "to": "sc:the_digital_cash_contract", - "function": "payFeeAndFundESDT", "esdtValue": [ { "tokenIdentifier": "str:CASHTOKEN-778899", @@ -55,6 +54,7 @@ "value": "50" } ], + "function": "payFeeAndFundESDT", "arguments": [ "0xdb474a3a065d3f0c0a62ae680ef6435e48eb482899d2ae30ff7a3a4b0ef19c60", "u64:100" @@ -112,7 +112,7 @@ "str:allTimeFeeTokens|str:.index|nested:str:CASHTOKEN-778899": "2", "str:allTimeFeeTokens|str:.index|nested:str:ESDT-778899": "3" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "0", diff --git a/contracts/examples/digital-cash/scenarios/set-accounts.scen.json b/contracts/examples/digital-cash/scenarios/set-accounts.scen.json index f010d40595..550268266b 100644 --- a/contracts/examples/digital-cash/scenarios/set-accounts.scen.json +++ b/contracts/examples/digital-cash/scenarios/set-accounts.scen.json @@ -42,7 +42,7 @@ "id": "deploy", "tx": { "from": "address:digital_cash_owner_address", - "contractCode": "file:../output/digital-cash.wasm", + "contractCode": "mxsc:../output/digital-cash.mxsc.json", "arguments": [ "10", "str:EGLD" @@ -72,7 +72,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "0", diff --git a/contracts/examples/digital-cash/scenarios/whitelist-blacklist-fee-tokens.scen.json b/contracts/examples/digital-cash/scenarios/whitelist-blacklist-fee-tokens.scen.json index bd9f1afd1a..f88f0e0073 100644 --- a/contracts/examples/digital-cash/scenarios/whitelist-blacklist-fee-tokens.scen.json +++ b/contracts/examples/digital-cash/scenarios/whitelist-blacklist-fee-tokens.scen.json @@ -140,7 +140,7 @@ "str:allTimeFeeTokens|str:.index|nested:str:CASHTOKEN-778899": "2", "str:allTimeFeeTokens|str:.index|nested:str:ESDT-778899": "3" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "0", diff --git a/contracts/examples/digital-cash/scenarios/withdraw-egld.scen.json b/contracts/examples/digital-cash/scenarios/withdraw-egld.scen.json index 5c4182a164..81b93b41fb 100644 --- a/contracts/examples/digital-cash/scenarios/withdraw-egld.scen.json +++ b/contracts/examples/digital-cash/scenarios/withdraw-egld.scen.json @@ -93,7 +93,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "4", @@ -230,7 +230,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "6", diff --git a/contracts/examples/digital-cash/scenarios/withdraw-esdt.scen.json b/contracts/examples/digital-cash/scenarios/withdraw-esdt.scen.json index 07d7c821e4..2a1d2743a0 100644 --- a/contracts/examples/digital-cash/scenarios/withdraw-esdt.scen.json +++ b/contracts/examples/digital-cash/scenarios/withdraw-esdt.scen.json @@ -93,7 +93,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", @@ -229,7 +229,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", diff --git a/contracts/examples/digital-cash/scenarios/withdraw-multi-esdt.scen.json b/contracts/examples/digital-cash/scenarios/withdraw-multi-esdt.scen.json index fae381c069..2e0ee98a3c 100644 --- a/contracts/examples/digital-cash/scenarios/withdraw-multi-esdt.scen.json +++ b/contracts/examples/digital-cash/scenarios/withdraw-multi-esdt.scen.json @@ -93,7 +93,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", @@ -227,7 +227,7 @@ "str:allTimeFeeTokens|str:.item|u32:1": "str:EGLD", "str:allTimeFeeTokens|str:.index|nested:str:EGLD": "1" }, - "code": "file:../output/digital-cash.wasm" + "code": "mxsc:../output/digital-cash.mxsc.json" }, "address:acc1": { "nonce": "3", diff --git a/contracts/examples/digital-cash/src/deposit_info.rs b/contracts/examples/digital-cash/src/deposit_info.rs index 2838d5de84..daef136feb 100644 --- a/contracts/examples/digital-cash/src/deposit_info.rs +++ b/contracts/examples/digital-cash/src/deposit_info.rs @@ -1,7 +1,7 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +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>, @@ -25,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 c1d6ac4af2..c1d96c9132 100644 --- a/contracts/examples/digital-cash/src/digital_cash.rs +++ b/contracts/examples/digital-cash/src/digital_cash.rs @@ -1,11 +1,11 @@ #![no_std] #![allow(unused_attributes)] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; mod constants; mod deposit_info; +pub mod digital_cash_proxy; mod helpers; mod pay_fee_and_fund; mod signature_operations; @@ -55,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 c9bb1ea0aa..aa5c4efadc 100644 --- a/contracts/examples/digital-cash/src/helpers.rs +++ b/contracts/examples/digital-cash/src/helpers.rs @@ -1,4 +1,4 @@ -multiversx_sc::imports!(); +use multiversx_sc::imports::*; use crate::{ constants::*, @@ -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/pay_fee_and_fund.rs b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs index 246ffefb6b..45e913c51d 100644 --- a/contracts/examples/digital-cash/src/pay_fee_and_fund.rs +++ b/contracts/examples/digital-cash/src/pay_fee_and_fund.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; use crate::{constants::*, helpers, storage}; diff --git a/contracts/examples/digital-cash/src/signature_operations.rs b/contracts/examples/digital-cash/src/signature_operations.rs index f02c1c7cb8..9c68951f05 100644 --- a/contracts/examples/digital-cash/src/signature_operations.rs +++ b/contracts/examples/digital-cash/src/signature_operations.rs @@ -1,9 +1,8 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; use crate::{constants::*, helpers, storage}; -pub use multiversx_sc::api::{ED25519_KEY_BYTE_LEN, ED25519_SIGNATURE_BYTE_LEN}; +pub use multiversx_sc::api::ED25519_SIGNATURE_BYTE_LEN; #[multiversx_sc::module] pub trait SignatureOperationsModule: storage::StorageModule + helpers::HelpersModule { @@ -34,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(); } } @@ -72,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/src/storage.rs b/contracts/examples/digital-cash/src/storage.rs index eb0fbef93d..2e18503ccd 100644 --- a/contracts/examples/digital-cash/src/storage.rs +++ b/contracts/examples/digital-cash/src/storage.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; use crate::deposit_info::*; 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 61ab7ff699..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,10 +2,9 @@ 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( - "file:output/digital-cash.wasm", + "mxsc:output/digital-cash.mxsc.json", digital_cash::ContractBuilder, ); blockchain diff --git a/contracts/examples/digital-cash/wasm/Cargo.lock b/contracts/examples/digital-cash/wasm/Cargo.lock index 189bab2640..34a22b35a1 100644 --- a/contracts/examples/digital-cash/wasm/Cargo.lock +++ b/contracts/examples/digital-cash/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "digital-cash" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/digital-cash/wasm/Cargo.toml b/contracts/examples/digital-cash/wasm/Cargo.toml index a7380c1009..efb1210508 100644 --- a/contracts/examples/digital-cash/wasm/Cargo.toml +++ b/contracts/examples/digital-cash/wasm/Cargo.toml @@ -1,17 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "digital-cash-wasm" version = "0.0.0" -authors = ["Valentin Craciun"] edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = [ ".",] - -[dev-dependencies] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -19,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.digital-cash] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/digital-cash/wasm/src/lib.rs b/contracts/examples/digital-cash/wasm/src/lib.rs index 4225446734..b010630ba6 100644 --- a/contracts/examples/digital-cash/wasm/src/lib.rs +++ b/contracts/examples/digital-cash/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 659973f49e..741783f0e3 100644 --- a/contracts/examples/empty/Cargo.toml +++ b/contracts/examples/empty/Cargo.toml @@ -9,12 +9,12 @@ publish = false path = "src/empty.rs" [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" [dev-dependencies] -num-bigint = "0.4.2" +num-bigint = "0.4" diff --git a/contracts/examples/empty/meta/Cargo.toml b/contracts/examples/empty/meta/Cargo.toml index 79ef16718a..f89d218375 100644 --- a/contracts/examples/empty/meta/Cargo.toml +++ b/contracts/examples/empty/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.empty] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/mxsc-template.toml b/contracts/examples/empty/mxsc-template.toml index 441addd7b6..ca202e5c31 100644 --- a/contracts/examples/empty/mxsc-template.toml +++ b/contracts/examples/empty/mxsc-template.toml @@ -12,7 +12,6 @@ files_include = [ "scenarios", "src", "tests", - "wasm/Cargo.toml", "Cargo.toml", "multiversx.json", ] diff --git a/contracts/examples/empty/scenarios/empty.scen.json b/contracts/examples/empty/scenarios/empty.scen.json index 486088b592..2c9ab7d083 100644 --- a/contracts/examples/empty/scenarios/empty.scen.json +++ b/contracts/examples/empty/scenarios/empty.scen.json @@ -22,7 +22,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/empty.wasm", + "contractCode": "mxsc:../output/empty.mxsc.json", "arguments": [], "gasLimit": "5,000,000", "gasPrice": "0" diff --git a/contracts/examples/empty/src/empty.rs b/contracts/examples/empty/src/empty.rs index 05c2ddb437..81353a08d9 100644 --- a/contracts/examples/empty/src/empty.rs +++ b/contracts/examples/empty/src/empty.rs @@ -1,10 +1,14 @@ #![no_std] -multiversx_sc::imports!(); +#[allow(unused_imports)] +use multiversx_sc::imports::*; /// An empty contract. To be used as a template when starting a new contract from scratch. #[multiversx_sc::contract] pub trait EmptyContract { #[init] fn init(&self) {} + + #[upgrade] + fn upgrade(&self) {} } diff --git a/contracts/examples/empty/tests/empty_scenario_rs_test.rs b/contracts/examples/empty/tests/empty_scenario_rs_test.rs index a4e9d0166c..7f84325dbe 100644 --- a/contracts/examples/empty/tests/empty_scenario_rs_test.rs +++ b/contracts/examples/empty/tests/empty_scenario_rs_test.rs @@ -2,9 +2,8 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/empty"); - blockchain.register_contract("file:output/empty.wasm", empty::ContractBuilder); + 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 a70ccc1183..f154541f76 100755 --- a/contracts/examples/empty/wasm/Cargo.lock +++ b/contracts/examples/empty/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "empty" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/empty/wasm/Cargo.toml b/contracts/examples/empty/wasm/Cargo.toml index 2e5736423f..b9c014aefc 100644 --- a/contracts/examples/empty/wasm/Cargo.toml +++ b/contracts/examples/empty/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "empty-wasm" version = "0.0.0" @@ -13,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.empty] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/empty/wasm/src/lib.rs b/contracts/examples/empty/wasm/src/lib.rs index 0f1e581eab..2d1910c9bd 100644 --- a/contracts/examples/empty/wasm/src/lib.rs +++ b/contracts/examples/empty/wasm/src/lib.rs @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 +// Upgrade: 1 // Endpoints: 0 // Async Callback (empty): 1 -// Total number of exported functions: 2 +// Total number of exported functions: 3 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { empty ( init => init + upgrade => upgrade ) } diff --git a/contracts/examples/esdt-transfer-with-fee/Cargo.toml b/contracts/examples/esdt-transfer-with-fee/Cargo.toml index dc0fb8ed37..dce8934c43 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 d59bb9fb1f..37dd4e6a63 100644 --- a/contracts/examples/esdt-transfer-with-fee/meta/Cargo.toml +++ b/contracts/examples/esdt-transfer-with-fee/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.esdt-transfer-with-fee] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/claim.scen.json b/contracts/examples/esdt-transfer-with-fee/scenarios/claim.scen.json index 0dcf1708c7..885ca9a4c0 100644 --- a/contracts/examples/esdt-transfer-with-fee/scenarios/claim.scen.json +++ b/contracts/examples/esdt-transfer-with-fee/scenarios/claim.scen.json @@ -81,7 +81,7 @@ "str:token_fee|nested:str:MFNFT-567890": "u8:1|nested:str:USDC-aaaaaa|u64:0|biguint:5", "str:token_fee|nested:str:WEGLD-012345": "u8:1|nested:str:USDC-aaaaaa|u64:0|biguint:10" }, - "code": "file:../output/esdt-transfer-with-fee.wasm", + "code": "mxsc:../output/esdt-transfer-with-fee.mxsc.json", "owner": "address:owner" } } diff --git a/contracts/examples/esdt-transfer-with-fee/scenarios/deploy.scen.json b/contracts/examples/esdt-transfer-with-fee/scenarios/deploy.scen.json index 6f18b1cf45..ac39e38400 100644 --- a/contracts/examples/esdt-transfer-with-fee/scenarios/deploy.scen.json +++ b/contracts/examples/esdt-transfer-with-fee/scenarios/deploy.scen.json @@ -54,7 +54,7 @@ "id": "1", "tx": { "from": "address:owner", - "contractCode": "file:../output/esdt-transfer-with-fee.wasm", + "contractCode": "mxsc:../output/esdt-transfer-with-fee.mxsc.json", "arguments": [], "gasLimit": "5,000,000", "gasPrice": "0" @@ -109,7 +109,7 @@ "sc:esdt-transfer-with-fee": { "nonce": "0", "storage": {}, - "code": "file:../output/esdt-transfer-with-fee.wasm", + "code": "mxsc:../output/esdt-transfer-with-fee.mxsc.json", "owner": "address:owner" } } diff --git a/contracts/examples/esdt-transfer-with-fee/scenarios/setup_fees_and_transfer.scen.json b/contracts/examples/esdt-transfer-with-fee/scenarios/setup_fees_and_transfer.scen.json index 018dda412f..0b4738d940 100644 --- a/contracts/examples/esdt-transfer-with-fee/scenarios/setup_fees_and_transfer.scen.json +++ b/contracts/examples/esdt-transfer-with-fee/scenarios/setup_fees_and_transfer.scen.json @@ -306,7 +306,7 @@ "str:paid_fees.value|u32:1": "nested:str:USDC-aaaaaa|u64:0", "str:paid_fees.mapped|nested:str:USDC-aaaaaa|u64:0": "13" }, - "code": "file:../output/esdt-transfer-with-fee.wasm", + "code": "mxsc:../output/esdt-transfer-with-fee.mxsc.json", "owner": "address:owner" } } 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 85abae23b6..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 @@ -3,7 +3,7 @@ mod fee; use fee::*; -multiversx_sc::imports!(); +use multiversx_sc::imports::*; #[multiversx_sc::contract] pub trait EsdtTransferWithFee { #[init] @@ -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/src/fee.rs b/contracts/examples/esdt-transfer-with-fee/src/fee.rs index fa53190af7..67c88d8742 100644 --- a/contracts/examples/esdt-transfer-with-fee/src/fee.rs +++ b/contracts/examples/esdt-transfer-with-fee/src/fee.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; pub(crate) const PERCENTAGE_DIVISOR: u32 = 10_000; // dividing the percentage fee by this number will result in a 2 decimal percentage 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 4dd601212a..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,10 +2,9 @@ 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( - "file:output/esdt-transfer-with-fee.wasm", + "mxsc:output/esdt-transfer-with-fee.mxsc.json", esdt_transfer_with_fee::ContractBuilder, ); blockchain diff --git a/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.lock b/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.lock index 10f2d10e7a..2783ad6bc8 100644 --- a/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.lock +++ b/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 0995871399..b5fb86309a 100644 --- a/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.toml +++ b/contracts/examples/esdt-transfer-with-fee/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "esdt-transfer-with-fee-wasm" version = "0.0.0" -authors = ["Alin Cruceat "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.esdt-transfer-with-fee] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 62d43c3c4f..cd2ccdbd51 100644 --- a/contracts/examples/esdt-transfer-with-fee/wasm/src/lib.rs +++ b/contracts/examples/esdt-transfer-with-fee/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 5dda7598f5..9eb6bf090e 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/factorial/meta/Cargo.toml b/contracts/examples/factorial/meta/Cargo.toml index b11dd1b6a6..8471feaaef 100644 --- a/contracts/examples/factorial/meta/Cargo.toml +++ b/contracts/examples/factorial/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.factorial] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/factorial.scen.json b/contracts/examples/factorial/scenarios/factorial.scen.json index 343eab0242..37a3a7e230 100644 --- a/contracts/examples/factorial/scenarios/factorial.scen.json +++ b/contracts/examples/factorial/scenarios/factorial.scen.json @@ -9,7 +9,7 @@ "balance": "0" }, "sc:factorial": { - "code": "file:../output/factorial.wasm" + "code": "mxsc:../output/factorial.mxsc.json" } } }, diff --git a/contracts/examples/factorial/src/factorial.rs b/contracts/examples/factorial/src/factorial.rs index 27771cbf1a..ac5c76427c 100644 --- a/contracts/examples/factorial/src/factorial.rs +++ b/contracts/examples/factorial/src/factorial.rs @@ -1,12 +1,16 @@ #![no_std] +#![allow(unused_imports)] -multiversx_sc::imports!(); +use multiversx_sc::imports::*; #[multiversx_sc::contract] pub trait Factorial { #[init] fn init(&self) {} + #[upgrade] + fn upgrade(&self) {} + #[endpoint] fn factorial(&self, value: BigUint) -> BigUint { let one = BigUint::from(1u32); diff --git a/contracts/examples/factorial/tests/factorial_scenario_rs_test.rs b/contracts/examples/factorial/tests/factorial_scenario_rs_test.rs index 9e192fbb3a..679c1a2d92 100644 --- a/contracts/examples/factorial/tests/factorial_scenario_rs_test.rs +++ b/contracts/examples/factorial/tests/factorial_scenario_rs_test.rs @@ -2,9 +2,11 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/examples/factorial"); - blockchain.register_contract("file:output/factorial.wasm", factorial::ContractBuilder); + blockchain.register_contract( + "mxsc:output/factorial.mxsc.json", + factorial::ContractBuilder, + ); blockchain } diff --git a/contracts/examples/factorial/wasm/Cargo.lock b/contracts/examples/factorial/wasm/Cargo.lock index de78a7b2fb..132e4a6fd5 100755 --- a/contracts/examples/factorial/wasm/Cargo.lock +++ b/contracts/examples/factorial/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/factorial/wasm/Cargo.toml b/contracts/examples/factorial/wasm/Cargo.toml index e18bc372c5..408adf31fc 100644 --- a/contracts/examples/factorial/wasm/Cargo.toml +++ b/contracts/examples/factorial/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "factorial-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.factorial] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/factorial/wasm/src/lib.rs b/contracts/examples/factorial/wasm/src/lib.rs index 9f564de44b..5bf5db395c 100644 --- a/contracts/examples/factorial/wasm/src/lib.rs +++ b/contracts/examples/factorial/wasm/src/lib.rs @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 +// Upgrade: 1 // Endpoints: 1 // Async Callback (empty): 1 -// Total number of exported functions: 3 +// Total number of exported functions: 4 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { factorial ( init => init + upgrade => upgrade factorial => factorial ) } diff --git a/contracts/examples/fractional-nfts/Cargo.toml b/contracts/examples/fractional-nfts/Cargo.toml index 1282388c4e..cd1a611e6c 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/fractional-nfts/meta/Cargo.toml b/contracts/examples/fractional-nfts/meta/Cargo.toml index 6de05d00db..99cd6705f3 100644 --- a/contracts/examples/fractional-nfts/meta/Cargo.toml +++ b/contracts/examples/fractional-nfts/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.fractional-nfts] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 a429cfad10..16f1c87aed 100644 --- a/contracts/examples/fractional-nfts/src/fractional_nfts.rs +++ b/contracts/examples/fractional-nfts/src/fractional_nfts.rs @@ -1,10 +1,11 @@ #![no_std] -multiversx_sc::imports!(); +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 { - 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 4837ee6fe1..e6ebdba4f2 100644 --- a/contracts/examples/fractional-nfts/src/fractional_uri_info.rs +++ b/contracts/examples/fractional-nfts/src/fractional_uri_info.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; use multiversx_sc::contract_base::ManagedSerializer; @@ -27,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 aacd07f0fa..37428b3918 100644 --- a/contracts/examples/fractional-nfts/wasm/Cargo.lock +++ b/contracts/examples/fractional-nfts/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -60,15 +42,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -77,61 +50,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/fractional-nfts/wasm/Cargo.toml b/contracts/examples/fractional-nfts/wasm/Cargo.toml index 312b335536..aca01461f3 100644 --- a/contracts/examples/fractional-nfts/wasm/Cargo.toml +++ b/contracts/examples/fractional-nfts/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "fractional-nfts-wasm" version = "0.0.0" -authors = ["Claudiu-Marcel Bruda "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.fractional-nfts] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 59e4a11f68..567d172c78 100644 --- a/contracts/examples/fractional-nfts/wasm/src/lib.rs +++ b/contracts/examples/fractional-nfts/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 950e8a8f9c..7239b8ea00 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/lottery-esdt/meta/Cargo.toml b/contracts/examples/lottery-esdt/meta/Cargo.toml index 0720fcc97f..5a0cc21f7b 100644 --- a/contracts/examples/lottery-esdt/meta/Cargo.toml +++ b/contracts/examples/lottery-esdt/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.lottery-esdt] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/buy-all-tickets-different-accounts.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-all-tickets-different-accounts.scen.json index eec0f7bb92..97ac4a1238 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-all-tickets-different-accounts.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-all-tickets-different-accounts.scen.json @@ -238,7 +238,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc5": "1", "+": "" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-more-tickets-than-allowed.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-more-tickets-than-allowed.scen.json index 9c82182a02..0a4db9473b 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-more-tickets-than-allowed.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-more-tickets-than-allowed.scen.json @@ -87,7 +87,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1", "+": "" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-deadline.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-deadline.scen.json index 86aeab033f..275c1ebbdb 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-deadline.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-deadline.scen.json @@ -89,7 +89,7 @@ "str:ticketHolder|nested:str:lottery_name|str:.item|u32:1": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-determined-winner.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-determined-winner.scen.json index 737bd01226..f1fe7fbc7f 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-determined-winner.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-determined-winner.scen.json @@ -70,7 +70,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-sold-out.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-sold-out.scen.json index 0594b4dcec..9f3b23542b 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-sold-out.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket-after-sold-out.scen.json @@ -88,7 +88,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc2": "1" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket-all-options.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket-all-options.scen.json index 9c7914e0b5..181bb2b6ae 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket-all-options.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket-all-options.scen.json @@ -83,7 +83,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1", "+": "" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket-another-account.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket-another-account.scen.json index 6292d93494..98d9e37bf2 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket-another-account.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket-another-account.scen.json @@ -84,7 +84,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc2": "1" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket-not-on-whitelist.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket-not-on-whitelist.scen.json index 97f0d944b8..0fa30523d7 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket-not-on-whitelist.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket-not-on-whitelist.scen.json @@ -86,7 +86,7 @@ }, "+": "" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket-same-account.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket-same-account.scen.json index 9a3d95c114..485b5746ad 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket-same-account.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket-same-account.scen.json @@ -83,7 +83,7 @@ "str:ticketHolder|nested:str:lottery_name|str:.item|u32:2": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "2" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket-second-lottery.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket-second-lottery.scen.json index 3b5035a252..84b5e87b55 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket-second-lottery.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket-second-lottery.scen.json @@ -91,7 +91,7 @@ "str:ticketHolder|nested:str:lottery_$$$$|str:.item|u32:1": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_$$$$|address:acc1": "1" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket-wrong-fee.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket-wrong-fee.scen.json index 268b1ceb6d..f07677239e 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket-wrong-fee.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket-wrong-fee.scen.json @@ -80,7 +80,7 @@ "6-prize_pool": "biguint:0" } }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/buy-ticket.scen.json b/contracts/examples/lottery-esdt/scenarios/buy-ticket.scen.json index 65bba60c19..fec1ff000c 100644 --- a/contracts/examples/lottery-esdt/scenarios/buy-ticket.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/buy-ticket.scen.json @@ -82,7 +82,7 @@ "str:ticketHolder|nested:str:lottery_name|str:.item|u32:1": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/complex-prize-distribution.scen.json b/contracts/examples/lottery-esdt/scenarios/complex-prize-distribution.scen.json index 5a072f4b0b..60d817e065 100644 --- a/contracts/examples/lottery-esdt/scenarios/complex-prize-distribution.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/complex-prize-distribution.scen.json @@ -88,7 +88,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc9": "1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc10": "1" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } }, "currentBlockInfo": { @@ -177,7 +177,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/determine-winner-different-ticket-holders-winner-acc1.scen.json b/contracts/examples/lottery-esdt/scenarios/determine-winner-different-ticket-holders-winner-acc1.scen.json index 2d9ebeb70c..c835331c1a 100644 --- a/contracts/examples/lottery-esdt/scenarios/determine-winner-different-ticket-holders-winner-acc1.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/determine-winner-different-ticket-holders-winner-acc1.scen.json @@ -56,7 +56,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/determine-winner-early.scen.json b/contracts/examples/lottery-esdt/scenarios/determine-winner-early.scen.json index 70cd130eee..0fcad25ec0 100644 --- a/contracts/examples/lottery-esdt/scenarios/determine-winner-early.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/determine-winner-early.scen.json @@ -93,7 +93,7 @@ "str:ticketHolder|nested:str:lottery_name|str:.item|u32:1": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/determine-winner-same-ticket-holder.scen.json b/contracts/examples/lottery-esdt/scenarios/determine-winner-same-ticket-holder.scen.json index ef64ce5089..64f4d475ab 100644 --- a/contracts/examples/lottery-esdt/scenarios/determine-winner-same-ticket-holder.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/determine-winner-same-ticket-holder.scen.json @@ -57,7 +57,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/determine-winner-split-prize-pool.scen.json b/contracts/examples/lottery-esdt/scenarios/determine-winner-split-prize-pool.scen.json index be3997a7f7..7071e71f3c 100644 --- a/contracts/examples/lottery-esdt/scenarios/determine-winner-split-prize-pool.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/determine-winner-split-prize-pool.scen.json @@ -76,7 +76,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/lottery-init.scen.json b/contracts/examples/lottery-esdt/scenarios/lottery-init.scen.json index 145619b314..607af2736e 100644 --- a/contracts/examples/lottery-esdt/scenarios/lottery-init.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/lottery-init.scen.json @@ -31,7 +31,7 @@ "id": "deploy", "tx": { "from": "address:my_address", - "contractCode": "file:../output/lottery-esdt.wasm", + "contractCode": "mxsc:../output/lottery-esdt.mxsc.json", "arguments": [], "gasLimit": "1,000,000", "gasPrice": "0" @@ -65,7 +65,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/lottery-with-burn-percentage.scen.json b/contracts/examples/lottery-esdt/scenarios/lottery-with-burn-percentage.scen.json index cdbdf09ada..9d4876f388 100644 --- a/contracts/examples/lottery-esdt/scenarios/lottery-with-burn-percentage.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/lottery-with-burn-percentage.scen.json @@ -57,7 +57,7 @@ ] } }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } }, @@ -116,7 +116,7 @@ }, "str:burnPercentageForLottery|nested:str:lottery_name": "50" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" }, "+": "" } @@ -218,7 +218,7 @@ "str:ticketHolder|nested:str:lottery_name|str:.item|u32:2": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "2" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" }, "+": "" } @@ -270,7 +270,7 @@ "str:lotteryInfo|nested:str:lottery_name": "", "str:burnPercentageForLottery|nested:str:lottery_name": "0" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" }, "+": "" } diff --git a/contracts/examples/lottery-esdt/scenarios/start-after-announced-winner.scen.json b/contracts/examples/lottery-esdt/scenarios/start-after-announced-winner.scen.json index 07ee4f49ea..1d5e5c5a1f 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-after-announced-winner.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-after-announced-winner.scen.json @@ -68,7 +68,7 @@ "6-prize_pool": "biguint:0" } }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-all-options-bigger-whitelist.scen.json b/contracts/examples/lottery-esdt/scenarios/start-all-options-bigger-whitelist.scen.json index 038cbbde27..05fc6dcd4f 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-all-options-bigger-whitelist.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-all-options-bigger-whitelist.scen.json @@ -98,7 +98,7 @@ }, "+": "" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-alternative-function-name.scen.json b/contracts/examples/lottery-esdt/scenarios/start-alternative-function-name.scen.json index 5ae9cc595c..234780df81 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-alternative-function-name.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-alternative-function-name.scen.json @@ -65,7 +65,7 @@ "6-prize_pool": "biguint:0" } }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-fixed-deadline.scen.json b/contracts/examples/lottery-esdt/scenarios/start-fixed-deadline.scen.json index 5eb06a9a6e..8f0506c3be 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-fixed-deadline.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-fixed-deadline.scen.json @@ -65,7 +65,7 @@ "6-prize_pool": "biguint:0" } }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline-invalid-deadline.scen.json b/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline-invalid-deadline.scen.json index 0cf4cdfcd7..353bb29ad7 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline-invalid-deadline.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline-invalid-deadline.scen.json @@ -62,7 +62,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline-invalid-ticket-price-arg.scen.json b/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline-invalid-ticket-price-arg.scen.json index 430b093bcb..284841d451 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline-invalid-ticket-price-arg.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline-invalid-ticket-price-arg.scen.json @@ -56,7 +56,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline.scen.json b/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline.scen.json index 776dfeb4ae..583f7db682 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-limited-tickets-and-fixed-deadline.scen.json @@ -65,7 +65,7 @@ "6-prize_pool": "biguint:0" } }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-limited-tickets.scen.json b/contracts/examples/lottery-esdt/scenarios/start-limited-tickets.scen.json index caccbfd375..e1fbfd225e 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-limited-tickets.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-limited-tickets.scen.json @@ -65,7 +65,7 @@ "6-prize_pool": "biguint:0" } }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-second-lottery.scen.json b/contracts/examples/lottery-esdt/scenarios/start-second-lottery.scen.json index 397c8e0a43..ee6aa28aa8 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-second-lottery.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-second-lottery.scen.json @@ -74,7 +74,7 @@ "6-prize_pool": "biguint:0" } }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-with-all-options.scen.json b/contracts/examples/lottery-esdt/scenarios/start-with-all-options.scen.json index 0d3d5b4224..7c2ea2c097 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-with-all-options.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-with-all-options.scen.json @@ -66,7 +66,7 @@ }, "+": "" }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/scenarios/start-with-no-options.scen.json b/contracts/examples/lottery-esdt/scenarios/start-with-no-options.scen.json index 5acb7138ae..14c9deae2f 100644 --- a/contracts/examples/lottery-esdt/scenarios/start-with-no-options.scen.json +++ b/contracts/examples/lottery-esdt/scenarios/start-with-no-options.scen.json @@ -65,7 +65,7 @@ "6-prize_pool": "biguint:0" } }, - "code": "file:../output/lottery-esdt.wasm" + "code": "mxsc:../output/lottery-esdt.mxsc.json" } } } diff --git a/contracts/examples/lottery-esdt/src/lottery.rs b/contracts/examples/lottery-esdt/src/lottery.rs index 24a84bc6be..3c5d9040b1 100644 --- a/contracts/examples/lottery-esdt/src/lottery.rs +++ b/contracts/examples/lottery-esdt/src/lottery.rs @@ -1,6 +1,6 @@ #![no_std] -multiversx_sc::imports!(); +use multiversx_sc::imports::*; mod lottery_info; mod status; @@ -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/src/lottery_info.rs b/contracts/examples/lottery-esdt/src/lottery_info.rs index a7d7f32992..4ec2a6055f 100644 --- a/contracts/examples/lottery-esdt/src/lottery_info.rs +++ b/contracts/examples/lottery-esdt/src/lottery_info.rs @@ -3,9 +3,10 @@ use multiversx_sc::{ types::{BigUint, EgldOrEsdtTokenIdentifier, ManagedVec}, }; -multiversx_sc::derive_imports!(); +use multiversx_sc::derive_imports::*; -#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] pub struct LotteryInfo { pub token_identifier: EgldOrEsdtTokenIdentifier, pub ticket_price: BigUint, diff --git a/contracts/examples/lottery-esdt/src/status.rs b/contracts/examples/lottery-esdt/src/status.rs index 90eaa84ad0..6a932f2f70 100644 --- a/contracts/examples/lottery-esdt/src/status.rs +++ b/contracts/examples/lottery-esdt/src/status.rs @@ -1,6 +1,7 @@ -multiversx_sc::derive_imports!(); +use multiversx_sc::derive_imports::*; -#[derive(TopEncode, TopDecode, TypeAbi, PartialEq, Eq, Clone, Copy)] +#[type_abi] +#[derive(TopEncode, TopDecode, PartialEq, Eq, Clone, Copy)] pub enum Status { Inactive, Running, 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 31ebeb7a7f..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,10 +2,9 @@ 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( - "file:output/lottery-esdt.wasm", + "mxsc:output/lottery-esdt.mxsc.json", lottery_esdt::ContractBuilder, ); blockchain diff --git a/contracts/examples/lottery-esdt/wasm/Cargo.lock b/contracts/examples/lottery-esdt/wasm/Cargo.lock index 8c52242bb4..1793c18657 100755 --- a/contracts/examples/lottery-esdt/wasm/Cargo.lock +++ b/contracts/examples/lottery-esdt/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "lottery-esdt" @@ -82,48 +55,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/lottery-esdt/wasm/Cargo.toml b/contracts/examples/lottery-esdt/wasm/Cargo.toml index 8f592f6c05..b5dc083865 100644 --- a/contracts/examples/lottery-esdt/wasm/Cargo.toml +++ b/contracts/examples/lottery-esdt/wasm/Cargo.toml @@ -1,12 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "lottery-esdt-wasm" version = "0.0.0" -authors = [ "Dorin Iancu ",] edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.lottery-esdt] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 9e429a0c02..a1184cee72 100644 --- a/contracts/examples/lottery-esdt/wasm/src/lib.rs +++ b/contracts/examples/lottery-esdt/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 44c15ef962..0b3bc9301e 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" [dev-dependencies.adder] @@ -27,10 +27,10 @@ path = "../adder" path = "../factorial" [dev-dependencies.multiversx-wegld-swap-sc] -version = "0.44.0" +version = "0.53.0" path = "../../core/wegld-swap" [dev-dependencies] -num-bigint = "0.4.2" +num-bigint = "0.4" num-traits = "0.2" hex = "0.4" diff --git a/contracts/examples/multisig/interact/Cargo.toml b/contracts/examples/multisig/interact/Cargo.toml index 2cce4b8b83..7d6914bd60 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.44.0" +version = "0.53.0" path = "../../../../contracts/modules" [dependencies.multiversx-sc-snippets] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/snippets" [dependencies.multiversx-sc-scenario] -version = "=0.44.0" +version = "=0.53.0" path = "../../../../framework/scenario" + +[dependencies.multiversx-sc] +version = "=0.53.0" +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 454391679b..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,32 +76,32 @@ 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; let wallet_address = interactor.register_wallet(test_wallets::mike()); let multisig_code = BytesValue::interpret_from( - "file:../output/multisig.wasm", + "mxsc:../output/multisig.mxsc.json", &InterpreterContext::default(), ); 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 596c72b933..4cc6ee464c 100644 --- a/contracts/examples/multisig/meta/Cargo.toml +++ b/contracts/examples/multisig/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.multisig] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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..22ff09f5dd 100644 --- a/contracts/examples/multisig/sc-config.toml +++ b/contracts/examples/multisig/sc-config.toml @@ -14,3 +14,11 @@ name = "multisig-view" external-view = true add-unlabelled = false add-labels = ["multisig-external-view"] + +[[proxy]] +path = "src/multisig_proxy.rs" + +[[proxy]] +path = "src/multisig_view_proxy.rs" +add-unlabelled = false +add-labels = ["multisig-external-view"] diff --git a/contracts/examples/multisig/scenarios/call_other_shard-2.scen.json b/contracts/examples/multisig/scenarios/call_other_shard-2.scen.json index 70fc626664..edbd724bff 100644 --- a/contracts/examples/multisig/scenarios/call_other_shard-2.scen.json +++ b/contracts/examples/multisig/scenarios/call_other_shard-2.scen.json @@ -13,7 +13,7 @@ "accounts": { "sc:other-shard-2": { "shard": "1", - "code": "file:../output/multisig.wasm" + "code": "mxsc:../output/multisig.mxsc.json" } } }, diff --git a/contracts/examples/multisig/scenarios/deployAdder_err.scen.json b/contracts/examples/multisig/scenarios/deployAdder_err.scen.json index b0403cac7e..128b6ebb02 100644 --- a/contracts/examples/multisig/scenarios/deployAdder_err.scen.json +++ b/contracts/examples/multisig/scenarios/deployAdder_err.scen.json @@ -27,7 +27,7 @@ "arguments": [ "0", "sc:adder-code", - "0x0000" + "0x0100" ], "gasLimit": "200,000,000", "gasPrice": "0" diff --git a/contracts/examples/multisig/scenarios/deployAdder_then_call.scen.json b/contracts/examples/multisig/scenarios/deployAdder_then_call.scen.json index 8b5d118e62..5dabd7c4e1 100644 --- a/contracts/examples/multisig/scenarios/deployAdder_then_call.scen.json +++ b/contracts/examples/multisig/scenarios/deployAdder_then_call.scen.json @@ -26,7 +26,7 @@ "arguments": [ "0", "sc:adder-code", - "0x0000", + "0x0100", "1234" ], "gasLimit": "200,000,000", @@ -73,14 +73,14 @@ "1-discriminant": "0x07", "2-amount": "u32:0", "3-code_source": "sc:adder-code", - "4-code_metadata": "0x0000", + "4-code_metadata": "0x0100", "5-arguments": [ "u32:1", "u32:2|1234" ] } }, - "code": "file:../output/multisig.wasm" + "code": "mxsc:../output/multisig.mxsc.json" }, "+": "" } @@ -169,7 +169,7 @@ "storage": { "str:sum": "1234" }, - "code": "file:../test-contracts/adder.wasm" + "code": "mxsc:../test-contracts/adder.mxsc.json" }, "+": "" } @@ -307,7 +307,7 @@ "storage": { "str:sum": "2468" }, - "code": "file:../test-contracts/adder.wasm" + "code": "mxsc:../test-contracts/adder.mxsc.json" }, "+": "" } diff --git a/contracts/examples/multisig/scenarios/deployFactorial.scen.json b/contracts/examples/multisig/scenarios/deployFactorial.scen.json index 96bda0545f..56e9ad6891 100644 --- a/contracts/examples/multisig/scenarios/deployFactorial.scen.json +++ b/contracts/examples/multisig/scenarios/deployFactorial.scen.json @@ -26,7 +26,7 @@ "arguments": [ "0", "sc:factorial-code", - "0x0000" + "0x0100" ], "gasLimit": "200,000,000", "gasPrice": "0" @@ -72,11 +72,11 @@ "1-discriminant": "0x07", "2-amount": "u32:0", "3-code_source": "sc:factorial-code", - "4-code_metadata": "0x0000", + "4-code_metadata": "0x0100", "5-arguments": "u32:0" } }, - "code": "file:../output/multisig.wasm" + "code": "mxsc:../output/multisig.mxsc.json" }, "+": "" } @@ -184,13 +184,13 @@ "str:quorum": "2", "str:action_data.len": "3" }, - "code": "file:../output/multisig.wasm" + "code": "mxsc:../output/multisig.mxsc.json" }, "sc:factorial": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../test-contracts/factorial.wasm" + "code": "mxsc:../test-contracts/factorial.mxsc.json" }, "+": "" } diff --git a/contracts/examples/multisig/scenarios/deployOtherMultisig.scen.json b/contracts/examples/multisig/scenarios/deployOtherMultisig.scen.json index a180dd0ce5..7aeec33d47 100644 --- a/contracts/examples/multisig/scenarios/deployOtherMultisig.scen.json +++ b/contracts/examples/multisig/scenarios/deployOtherMultisig.scen.json @@ -26,7 +26,7 @@ "arguments": [ "0", "sc:multisig", - "0x0000", + "0x0100", "1", "address:paul" ], @@ -132,7 +132,7 @@ "str:num_board_members": "1", "str:quorum": "1" }, - "code": "file:../output/multisig.wasm" + "code": "mxsc:../output/multisig.mxsc.json" }, "+": "" } diff --git a/contracts/examples/multisig/scenarios/deploy_duplicate_bm.scen.json b/contracts/examples/multisig/scenarios/deploy_duplicate_bm.scen.json index b9f1f382b8..d7c85582a1 100644 --- a/contracts/examples/multisig/scenarios/deploy_duplicate_bm.scen.json +++ b/contracts/examples/multisig/scenarios/deploy_duplicate_bm.scen.json @@ -10,7 +10,7 @@ "id": "multisig-deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/multisig.wasm", + "contractCode": "mxsc:../output/multisig.mxsc.json", "arguments": [ "2", "address:alice", diff --git a/contracts/examples/multisig/scenarios/interactor_nft.scen.json b/contracts/examples/multisig/scenarios/interactor_nft.scen.json index f920c34a36..c2d0796fa5 100644 --- a/contracts/examples/multisig/scenarios/interactor_nft.scen.json +++ b/contracts/examples/multisig/scenarios/interactor_nft.scen.json @@ -139,7 +139,7 @@ "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", - "contractCode": "file:../output/multisig.wasm", + "contractCode": "mxsc:../output/multisig.mxsc.json", "arguments": [ "0x02", "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", diff --git a/contracts/examples/multisig/scenarios/interactor_nft_all_roles.scen.json b/contracts/examples/multisig/scenarios/interactor_nft_all_roles.scen.json index 8746f7fba9..d74848e97e 100644 --- a/contracts/examples/multisig/scenarios/interactor_nft_all_roles.scen.json +++ b/contracts/examples/multisig/scenarios/interactor_nft_all_roles.scen.json @@ -175,7 +175,7 @@ "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", - "contractCode": "file:../output/multisig.wasm", + "contractCode": "mxsc:../output/multisig.mxsc.json", "arguments": [ "0x02", "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", diff --git a/contracts/examples/multisig/scenarios/interactor_wegld.scen.json b/contracts/examples/multisig/scenarios/interactor_wegld.scen.json index ea9ed6ff68..15e9fc0386 100644 --- a/contracts/examples/multisig/scenarios/interactor_wegld.scen.json +++ b/contracts/examples/multisig/scenarios/interactor_wegld.scen.json @@ -11,8 +11,7 @@ "str:CAN-2abf4b": "1000", "str:CAN-6d39e6": "1000", "str:CAN-ac1592": "1000" - }, - "username": "" + } } } }, @@ -31,8 +30,7 @@ } ] } - }, - "username": "" + } } } }, @@ -41,8 +39,7 @@ "accounts": { "0xb13a017423c366caff8cecfb77a12610a130f4888134122c7937feae0d6d7d17": { "nonce": "179", - "balance": "7777023510140000000", - "username": "" + "balance": "7777023510140000000" } } }, @@ -56,8 +53,7 @@ "str:USDC-091bd3": "9997000000000", "str:XRF-079f0d": "999999805000000000000000000", "str:XUSDC-929b9b": "1000000000000000000000000" - }, - "username": "" + } } } }, @@ -69,14 +65,12 @@ "balance": "54039792195269569513", "esdt": { "str:WEGLD-6cf38e": { - "instances": [], "roles": [ "ESDTRoleLocalBurn", "ESDTRoleLocalMint" ] } }, - "username": "", "storage": { "0x7772617070656445676c64546f6b656e4964": "0x5745474c442d366366333865" }, @@ -96,10 +90,9 @@ }, { "step": "scDeploy", - "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", - "contractCode": "file:../output/multisig.wasm", + "contractCode": "mxsc:../output/multisig.mxsc.json", "arguments": [ "0x02", "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", @@ -107,16 +100,15 @@ "0xb13a017423c366caff8cecfb77a12610a130f4888134122c7937feae0d6d7d17", "0x3af8d9c9423b2577c6252722c1d90212a4111f7203f9744f76fcfa1d0a310033" ], - "gasLimit": "70,000,000", - "gasPrice": "" + "gasLimit": "70,000,000" }, "expect": { + "out": [], "status": "0" } }, { "step": "transfer", - "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -126,7 +118,6 @@ }, { "step": "scCall", - "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -136,13 +127,11 @@ "0xb1a2bc2ec50000", "0x7772617045676c64" ], - "gasLimit": "10,000,000", - "gasPrice": "" + "gasLimit": "10,000,000" } }, { "step": "scCall", - "id": "", "tx": { "from": "0xb2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -150,13 +139,11 @@ "arguments": [ "0x01" ], - "gasLimit": "15,000,000", - "gasPrice": "" + "gasLimit": "15,000,000" } }, { "step": "scCall", - "id": "", "tx": { "from": "0xb13a017423c366caff8cecfb77a12610a130f4888134122c7937feae0d6d7d17", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -164,13 +151,11 @@ "arguments": [ "0x01" ], - "gasLimit": "15,000,000", - "gasPrice": "" + "gasLimit": "15,000,000" } }, { "step": "scCall", - "id": "", "tx": { "from": "0x3af8d9c9423b2577c6252722c1d90212a4111f7203f9744f76fcfa1d0a310033", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -178,13 +163,11 @@ "arguments": [ "0x01" ], - "gasLimit": "15,000,000", - "gasPrice": "" + "gasLimit": "15,000,000" } }, { "step": "scCall", - "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -192,13 +175,11 @@ "arguments": [ "0x01" ], - "gasLimit": "15,000,000", - "gasPrice": "" + "gasLimit": "15,000,000" } }, { "step": "scCall", - "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -211,13 +192,11 @@ "0x58d15e17628000", "0x756e7772617045676c64" ], - "gasLimit": "10,000,000", - "gasPrice": "" + "gasLimit": "10,000,000" } }, { "step": "scCall", - "id": "", "tx": { "from": "0xb2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -225,13 +204,11 @@ "arguments": [ "0x02" ], - "gasLimit": "15,000,000", - "gasPrice": "" + "gasLimit": "15,000,000" } }, { "step": "scCall", - "id": "", "tx": { "from": "0xb13a017423c366caff8cecfb77a12610a130f4888134122c7937feae0d6d7d17", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -239,13 +216,11 @@ "arguments": [ "0x02" ], - "gasLimit": "15,000,000", - "gasPrice": "" + "gasLimit": "15,000,000" } }, { "step": "scCall", - "id": "", "tx": { "from": "0x3af8d9c9423b2577c6252722c1d90212a4111f7203f9744f76fcfa1d0a310033", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -253,13 +228,11 @@ "arguments": [ "0x02" ], - "gasLimit": "15,000,000", - "gasPrice": "" + "gasLimit": "15,000,000" } }, { "step": "scCall", - "id": "", "tx": { "from": "0xe32afedc904fe1939746ad973beb383563cf63642ba669b3040f9b9428a5ed60", "to": "0x0000000000000000050013ee5923031e866a442d3cb543820bf74178bc7fed60", @@ -267,8 +240,7 @@ "arguments": [ "0x02" ], - "gasLimit": "15,000,000", - "gasPrice": "" + "gasLimit": "15,000,000" } } ] diff --git a/contracts/examples/multisig/scenarios/remove_everyone.scen.json b/contracts/examples/multisig/scenarios/remove_everyone.scen.json index 604eb538e0..bb7ecdcf35 100644 --- a/contracts/examples/multisig/scenarios/remove_everyone.scen.json +++ b/contracts/examples/multisig/scenarios/remove_everyone.scen.json @@ -9,7 +9,7 @@ "id": "multisig-deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/multisig.wasm", + "contractCode": "mxsc:../output/multisig.mxsc.json", "arguments": [ "1", "address:alice" diff --git a/contracts/examples/multisig/scenarios/sendEsdt.scen.json b/contracts/examples/multisig/scenarios/sendEsdt.scen.json index cc93103dc2..e30ae951c8 100644 --- a/contracts/examples/multisig/scenarios/sendEsdt.scen.json +++ b/contracts/examples/multisig/scenarios/sendEsdt.scen.json @@ -192,7 +192,7 @@ "3", "10" ], - "data": "" + "data": "*" }, { "address": "sc:multisig", @@ -201,31 +201,28 @@ "str:FUNG-TOKEN", "0", "1000", - "address:esdt-owner" - ], - "data": "" - }, - { - "address": "sc:multisig", - "endpoint": "str:MultiESDTNFTTransfer", - "topics": [ "str:NFT-123456", "1", "1", + "str:SFT-456789", + "3", + "10", "address:esdt-owner" ], - "data": "" + "data": "*" }, { - "address": "sc:multisig", - "endpoint": "str:MultiESDTNFTTransfer", + "address": "address:esdt-owner", + "endpoint": "str:transferValueOnly", "topics": [ - "str:SFT-456789", - "3", - "10", - "address:esdt-owner" + "", + "sc:multisig" ], - "data": "" + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] }, { "address": "sc:multisig", @@ -233,7 +230,7 @@ "topics": [ "str:asyncCallSuccess" ], - "data": "" + "data": "*" } ], "gas": "*", diff --git a/contracts/examples/multisig/scenarios/steps/deploy.steps.json b/contracts/examples/multisig/scenarios/steps/deploy.steps.json index 3f3796ce4f..a317229c4e 100644 --- a/contracts/examples/multisig/scenarios/steps/deploy.steps.json +++ b/contracts/examples/multisig/scenarios/steps/deploy.steps.json @@ -7,7 +7,7 @@ "id": "multisig-deploy", "tx": { "from": "address:owner", - "contractCode": "file:../../output/multisig.wasm", + "contractCode": "mxsc:../../output/multisig.mxsc.json", "arguments": [ "2", "address:alice", @@ -30,7 +30,7 @@ "id": "multisig-view-deploy", "tx": { "from": "address:owner", - "contractCode": "file:../../output/multisig-view.wasm", + "contractCode": "mxsc:../../output/multisig-view.mxsc.json", "arguments": [ "sc:multisig" ], @@ -107,7 +107,7 @@ "str:num_board_members": "3", "str:quorum": "2" }, - "code": "file:../../output/multisig.wasm" + "code": "mxsc:../../output/multisig.mxsc.json" }, "+": "" } diff --git a/contracts/examples/multisig/scenarios/steps/deploy_minimal.steps.json b/contracts/examples/multisig/scenarios/steps/deploy_minimal.steps.json index fc8e846176..c8aeccebc9 100644 --- a/contracts/examples/multisig/scenarios/steps/deploy_minimal.steps.json +++ b/contracts/examples/multisig/scenarios/steps/deploy_minimal.steps.json @@ -5,7 +5,7 @@ "id": "multisig-deploy", "tx": { "from": "address:owner", - "contractCode": "file:../../output/multisig.wasm", + "contractCode": "mxsc:../../output/multisig.mxsc.json", "arguments": [ "0", "address:alice" diff --git a/contracts/examples/multisig/scenarios/steps/init_accounts.steps.json b/contracts/examples/multisig/scenarios/steps/init_accounts.steps.json index 2e16b4d454..d40648222c 100644 --- a/contracts/examples/multisig/scenarios/steps/init_accounts.steps.json +++ b/contracts/examples/multisig/scenarios/steps/init_accounts.steps.json @@ -30,10 +30,10 @@ "balance": "0" }, "sc:adder-code": { - "code": "file:../../test-contracts/adder.wasm" + "code": "mxsc:../../test-contracts/adder.mxsc.json" }, "sc:factorial-code": { - "code": "file:../../test-contracts/factorial.wasm" + "code": "mxsc:../../test-contracts/factorial.mxsc.json" } }, "newAddresses": [ diff --git a/contracts/examples/multisig/scenarios/upgrade.scen.json b/contracts/examples/multisig/scenarios/upgrade.scen.json index 89efaae490..549fb09e74 100644 --- a/contracts/examples/multisig/scenarios/upgrade.scen.json +++ b/contracts/examples/multisig/scenarios/upgrade.scen.json @@ -16,7 +16,7 @@ "sc:multisig-child", "0", "sc:adder-code", - "0x0000", + "0x0100", "1234" ], "gasLimit": "15,000,000", @@ -110,7 +110,7 @@ "str:quorum": "1", "str:sum": "1234" }, - "code": "file:../test-contracts/adder.wasm" + "code": "mxsc:../test-contracts/adder.mxsc.json" }, "+": "" } diff --git a/contracts/examples/multisig/scenarios/upgrade_from_source.scen.json b/contracts/examples/multisig/scenarios/upgrade_from_source.scen.json index f8d1d7a942..8b2e6dfb83 100644 --- a/contracts/examples/multisig/scenarios/upgrade_from_source.scen.json +++ b/contracts/examples/multisig/scenarios/upgrade_from_source.scen.json @@ -16,7 +16,7 @@ "sc:multisig-child", "0", "sc:multisig", - "0x0000", + "0x0100", "1", "address:alice" ], @@ -114,7 +114,7 @@ "str:quorum": "1", "str:sum": "1234" }, - "code": "file:../output/multisig.wasm" + "code": "mxsc:../output/multisig.mxsc.json" }, "+": "" } diff --git a/contracts/examples/multisig/src/action.rs b/contracts/examples/multisig/src/action.rs index f5c55cc117..c26c83259a 100644 --- a/contracts/examples/multisig/src/action.rs +++ b/contracts/examples/multisig/src/action.rs @@ -3,9 +3,10 @@ use multiversx_sc::{ types::{BigUint, CodeMetadata, ManagedAddress, ManagedBuffer, ManagedVec}, }; -multiversx_sc::derive_imports!(); +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 d392cda5e8..d1e177df02 100644 --- a/contracts/examples/multisig/src/multisig.rs +++ b/contracts/examples/multisig/src/multisig.rs @@ -4,13 +4,15 @@ 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 multisig_view_proxy; pub mod user_role; use action::ActionFullInfo; use user_role::UserRole; -multiversx_sc::imports!(); +use multiversx_sc::imports::*; /// Multi-signature smart contract implementation. /// Acts like a wallet that needs multiple signers for any action performed. @@ -41,6 +43,11 @@ pub trait Multisig: self.quorum().set(quorum); } + #[upgrade] + fn upgrade(&self, quorum: usize, board: MultiValueEncoded) { + self.init(quorum, board) + } + /// Allows the contract to receive funds even if it is marked as unpayable in the protocol. #[payable("*")] #[endpoint] diff --git a/contracts/examples/multisig/src/multisig_events.rs b/contracts/examples/multisig/src/multisig_events.rs index 384fdb2c1f..6db1567f28 100644 --- a/contracts/examples/multisig/src/multisig_events.rs +++ b/contracts/examples/multisig/src/multisig_events.rs @@ -1,6 +1,6 @@ use crate::{action::ActionFullInfo, user_role::UserRole}; -multiversx_sc::imports!(); +use multiversx_sc::imports::*; /// Contains all events that can be emitted by the contract. #[multiversx_sc::module] diff --git a/contracts/examples/multisig/src/multisig_perform.rs b/contracts/examples/multisig/src/multisig_perform.rs index 4769923423..3024df2696 100644 --- a/contracts/examples/multisig/src/multisig_perform.rs +++ b/contracts/examples/multisig/src/multisig_perform.rs @@ -3,7 +3,7 @@ use crate::{ user_role::UserRole, }; -multiversx_sc::imports!(); +use multiversx_sc::imports::*; /// Gas required to finish transaction after transfer-execute. const PERFORM_ACTION_FINISH_GAS: u64 = 300_000; @@ -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_propose.rs b/contracts/examples/multisig/src/multisig_propose.rs index 053b376236..8d59f58275 100644 --- a/contracts/examples/multisig/src/multisig_propose.rs +++ b/contracts/examples/multisig/src/multisig_propose.rs @@ -1,6 +1,6 @@ use crate::action::{Action, CallActionData}; -multiversx_sc::imports!(); +use multiversx_sc::imports::*; /// Contains all events that can be emitted by the contract. #[multiversx_sc::module] diff --git a/contracts/examples/multisig/src/multisig_proxy.rs b/contracts/examples/multisig/src/multisig_proxy.rs new file mode 100644 index 0000000000..6e4b78df16 --- /dev/null +++ b/contracts/examples/multisig/src/multisig_proxy.rs @@ -0,0 +1,466 @@ +// 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() + } + + /// 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() + } + + /// 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() + } + + /// 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/src/multisig_state.rs b/contracts/examples/multisig/src/multisig_state.rs index db64843ade..bfadd8efd6 100644 --- a/contracts/examples/multisig/src/multisig_state.rs +++ b/contracts/examples/multisig/src/multisig_state.rs @@ -1,6 +1,6 @@ use crate::{action::Action, user_role::UserRole}; -multiversx_sc::imports!(); +use multiversx_sc::imports::*; /// Contains all events that can be emitted by the contract. #[multiversx_sc::module] diff --git a/contracts/examples/multisig/src/multisig_view_proxy.rs b/contracts/examples/multisig/src/multisig_view_proxy.rs new file mode 100644 index 0000000000..f17bdc4212 --- /dev/null +++ b/contracts/examples/multisig/src/multisig_view_proxy.rs @@ -0,0 +1,220 @@ +// 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, + To: TxTo, + Gas: TxGas, +{ + /// 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() + } + + /// 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() + } + + /// 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() + } +} + +#[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/src/user_role.rs b/contracts/examples/multisig/src/user_role.rs index fa401130ac..b92b2dea30 100644 --- a/contracts/examples/multisig/src/user_role.rs +++ b/contracts/examples/multisig/src/user_role.rs @@ -1,4 +1,4 @@ -multiversx_sc::derive_imports!(); +use multiversx_sc::derive_imports::*; #[derive(TopEncode, TopDecode, TypeAbi, Clone, Copy, PartialEq, Eq, Debug)] pub enum UserRole { diff --git a/contracts/examples/multisig/test-contracts/adder.mxsc.json b/contracts/examples/multisig/test-contracts/adder.mxsc.json new file mode 100644 index 0000000000..7211303a9c --- /dev/null +++ b/contracts/examples/multisig/test-contracts/adder.mxsc.json @@ -0,0 +1,77 @@ +{ + "buildInfo": { + "rustc": { + "version": "1.76.0-nightly", + "commitHash": "21cce21d8c012f14cf74d5afddd795d324600dac", + "commitDate": "2023-12-11", + "channel": "Nightly", + "short": "rustc 1.76.0-nightly (21cce21d8 2023-12-11)" + }, + "contractCrate": { + "name": "adder", + "version": "0.0.0" + }, + "framework": { + "name": "multiversx-sc", + "version": "0.47.1" + } + }, + "abi": { + "docs": [ + "One of the simplest smart contracts possible,", + "it holds a single variable in storage, which anyone can increment." + ], + "name": "Adder", + "constructor": { + "inputs": [ + { + "name": "initial_value", + "type": "BigUint" + } + ], + "outputs": [] + }, + "endpoints": [ + { + "name": "getSum", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "BigUint" + } + ] + }, + { + "name": "upgrade", + "mutability": "mutable", + "inputs": [ + { + "name": "initial_value", + "type": "BigUint" + } + ], + "outputs": [] + }, + { + "docs": [ + "Add desired amount to the storage variable." + ], + "name": "add", + "mutability": "mutable", + "inputs": [ + { + "name": "value", + "type": "BigUint" + } + ], + "outputs": [] + } + ], + "esdtAttributes": [], + "hasCallback": false, + "types": {} + }, + "size": 697, + "code": "0061736d010000000129086000006000017f60027f7f017f60027f7f0060017f0060037f7f7f017f60037f7f7f0060017f017f0290020b03656e7619626967496e74476574556e7369676e6564417267756d656e74000303656e760f6765744e756d417267756d656e7473000103656e760b7369676e616c4572726f72000303656e76126d42756666657253746f726167654c6f6164000203656e76176d427566666572546f426967496e74556e7369676e6564000203656e76196d42756666657246726f6d426967496e74556e7369676e6564000203656e76136d42756666657253746f7261676553746f7265000203656e760f6d4275666665725365744279746573000503656e760e636865636b4e6f5061796d656e74000003656e7614626967496e7446696e697368556e7369676e6564000403656e7609626967496e744164640006030b0a010104070301000000000503010003060f027f0041a080080b7f0041a080080b075008066d656d6f7279020004696e697400110667657453756d00120361646400130863616c6c4261636b0014077570677261646500110a5f5f646174615f656e6403000b5f5f686561705f6261736503010aca010a0e01017f4100100c2200100020000b1901017f419c8008419c800828020041016b220036020020000b1400100120004604400f0b4180800841191002000b16002000100c220010031a2000100c220010041a20000b1401017f100c2202200110051a2000200210061a0b1301017f100c220041998008410310071a20000b1401017f10084101100d100b210010102000100f0b0e0010084100100d1010100e10090b2201037f10084101100d100b210110102202100e220020002001100a20022000100f0b0300010b0b2f0200418080080b1c77726f6e67206e756d626572206f6620617267756d656e747373756d00419c80080b049cffffff" +} diff --git a/contracts/examples/multisig/test-contracts/adder.wasm b/contracts/examples/multisig/test-contracts/adder.wasm deleted file mode 100755 index edbbd78f59..0000000000 Binary files a/contracts/examples/multisig/test-contracts/adder.wasm and /dev/null differ diff --git a/contracts/examples/multisig/test-contracts/factorial.mxsc.json b/contracts/examples/multisig/test-contracts/factorial.mxsc.json new file mode 100644 index 0000000000..db27b09157 --- /dev/null +++ b/contracts/examples/multisig/test-contracts/factorial.mxsc.json @@ -0,0 +1,54 @@ +{ + "buildInfo": { + "rustc": { + "version": "1.76.0-nightly", + "commitHash": "21cce21d8c012f14cf74d5afddd795d324600dac", + "commitDate": "2023-12-11", + "channel": "Nightly", + "short": "rustc 1.76.0-nightly (21cce21d8 2023-12-11)" + }, + "contractCrate": { + "name": "factorial", + "version": "0.0.0" + }, + "framework": { + "name": "multiversx-sc", + "version": "0.47.1" + } + }, + "abi": { + "name": "Factorial", + "constructor": { + "inputs": [], + "outputs": [] + }, + "endpoints": [ + { + "name": "upgrade", + "mutability": "mutable", + "inputs": [], + "outputs": [] + }, + { + "name": "factorial", + "mutability": "mutable", + "inputs": [ + { + "name": "value", + "type": "BigUint" + } + ], + "outputs": [ + { + "type": "BigUint" + } + ] + } + ], + "esdtAttributes": [], + "hasCallback": false, + "types": {} + }, + "size": 577, + "code": "0061736d010000000127086000006000017f60027f7f0060037f7f7f0060017f0060027f7e0060017f017f60027f7f017f02cf010a03656e760e626967496e74536574496e743634000503656e7619626967496e74476574556e7369676e6564417267756d656e74000203656e760f6765744e756d417267756d656e7473000103656e760b7369676e616c4572726f72000203656e760e636865636b4e6f5061796d656e74000003656e760a626967496e745369676e000603656e7609626967496e74436d70000703656e7609626967496e744d756c000303656e7609626967496e74416464000303656e7614626967496e7446696e697368556e7369676e656400040307060101040000000503010003060f027f0041a080080b7f0041a080080b074d07066d656d6f7279020004696e6974000d09666163746f7269616c000e0863616c6c4261636b000f0775706772616465000d0a5f5f646174615f656e6403000b5f5f686561705f6261736503010a9f01060e01017f100b22004201100020000b1901017f419c8008419c800828020041016b220036020020000b1400100220004604400f0b4180800841191003000b080010044100100c0b5201047f10044101100c4100100b2200100120002103100a210220001005047f100a2101100a2100037f20002003100641004a047f200105200120012000100720002000200210080c010b0b0520020b10090b0300010b0b2c0200418080080b1977726f6e67206e756d626572206f6620617267756d656e747300419c80080b049cffffff" +} diff --git a/contracts/examples/multisig/test-contracts/factorial.wasm b/contracts/examples/multisig/test-contracts/factorial.wasm deleted file mode 100755 index 5b8b3f50a9..0000000000 Binary files a/contracts/examples/multisig/test-contracts/factorial.wasm and /dev/null differ diff --git a/contracts/examples/multisig/tests/multisig_blackbox_test.rs b/contracts/examples/multisig/tests/multisig_blackbox_test.rs index ce2a522fcb..e8067bb73a 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, multisig_view_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 = "file:test-contracts/adder.wasm"; -const BOARD_MEMBER_ADDRESS_EXPR: &str = "address:board-member"; -const MULTISIG_ADDRESS_EXPR: &str = "sc:multisig"; -const MULTISIG_PATH_EXPR: &str = "file:output/multisig.wasm"; -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_view_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_view_proxy::UserRole, + ) { + self.world + .query() + .to(MULTISIG_ADDRESS) + .typed(multisig_view_proxy::MultisigProxy) + .user_role(user) + .returns(ExpectValue(expected_user_role)) + .run(); } } @@ -266,28 +249,30 @@ 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_view_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_view_proxy::UserRole::BoardMember, ); + state + .world + .query() + .to(MULTISIG_ADDRESS) + .typed(multisig_view_proxy::MultisigProxy) + .get_all_board_members() + .returns(ExpectValue(expected_value)) + .run() } #[test] @@ -295,28 +280,33 @@ 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_view_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_view_proxy::UserRole::Proposer, ); + + let expected_value = MultiValueVec::from(vec![PROPOSER_ADDRESS, new_proposer_address_expr]); + state + .world + .query() + .to(MULTISIG_ADDRESS) + .typed(multisig_view_proxy::MultisigProxy) + .get_all_proposers() + .returns(ExpectValue(expected_value)) + .run(); } #[test] @@ -324,18 +314,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_view_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_view_proxy::UserRole::None); + state + .world + .query() + .to(MULTISIG_ADDRESS) + .typed(multisig_view_proxy::MultisigProxy) + .get_all_proposers() + .returns(ExpectValue(MultiValueVec::
::new())) + .run(); } #[test] @@ -343,7 +336,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 +353,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 +416,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 +468,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 +494,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 +520,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 = "file:test-contracts/factorial.wasm"; + 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 +585,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_go_test.rs b/contracts/examples/multisig/tests/multisig_scenario_go_test.rs index 6e7fc7464e..d7d1dd523c 100644 --- a/contracts/examples/multisig/tests/multisig_scenario_go_test.rs +++ b/contracts/examples/multisig/tests/multisig_scenario_go_test.rs @@ -55,13 +55,13 @@ fn deploy_duplicate_bm_go() { } #[test] -#[ignore = "system SC not yet implemented"] +#[ignore = "missing 'newTokenIdentifiers' syntax"] fn interactor_nft_go() { world().run("scenarios/interactor_nft.scen.json"); } #[test] -#[ignore = "system SC not yet implemented"] +#[ignore = "missing 'newTokenIdentifiers' syntax"] fn interactor_nft_all_roles_go() { world().run("scenarios/interactor_nft_all_roles.scen.json"); } diff --git a/contracts/examples/multisig/tests/multisig_scenario_rs_test.rs b/contracts/examples/multisig/tests/multisig_scenario_rs_test.rs index 27d286e1d9..67baad4ca2 100644 --- a/contracts/examples/multisig/tests/multisig_scenario_rs_test.rs +++ b/contracts/examples/multisig/tests/multisig_scenario_rs_test.rs @@ -4,23 +4,25 @@ 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::( - "file:output/multisig.wasm", + "mxsc:output/multisig.mxsc.json", multisig::ContractBuilder, "multisig", ); blockchain.register_partial_contract::( - "file:output/multisig-view.wasm", + "mxsc:output/multisig-view.mxsc.json", multisig::ContractBuilder, "multisig-view", ); - blockchain.register_contract("file:test-contracts/adder.wasm", adder::ContractBuilder); + blockchain.register_contract( + "mxsc:test-contracts/adder.mxsc.json", + adder::ContractBuilder, + ); blockchain.register_contract( - "file:test-contracts/factorial.wasm", + "mxsc:test-contracts/factorial.mxsc.json", factorial::ContractBuilder, ); diff --git a/contracts/examples/multisig/tests/multisig_whitebox_test.rs b/contracts/examples/multisig/tests/multisig_whitebox_test.rs index 923207d720..5e1347d82b 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,32 +9,12 @@ 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"; -const BOARD_MEMBER_ADDRESS_EXPR: &str = "address:board-member"; -const MULTISIG_ADDRESS_EXPR: &str = "sc:multisig"; -const MULTISIG_PATH_EXPR: &str = "file:output/multisig.wasm"; +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const PROPOSER_ADDRESS: TestAddress = TestAddress::new("proposer"); +const BOARD_MEMBER_ADDRESS: TestAddress = TestAddress::new("board-member"); +const MULTISIG_ADDRESS: TestSCAddress = TestSCAddress::new("multisig"); +const MULTISIG_PATH_EXPR: MxscPath = MxscPath::new("mxsc:output/multisig.mxsc.json"); const QUORUM_SIZE: usize = 1; type RustBigUint = num_bigint::BigUint; @@ -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 @@ -79,40 +59,28 @@ fn world() -> ScenarioWorld { fn setup() -> ScenarioWorld { // setup let mut world = world(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); - let multisig_code = world.code_expression(MULTISIG_PATH_EXPR); - - 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(100_000_000u64), - ) - .put_account(BOARD_MEMBER_ADDRESS_EXPR, Account::new().nonce(1)), - ); + + world.account(OWNER_ADDRESS).nonce(1); + world + .account(PROPOSER_ADDRESS) + .nonce(1) + .balance(100_000_000u64); + world.account(BOARD_MEMBER_ADDRESS).nonce(1); // init multisig - world.whitebox_deploy( - &multisig_whitebox, - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(multisig_code), - |sc| { + world + .tx() + .from(OWNER_ADDRESS) + .raw_deploy() + .code(MULTISIG_PATH_EXPR) + .new_address(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let mut board_members = ManagedVec::new(); - board_members.push(managed_address!(&address_expr_to_address( - BOARD_MEMBER_ADDRESS_EXPR - ))); + board_members.push(BOARD_MEMBER_ADDRESS.to_managed_address()); sc.init(QUORUM_SIZE, board_members.into()); - sc.change_user_role( - 0, - managed_address!(&address_expr_to_address(PROPOSER_ADDRESS_EXPR)), - UserRole::Proposer, - ); - }, - ); + sc.change_user_role(0, PROPOSER_ADDRESS.to_managed_address(), UserRole::Proposer); + }); world } @@ -139,70 +107,66 @@ fn call_propose( let mut action_id = 0; - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); - - world.whitebox_call_check( - &multisig_whitebox, - ScCallStep::new() - .from(PROPOSER_ADDRESS_EXPR) - .egld_value(amount_rust_biguint) - .no_expect(), - |sc| { - action_id = match action { - ActionRaw::_Nothing => panic!("Invalid action"), - ActionRaw::AddBoardMember(addr) => { - sc.propose_add_board_member(managed_address!(&addr)) + let mut transaction = world + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .egld(BigUint::from(egld_amount)); + + let mut transaction_with_err = match expected_message { + Some(message) => transaction.returns(ExpectError(4u64, message)), + None => transaction.returns(ExpectError(0u64, "")), + }; + + transaction_with_err.whitebox(multisig::contract_obj, |sc| { + action_id = match action { + ActionRaw::_Nothing => panic!("Invalid action"), + ActionRaw::AddBoardMember(addr) => sc.propose_add_board_member(managed_address!(&addr)), + ActionRaw::AddProposer(addr) => sc.propose_add_proposer(managed_address!(&addr)), + ActionRaw::RemoveUser(addr) => sc.propose_remove_user(managed_address!(&addr)), + ActionRaw::ChangeQuorum(new_size) => sc.propose_change_quorum(new_size), + ActionRaw::SendTransferExecute(call_data) => sc.propose_transfer_execute( + managed_address!(&call_data.to), + call_data.egld_amount.into(), + FunctionCall { + function_name: call_data.endpoint_name.into(), + arg_buffer: call_data.arguments.into(), }, - ActionRaw::AddProposer(addr) => sc.propose_add_proposer(managed_address!(&addr)), - ActionRaw::RemoveUser(addr) => sc.propose_remove_user(managed_address!(&addr)), - ActionRaw::ChangeQuorum(new_size) => sc.propose_change_quorum(new_size), - ActionRaw::SendTransferExecute(call_data) => sc.propose_transfer_execute( - managed_address!(&call_data.to), - BigUint::from_bytes_be(&call_data.egld_amount.to_bytes_be()), - FunctionCall { - function_name: call_data.endpoint_name.into(), - arg_buffer: call_data.arguments.into(), - }, - ), - ActionRaw::SendAsyncCall(call_data) => sc.propose_async_call( - managed_address!(&call_data.to), - BigUint::from_bytes_be(&call_data.egld_amount.to_bytes_be()), - FunctionCall { - function_name: call_data.endpoint_name.into(), - arg_buffer: call_data.arguments.into(), - }, - ), - ActionRaw::SCDeployFromSource { - amount, - source, - code_metadata, - arguments, - } => sc.propose_sc_deploy_from_source( - BigUint::from_bytes_be(&amount.to_bytes_be()), - managed_address!(&source), - code_metadata, - boxed_bytes_vec_to_managed(arguments).into(), - ), - ActionRaw::SCUpgradeFromSource { - sc_address, - amount, - source, - code_metadata, - arguments, - } => sc.propose_sc_upgrade_from_source( - managed_address!(&sc_address), - BigUint::from_bytes_be(&amount.to_bytes_be()), - managed_address!(&source), - code_metadata, - boxed_bytes_vec_to_managed(arguments).into(), - ), - } - }, - |r| match expected_message { - Some(msg) => r.assert_user_error(msg), - None => r.assert_ok(), - }, - ); + ), + ActionRaw::SendAsyncCall(call_data) => sc.propose_async_call( + managed_address!(&call_data.to), + call_data.egld_amount.into(), + FunctionCall { + function_name: call_data.endpoint_name.into(), + arg_buffer: call_data.arguments.into(), + }, + ), + ActionRaw::SCDeployFromSource { + amount, + source, + code_metadata, + arguments, + } => sc.propose_sc_deploy_from_source( + amount.into(), + managed_address!(&source), + code_metadata, + boxed_bytes_vec_to_managed(arguments).into(), + ), + ActionRaw::SCUpgradeFromSource { + sc_address, + amount, + source, + code_metadata, + arguments, + } => sc.propose_sc_upgrade_from_source( + managed_address!(&sc_address), + amount.into(), + managed_address!(&source), + code_metadata, + boxed_bytes_vec_to_managed(arguments).into(), + ), + } + }); action_id } @@ -210,341 +174,300 @@ fn call_propose( #[test] fn test_add_board_member() { let mut world = setup(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); - const NEW_BOARD_MEMBER_ADDRESS_EXPR: &str = "address:new-board-member"; - world.set_state_step( - SetStateStep::new().put_account(NEW_BOARD_MEMBER_ADDRESS_EXPR, Account::new().nonce(1)), - ); + const NEW_BOARD_MEMBER_ADDRESS: TestAddress = TestAddress::new("new-board-member"); + world.account(NEW_BOARD_MEMBER_ADDRESS).nonce(1); - world.whitebox_query(&multisig_whitebox, |sc| { - // check role before - let user_role = sc.user_role(managed_address!(&address_expr_to_address( - NEW_BOARD_MEMBER_ADDRESS_EXPR - ))); - assert_eq!(user_role, UserRole::None); - }); + world + .query() + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { + // check role before + let user_role = sc.user_role(NEW_BOARD_MEMBER_ADDRESS.to_managed_address()); + assert_eq!(user_role, UserRole::None); + }); let action_id = call_propose( &mut world, - ActionRaw::AddBoardMember(address_expr_to_address(NEW_BOARD_MEMBER_ADDRESS_EXPR)), + ActionRaw::AddBoardMember(NEW_BOARD_MEMBER_ADDRESS.to_address()), None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); + }); - world.whitebox_query(&multisig_whitebox, |sc| { - // check role after - let user_role = sc.user_role(managed_address!(&address_expr_to_address( - NEW_BOARD_MEMBER_ADDRESS_EXPR - ))); - assert_eq!(user_role, UserRole::BoardMember); - - let board_members = sc.get_all_board_members().to_vec(); - assert_eq!( - (board_members.get(0).borrow() as &ManagedAddress).clone(), - managed_address!(&address_expr_to_address(BOARD_MEMBER_ADDRESS_EXPR)) - ); - assert_eq!( - (board_members.get(1).borrow() as &ManagedAddress).clone(), - managed_address!(&address_expr_to_address(NEW_BOARD_MEMBER_ADDRESS_EXPR)) - ); - }); + world + .query() + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { + // check role after + let user_role = sc.user_role(NEW_BOARD_MEMBER_ADDRESS.to_managed_address()); + assert_eq!(user_role, UserRole::BoardMember); + + let board_members = sc.get_all_board_members().to_vec(); + assert_eq!(*board_members.get(0), BOARD_MEMBER_ADDRESS); + assert_eq!(*board_members.get(1), NEW_BOARD_MEMBER_ADDRESS); + }); } #[test] fn test_add_proposer() { let mut world = setup(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); - const NEW_PROPOSER_ADDRESS_EXPR: &str = "address:new-proposer"; - world.set_state_step( - SetStateStep::new().put_account(NEW_PROPOSER_ADDRESS_EXPR, Account::new().nonce(1)), - ); + const NEW_PROPOSER_ADDRESS: TestAddress = TestAddress::new("new-proposer"); + world.account(NEW_PROPOSER_ADDRESS).nonce(1); - world.whitebox_query(&multisig_whitebox, |sc| { - // check role before - let user_role = sc.user_role(managed_address!(&address_expr_to_address( - NEW_PROPOSER_ADDRESS_EXPR - ))); - assert_eq!(user_role, UserRole::None); - }); + world + .query() + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { + // check role before + let user_role = sc.user_role(NEW_PROPOSER_ADDRESS.to_managed_address()); + assert_eq!(user_role, UserRole::None); + }); let action_id = call_propose( &mut world, - ActionRaw::AddProposer(address_expr_to_address(NEW_PROPOSER_ADDRESS_EXPR)), + ActionRaw::AddProposer(NEW_PROPOSER_ADDRESS.to_address()), None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); + }); - world.whitebox_query(&multisig_whitebox, |sc| { - // check role after - let user_role = sc.user_role(managed_address!(&address_expr_to_address( - NEW_PROPOSER_ADDRESS_EXPR - ))); - assert_eq!(user_role, UserRole::Proposer); - - let proposers = sc.get_all_proposers().to_vec(); - assert_eq!( - (proposers.get(0).borrow() as &ManagedAddress).clone(), - managed_address!(&address_expr_to_address(PROPOSER_ADDRESS_EXPR)) - ); - assert_eq!( - (proposers.get(1).borrow() as &ManagedAddress).clone(), - managed_address!(&address_expr_to_address(NEW_PROPOSER_ADDRESS_EXPR)) - ); - }); + world + .query() + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { + // check role after + let user_role = sc.user_role(NEW_PROPOSER_ADDRESS.to_managed_address()); + assert_eq!(user_role, UserRole::Proposer); + + let proposers = sc.get_all_proposers().to_vec(); + assert_eq!(*proposers.get(0), PROPOSER_ADDRESS); + assert_eq!(*proposers.get(1), NEW_PROPOSER_ADDRESS); + }); } #[test] fn test_remove_proposer() { let mut world = setup(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); - - world.whitebox_query(&multisig_whitebox, |sc| { - // check role before - let user_role = sc.user_role(managed_address!(&address_expr_to_address( - PROPOSER_ADDRESS_EXPR - ))); - assert_eq!(user_role, UserRole::Proposer); - }); + + world + .query() + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { + // check role before + let user_role = sc.user_role(PROPOSER_ADDRESS.to_managed_address()); + assert_eq!(user_role, UserRole::Proposer); + }); let action_id = call_propose( &mut world, - ActionRaw::RemoveUser(address_expr_to_address(PROPOSER_ADDRESS_EXPR)), + ActionRaw::RemoveUser(PROPOSER_ADDRESS.to_address()), None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); + }); - world.whitebox_query(&multisig_whitebox, |sc| { - // check role after - let user_role = sc.user_role(managed_address!(&address_expr_to_address( - PROPOSER_ADDRESS_EXPR - ))); - assert_eq!(user_role, UserRole::None); - - let proposers = sc.get_all_proposers().to_vec(); - assert!(proposers.is_empty()); - }); + world + .query() + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { + // check role after + let user_role = sc.user_role(PROPOSER_ADDRESS.to_managed_address()); + assert_eq!(user_role, UserRole::None); + + let proposers = sc.get_all_proposers(); + assert!(proposers.is_empty()); + }); } #[test] fn test_try_remove_all_board_members() { let mut world = setup(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); let action_id = call_propose( &mut world, - ActionRaw::RemoveUser(address_expr_to_address(BOARD_MEMBER_ADDRESS_EXPR)), + ActionRaw::RemoveUser(BOARD_MEMBER_ADDRESS.to_address()), None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call_check( - &multisig_whitebox, - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .no_expect(), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .returns(ExpectError(4u64, "quorum cannot exceed board size")) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - |r| { - r.assert_user_error("quorum cannot exceed board size"); - }, - ); + }); } #[test] fn test_change_quorum() { let mut world = setup(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); let new_quorum_size = 2; // try change quorum > board size let action_id = call_propose(&mut world, ActionRaw::ChangeQuorum(new_quorum_size), None); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call_check( - &multisig_whitebox, - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .no_expect(), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .returns(ExpectError(4u64, "quorum cannot exceed board size")) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - |r| { - r.assert_user_error("quorum cannot exceed board size"); - }, - ); + }); // try discard before unsigning - world.whitebox_call_check( - &multisig_whitebox, - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .no_expect(), - |sc| { - sc.discard_action(action_id); - }, - |r| { - r.assert_user_error("cannot discard action with valid signatures"); - }, - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .returns(ExpectError( + 4u64, + "cannot discard action with valid signatures", + )) + .whitebox(multisig::contract_obj, |sc| sc.discard_action(action_id)); // unsign and discard action - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.unsign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.unsign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { - sc.discard_action(action_id); - }, - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.discard_action(action_id)); // try sign discarded action - world.whitebox_call_check( - &multisig_whitebox, - ScCallStep::new() - .from(BOARD_MEMBER_ADDRESS_EXPR) - .no_expect(), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .returns(ExpectError(4u64, "action does not exist")) + .whitebox(multisig::contract_obj, |sc| { sc.sign(action_id); - }, - |r| { - r.assert_user_error("action does not exist"); - }, - ); + }); // add another board member - const NEW_BOARD_MEMBER_ADDRESS_EXPR: &str = "address:new-board-member"; - world.set_state_step( - SetStateStep::new().put_account(NEW_BOARD_MEMBER_ADDRESS_EXPR, Account::new().nonce(1)), - ); + const NEW_BOARD_MEMBER_ADDRESS: TestAddress = TestAddress::new("new-board-member"); + world.account(NEW_BOARD_MEMBER_ADDRESS).nonce(1); let action_id = call_propose( &mut world, - ActionRaw::AddBoardMember(address_expr_to_address(NEW_BOARD_MEMBER_ADDRESS_EXPR)), + ActionRaw::AddBoardMember(NEW_BOARD_MEMBER_ADDRESS.to_address()), None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); + }); // change quorum to 2 let action_id = call_propose(&mut world, ActionRaw::ChangeQuorum(new_quorum_size), None); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); + }); } #[test] fn test_transfer_execute_to_user() { let mut world = setup(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); - const NEW_USER_ADDRESS_EXPR: &str = "address:new-user"; - world.set_state_step( - SetStateStep::new().put_account(NEW_USER_ADDRESS_EXPR, Account::new().nonce(1)), - ); + const NEW_USER_ADDRESS: TestAddress = TestAddress::new("new-user"); + world.account(NEW_USER_ADDRESS).nonce(1); const EGLD_AMOUNT: u64 = 100; - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new() - .from(PROPOSER_ADDRESS_EXPR) - .egld_value(EGLD_AMOUNT), - |sc| { + world + .tx() + .from(PROPOSER_ADDRESS) + .to(MULTISIG_ADDRESS) + .egld(EGLD_AMOUNT) + .whitebox(multisig::contract_obj, |sc| { sc.deposit(); - }, - ); + }); - world.check_state_step(CheckStateStep::new().put_account( - MULTISIG_ADDRESS_EXPR, - CheckAccount::new().balance(EGLD_AMOUNT.to_string().as_str()), - )); + world.check_account(MULTISIG_ADDRESS).balance(EGLD_AMOUNT); // failed attempt let action_id = call_propose( &mut world, ActionRaw::SendTransferExecute(CallActionDataRaw { - to: address_expr_to_address(NEW_USER_ADDRESS_EXPR), + to: NEW_USER_ADDRESS.to_address(), egld_amount: rust_biguint!(0), endpoint_name: BoxedBytes::empty(), arguments: Vec::new(), @@ -556,7 +479,7 @@ fn test_transfer_execute_to_user() { let action_id = call_propose( &mut world, ActionRaw::SendTransferExecute(CallActionDataRaw { - to: address_expr_to_address(NEW_USER_ADDRESS_EXPR), + to: NEW_USER_ADDRESS.to_address(), egld_amount: rust_biguint!(EGLD_AMOUNT), endpoint_name: BoxedBytes::empty(), arguments: Vec::new(), @@ -564,59 +487,48 @@ fn test_transfer_execute_to_user() { None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); + }); - world.check_state_step(CheckStateStep::new().put_account( - NEW_USER_ADDRESS_EXPR, - CheckAccount::new().balance(EGLD_AMOUNT.to_string().as_str()), - )); + world.check_account(NEW_USER_ADDRESS).balance(EGLD_AMOUNT); } #[test] fn test_transfer_execute_sc_all() { let mut world = setup(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); - - let adder_whitebox = WhiteboxContract::new(ADDER_ADDRESS_EXPR, adder::contract_obj); - let adder_code = world.code_expression(ADDER_PATH_EXPR); - const ADDER_OWNER_ADDRESS_EXPR: &str = "address:adder-owner"; - const ADDER_ADDRESS_EXPR: &str = "sc:adder"; - const ADDER_PATH_EXPR: &str = "file:test-contracts/adder.wasm"; + const ADDER_OWNER_ADDRESS: TestAddress = TestAddress::new("adder-owner"); + const ADDER_ADDRESS: TestSCAddress = TestSCAddress::new("adder"); + const ADDER_PATH_EXPR: MxscPath = MxscPath::new("mxsc:test-contracts/adder.mxsc.json"); world.register_contract(ADDER_PATH_EXPR, adder::ContractBuilder); - world.set_state_step( - SetStateStep::new() - .put_account(ADDER_OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .new_address(ADDER_OWNER_ADDRESS_EXPR, 1, ADDER_ADDRESS_EXPR), - ); + world.account(ADDER_OWNER_ADDRESS).nonce(1); - world.whitebox_deploy( - &adder_whitebox, - ScDeployStep::new() - .from(ADDER_OWNER_ADDRESS_EXPR) - .code(adder_code), - |sc| { - sc.init(managed_biguint!(5)); - }, - ); + world + .tx() + .raw_deploy() + .from(ADDER_OWNER_ADDRESS) + .code(ADDER_PATH_EXPR) + .new_address(ADDER_ADDRESS) + .whitebox(adder::contract_obj, |sc| { + sc.init(BigUint::from(5u64)); + }); let action_id = call_propose( &mut world, ActionRaw::SendTransferExecute(CallActionDataRaw { - to: address_expr_to_address(ADDER_ADDRESS_EXPR), + to: ADDER_ADDRESS.to_address(), egld_amount: 0u64.into(), endpoint_name: BoxedBytes::from(&b"add"[..]), arguments: vec![BoxedBytes::from(&[5u8][..])], @@ -624,60 +536,55 @@ fn test_transfer_execute_sc_all() { None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); + }); - world.whitebox_query(&adder_whitebox, |sc| { - let actual_sum = sc.sum().get(); - let expected_sum = managed_biguint!(10); - assert_eq!(actual_sum, expected_sum); - }); + world + .query() + .to(ADDER_ADDRESS) + .whitebox(adder::contract_obj, |sc| { + let actual_sum = sc.sum().get(); + let expected_sum = managed_biguint!(10); + assert_eq!(actual_sum, expected_sum); + }); } #[test] fn test_async_call_to_sc() { let mut world = setup(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); - let adder_whitebox = WhiteboxContract::new(ADDER_ADDRESS_EXPR, adder::contract_obj); - let adder_code = world.code_expression(ADDER_PATH_EXPR); - - const ADDER_OWNER_ADDRESS_EXPR: &str = "address:adder-owner"; - const ADDER_ADDRESS_EXPR: &str = "sc:adder"; - const ADDER_PATH_EXPR: &str = "file:test-contracts/adder.wasm"; + const ADDER_OWNER_ADDRESS: TestAddress = TestAddress::new("adder-owner"); + const ADDER_ADDRESS: TestSCAddress = TestSCAddress::new("adder"); + const ADDER_PATH_EXPR: MxscPath = MxscPath::new("mxsc:test-contracts/adder.mxsc.json"); world.register_contract(ADDER_PATH_EXPR, adder::ContractBuilder); - world.set_state_step( - SetStateStep::new() - .put_account(ADDER_OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .new_address(ADDER_OWNER_ADDRESS_EXPR, 1, ADDER_ADDRESS_EXPR), - ); + world.account(ADDER_OWNER_ADDRESS).nonce(1); - world.whitebox_deploy( - &adder_whitebox, - ScDeployStep::new() - .from(ADDER_OWNER_ADDRESS_EXPR) - .code(adder_code), - |sc| { - sc.init(managed_biguint!(5)); - }, - ); + world + .tx() + .raw_deploy() + .from(ADDER_OWNER_ADDRESS) + .code(ADDER_PATH_EXPR) + .new_address(ADDER_ADDRESS) + .whitebox(adder::contract_obj, |sc| { + sc.init(BigUint::from(5u64)); + }); let action_id = call_propose( &mut world, ActionRaw::SendAsyncCall(CallActionDataRaw { - to: address_expr_to_address(ADDER_ADDRESS_EXPR), + to: ADDER_ADDRESS.to_address(), egld_amount: 0u64.into(), endpoint_name: BoxedBytes::from(&b"add"[..]), arguments: vec![BoxedBytes::from(&[5u8][..])], @@ -685,93 +592,90 @@ fn test_async_call_to_sc() { None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); + }); - world.whitebox_query(&adder_whitebox, |sc| { - let actual_sum = sc.sum().get(); - let expected_sum = managed_biguint!(10); - assert_eq!(actual_sum, expected_sum); - }); + world + .query() + .to(ADDER_ADDRESS) + .whitebox(adder::contract_obj, |sc| { + let actual_sum = sc.sum().get(); + let expected_sum = managed_biguint!(10); + assert_eq!(actual_sum, expected_sum); + }); } #[test] fn test_deploy_and_upgrade_from_source() { let mut world = setup(); - let multisig_whitebox = WhiteboxContract::new(MULTISIG_ADDRESS_EXPR, multisig::contract_obj); - - let adder_whitebox = WhiteboxContract::new(ADDER_ADDRESS_EXPR, adder::contract_obj); - let adder_code = world.code_expression(ADDER_PATH_EXPR); - - let new_adder_whitebox = WhiteboxContract::new(NEW_ADDER_ADDRESS_EXPR, adder::contract_obj); + const NEW_ADDER_ADDRESS: TestSCAddress = TestSCAddress::new("new-adder"); - const ADDER_OWNER_ADDRESS_EXPR: &str = "address:adder-owner"; - const ADDER_ADDRESS_EXPR: &str = "sc:adder"; - const NEW_ADDER_ADDRESS_EXPR: &str = "sc:new-adder"; - const ADDER_PATH_EXPR: &str = "file:test-contracts/adder.wasm"; + const ADDER_OWNER_ADDRESS: TestAddress = TestAddress::new("adder-owner"); + const ADDER_ADDRESS: TestSCAddress = TestSCAddress::new("adder"); + const ADDER_PATH_EXPR: MxscPath = MxscPath::new("mxsc:test-contracts/adder.mxsc.json"); world.register_contract(ADDER_PATH_EXPR, adder::ContractBuilder); - world.set_state_step( - SetStateStep::new() - .put_account(ADDER_OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .new_address(ADDER_OWNER_ADDRESS_EXPR, 1, ADDER_ADDRESS_EXPR) - .new_address(MULTISIG_ADDRESS_EXPR, 0, NEW_ADDER_ADDRESS_EXPR), - ); + world.set_state_step(SetStateStep::new().new_address( + MULTISIG_ADDRESS.eval_to_expr().as_str(), + 0, + NEW_ADDER_ADDRESS.eval_to_expr().as_str(), + )); - world.whitebox_deploy( - &adder_whitebox, - ScDeployStep::new() - .from(ADDER_OWNER_ADDRESS_EXPR) - .code(adder_code), - |sc| { - sc.init(managed_biguint!(5)); - }, - ); + world.account(ADDER_OWNER_ADDRESS).nonce(1); + + world + .tx() + .raw_deploy() + .from(ADDER_OWNER_ADDRESS) + .code(ADDER_PATH_EXPR) + .new_address(ADDER_ADDRESS) + .whitebox(adder::contract_obj, |sc| { + sc.init(BigUint::from(5u64)); + }); let action_id = call_propose( &mut world, ActionRaw::SCDeployFromSource { amount: 0u64.into(), - source: address_expr_to_address(ADDER_ADDRESS_EXPR), + source: ADDER_ADDRESS.to_address(), code_metadata: CodeMetadata::all(), arguments: vec![BoxedBytes::from(&[5u8][..])], }, None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - let mut addr = Address::zero(); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let opt_address = sc.perform_action_endpoint(action_id); - addr = opt_address.into_option().unwrap().to_address(); - }, - ); + let addr = opt_address.into_option().unwrap().to_address(); - assert_eq!(address_expr_to_address(NEW_ADDER_ADDRESS_EXPR), addr); + assert_eq!(NEW_ADDER_ADDRESS.to_address(), addr); + }); let action_id = call_propose( &mut world, ActionRaw::SendTransferExecute(CallActionDataRaw { - to: address_expr_to_address(NEW_ADDER_ADDRESS_EXPR), + to: NEW_ADDER_ADDRESS.to_address(), egld_amount: 0u64.into(), endpoint_name: BoxedBytes::from(&b"add"[..]), arguments: vec![BoxedBytes::from(&[5u8][..])], @@ -779,71 +683,70 @@ fn test_deploy_and_upgrade_from_source() { None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); + }); - world.whitebox_query(&new_adder_whitebox, |sc| { - let actual_sum = sc.sum().get(); - let expected_sum = managed_biguint!(10); - assert_eq!(actual_sum, expected_sum); - }); - - let factorial_code = world.code_expression(FACTORIAL_PATH_EXPR); + world + .query() + .to(NEW_ADDER_ADDRESS) + .whitebox(adder::contract_obj, |sc| { + let actual_sum = sc.sum().get(); + let expected_sum = managed_biguint!(10); + assert_eq!(actual_sum, expected_sum); + }); - const FACTORIAL_ADDRESS_EXPR: &str = "sc:factorial"; - const FACTORIAL_PATH_EXPR: &str = "file:test-contracts/factorial.wasm"; + const FACTORIAL_ADDRESS: TestSCAddress = TestSCAddress::new("factorial"); + const FACTORIAL_PATH_EXPR: MxscPath = MxscPath::new("mxsc:test-contracts/factorial.mxsc.json"); world.register_contract(FACTORIAL_PATH_EXPR, factorial::ContractBuilder); - world.set_state_step(SetStateStep::new().put_account( - FACTORIAL_ADDRESS_EXPR, - Account::new().nonce(1).code(factorial_code.clone()), - )); + world + .tx() + .raw_deploy() + .from(OWNER_ADDRESS) + .code(FACTORIAL_PATH_EXPR) + .new_address(FACTORIAL_ADDRESS) + .whitebox(factorial::contract_obj, |sc| { + sc.init(); + }); let action_id = call_propose( &mut world, ActionRaw::SCUpgradeFromSource { - source: address_expr_to_address(FACTORIAL_ADDRESS_EXPR), + source: FACTORIAL_ADDRESS.to_address(), amount: 0u64.into(), code_metadata: CodeMetadata::all(), arguments: Vec::new(), - sc_address: address_expr_to_address(ADDER_ADDRESS_EXPR), + sc_address: ADDER_ADDRESS.to_address(), }, None, ); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| sc.sign(action_id), - ); + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| sc.sign(action_id)); - world.whitebox_call( - &multisig_whitebox, - ScCallStep::new().from(BOARD_MEMBER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(BOARD_MEMBER_ADDRESS) + .to(MULTISIG_ADDRESS) + .whitebox(multisig::contract_obj, |sc| { let _ = sc.perform_action_endpoint(action_id); - }, - ); - - world.check_state_step( - CheckStateStep::new() - .put_account(ADDER_ADDRESS_EXPR, CheckAccount::new().code(factorial_code)), - ); -} + }); -fn address_expr_to_address(address_expr: &str) -> Address { - AddressValue::from(address_expr).to_address() + world.check_account(ADDER_ADDRESS).code(FACTORIAL_PATH_EXPR); } fn boxed_bytes_vec_to_managed( diff --git a/contracts/examples/multisig/wasm-multisig-full/Cargo.lock b/contracts/examples/multisig/wasm-multisig-full/Cargo.lock index a3c53028cf..9d07aa098f 100644 --- a/contracts/examples/multisig/wasm-multisig-full/Cargo.lock +++ b/contracts/examples/multisig/wasm-multisig-full/Cargo.lock @@ -2,47 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -50,16 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" -dependencies = [ - "ahash", - "allocator-api2", -] - [[package]] name = "hex" version = "0.4.3" @@ -90,55 +56,56 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -154,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -197,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -230,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/multisig/wasm-multisig-full/Cargo.toml b/contracts/examples/multisig/wasm-multisig-full/Cargo.toml index 7a42c9ae93..86facedf0f 100644 --- a/contracts/examples/multisig/wasm-multisig-full/Cargo.toml +++ b/contracts/examples/multisig/wasm-multisig-full/Cargo.toml @@ -1,4 +1,4 @@ -# Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +# Code generated by the multiversx-sc build system. DO NOT EDIT. # ########################################## # ############## AUTO-GENERATED ############# @@ -19,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.multisig] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 f06f1be4f6..c62c8ef62b 100644 --- a/contracts/examples/multisig/wasm-multisig-full/src/lib.rs +++ b/contracts/examples/multisig/wasm-multisig-full/src/lib.rs @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 +// Upgrade: 1 // Endpoints: 28 // Async Callback: 1 -// Total number of exported functions: 30 +// Total number of exported functions: 31 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { multisig ( init => init + upgrade => upgrade deposit => deposit signed => signed sign => sign diff --git a/contracts/examples/multisig/wasm-multisig-view/Cargo.lock b/contracts/examples/multisig/wasm-multisig-view/Cargo.lock index c78ebcfee8..0f6e03942e 100644 --- a/contracts/examples/multisig/wasm-multisig-view/Cargo.lock +++ b/contracts/examples/multisig/wasm-multisig-view/Cargo.lock @@ -2,47 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -50,16 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" -dependencies = [ - "ahash", - "allocator-api2", -] - [[package]] name = "hex" version = "0.4.3" @@ -90,55 +56,56 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -154,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -197,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -230,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/multisig/wasm-multisig-view/Cargo.toml b/contracts/examples/multisig/wasm-multisig-view/Cargo.toml index 405b3e2a43..e3bd48b6f4 100644 --- a/contracts/examples/multisig/wasm-multisig-view/Cargo.toml +++ b/contracts/examples/multisig/wasm-multisig-view/Cargo.toml @@ -1,4 +1,4 @@ -# Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +# Code generated by the multiversx-sc build system. DO NOT EDIT. # ########################################## # ############## AUTO-GENERATED ############# @@ -19,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.multisig] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 baa4919742..de4e6479d6 100644 --- a/contracts/examples/multisig/wasm-multisig-view/src/lib.rs +++ b/contracts/examples/multisig/wasm-multisig-view/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 2067a451d1..0e92d680d6 100755 --- a/contracts/examples/multisig/wasm/Cargo.lock +++ b/contracts/examples/multisig/wasm/Cargo.lock @@ -2,47 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -50,16 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" -dependencies = [ - "ahash", - "allocator-api2", -] - [[package]] name = "hex" version = "0.4.3" @@ -90,55 +56,56 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -154,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -197,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -230,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/multisig/wasm/Cargo.toml b/contracts/examples/multisig/wasm/Cargo.toml index 8d7b6a2f7c..03ae711446 100644 --- a/contracts/examples/multisig/wasm/Cargo.toml +++ b/contracts/examples/multisig/wasm/Cargo.toml @@ -1,4 +1,4 @@ -# Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +# Code generated by the multiversx-sc build system. DO NOT EDIT. # ########################################## # ############## AUTO-GENERATED ############# @@ -19,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.multisig] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" [workspace] diff --git a/contracts/examples/multisig/wasm/src/lib.rs b/contracts/examples/multisig/wasm/src/lib.rs index d62dd3d4c8..2d7e536d14 100644 --- a/contracts/examples/multisig/wasm/src/lib.rs +++ b/contracts/examples/multisig/wasm/src/lib.rs @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 +// Upgrade: 1 // Endpoints: 20 // Async Callback: 1 -// Total number of exported functions: 22 +// Total number of exported functions: 23 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { multisig ( init => init + upgrade => upgrade deposit => deposit signed => signed sign => sign 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 78c800f2a7..2490922fb5 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/nft-minter/meta/Cargo.toml b/contracts/examples/nft-minter/meta/Cargo.toml index 0709b85822..08f8dace58 100644 --- a/contracts/examples/nft-minter/meta/Cargo.toml +++ b/contracts/examples/nft-minter/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.nft-minter] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/create_nft.scen.json b/contracts/examples/nft-minter/scenarios/create_nft.scen.json index 2ede6d317e..34a6c2e8a2 100644 --- a/contracts/examples/nft-minter/scenarios/create_nft.scen.json +++ b/contracts/examples/nft-minter/scenarios/create_nft.scen.json @@ -116,7 +116,7 @@ "3-amount": "biguint:500" } }, - "code": "file:../output/nft-minter.wasm", + "code": "mxsc:../output/nft-minter.mxsc.json", "owner": "address:owner" }, "+": "" diff --git a/contracts/examples/nft-minter/scenarios/init.scen.json b/contracts/examples/nft-minter/scenarios/init.scen.json index 59f84128b5..61d7a1c65b 100644 --- a/contracts/examples/nft-minter/scenarios/init.scen.json +++ b/contracts/examples/nft-minter/scenarios/init.scen.json @@ -41,7 +41,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/nft-minter.wasm", + "contractCode": "mxsc:../output/nft-minter.mxsc.json", "arguments": [], "gasLimit": "10,000,000", "gasPrice": "0" @@ -61,7 +61,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/nft-minter.wasm" + "code": "mxsc:../output/nft-minter.mxsc.json" }, "+": "" } @@ -83,7 +83,7 @@ "storage": { "str:nftTokenId": "str:NFT-123456" }, - "code": "file:../output/nft-minter.wasm", + "code": "mxsc:../output/nft-minter.mxsc.json", "owner": "address:owner" } } diff --git a/contracts/examples/nft-minter/src/lib.rs b/contracts/examples/nft-minter/src/lib.rs index e65e8a7dff..4148f368c2 100644 --- a/contracts/examples/nft-minter/src/lib.rs +++ b/contracts/examples/nft-minter/src/lib.rs @@ -1,8 +1,8 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; +pub mod nft_marketplace_proxy; mod nft_module; #[derive(TypeAbi, TopEncode, TopDecode)] @@ -73,30 +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::imports!(); - - #[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 5643201724..66f50ea958 100644 --- a/contracts/examples/nft-minter/src/nft_module.rs +++ b/contracts/examples/nft-minter/src/nft_module.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; const NFT_AMOUNT: u32 = 1; const ROYALTIES_MAX: u32 = 10_000; @@ -38,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] @@ -55,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 @@ -89,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 @@ -133,14 +123,12 @@ pub trait NftModule { ) { match result { ManagedAsyncCallResult::Ok(token_id) => { - self.nft_token_id().set(&token_id.unwrap_esdt()); + 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/scenario_go_test.rs b/contracts/examples/nft-minter/tests/nft_minter_scenario_go_test.rs similarity index 100% rename from contracts/examples/nft-minter/tests/scenario_go_test.rs rename to contracts/examples/nft-minter/tests/nft_minter_scenario_go_test.rs 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 3d3961f1a2..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 @@ -1,23 +1,26 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { - todo!() + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + "mxsc:output/nft-minter.mxsc.json", + nft_minter::ContractBuilder, + ); + blockchain } #[test] -#[ignore = "not supported"] fn buy_nft_rs() { world().run("scenarios/buy_nft.scen.json"); } #[test] -#[ignore = "not supported"] fn create_nft_rs() { world().run("scenarios/create_nft.scen.json"); } #[test] -#[ignore = "not supported"] fn init_rs() { world().run("scenarios/init.scen.json"); } diff --git a/contracts/examples/nft-minter/wasm/Cargo.lock b/contracts/examples/nft-minter/wasm/Cargo.lock index 213f4e9cea..60fe9c66ed 100644 --- a/contracts/examples/nft-minter/wasm/Cargo.lock +++ b/contracts/examples/nft-minter/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/nft-minter/wasm/Cargo.toml b/contracts/examples/nft-minter/wasm/Cargo.toml index d068d3fae9..8dc62e8b60 100644 --- a/contracts/examples/nft-minter/wasm/Cargo.toml +++ b/contracts/examples/nft-minter/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "nft-minter-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.nft-minter] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 97063eb7a4..daef60b06e 100644 --- a/contracts/examples/nft-minter/wasm/src/lib.rs +++ b/contracts/examples/nft-minter/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 95bad88322..d3dceaa538 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/nft-storage-prepay/meta/Cargo.toml b/contracts/examples/nft-storage-prepay/meta/Cargo.toml index 21c41731aa..0271a13b9d 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,6 +10,7 @@ publish = false [dependencies.nft-storage-prepay] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 e546da11e3..7e1c6115d3 100644 --- a/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs +++ b/contracts/examples/nft-storage-prepay/src/nft_storage_prepay.rs @@ -1,6 +1,6 @@ #![no_std] -multiversx_sc::imports!(); +use multiversx_sc::imports::*; #[multiversx_sc::contract] pub trait NftStoragePrepay { @@ -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 8ed048a096..029d5d42f5 100755 --- a/contracts/examples/nft-storage-prepay/wasm/Cargo.lock +++ b/contracts/examples/nft-storage-prepay/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/nft-storage-prepay/wasm/Cargo.toml b/contracts/examples/nft-storage-prepay/wasm/Cargo.toml index 25e2ed96ea..4a204d527b 100644 --- a/contracts/examples/nft-storage-prepay/wasm/Cargo.toml +++ b/contracts/examples/nft-storage-prepay/wasm/Cargo.toml @@ -1,17 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "nft-storage-prepay-wasm" version = "0.0.0" -authors = [ "Dorin Iancu ",] edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = [ ".",] - -[dev-dependencies] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -19,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.nft-storage-prepay] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/nft-storage-prepay/wasm/src/lib.rs b/contracts/examples/nft-storage-prepay/wasm/src/lib.rs index 6541f8b937..cbcfccb60f 100644 --- a/contracts/examples/nft-storage-prepay/wasm/src/lib.rs +++ b/contracts/examples/nft-storage-prepay/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 8d0b7b383b..b2c48529dc 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/nft-subscription/meta/Cargo.toml b/contracts/examples/nft-subscription/meta/Cargo.toml index c8816b94be..4d01981805 100644 --- a/contracts/examples/nft-subscription/meta/Cargo.toml +++ b/contracts/examples/nft-subscription/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.nft-subscription] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/init.scen.json b/contracts/examples/nft-subscription/scenarios/init.scen.json index 40a0f7da51..73389dc5b0 100644 --- a/contracts/examples/nft-subscription/scenarios/init.scen.json +++ b/contracts/examples/nft-subscription/scenarios/init.scen.json @@ -26,7 +26,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/nft-subscription.wasm", + "contractCode": "mxsc:../output/nft-subscription.mxsc.json", "arguments": [], "gasLimit": "10,000,000", "gasPrice": "0" @@ -46,7 +46,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/nft-subscription.wasm" + "code": "mxsc:../output/nft-subscription.mxsc.json" }, "+": "" } @@ -69,7 +69,7 @@ "storage": { "str:tokenId": "str:NFT-123456" }, - "code": "file:../output/nft-subscription.wasm", + "code": "mxsc:../output/nft-subscription.mxsc.json", "owner": "address:owner" } } diff --git a/contracts/examples/nft-subscription/scenarios/test_subscription.scen.json b/contracts/examples/nft-subscription/scenarios/test_subscription.scen.json index 7948b03bcc..8cec16fce7 100644 --- a/contracts/examples/nft-subscription/scenarios/test_subscription.scen.json +++ b/contracts/examples/nft-subscription/scenarios/test_subscription.scen.json @@ -212,4 +212,4 @@ } } ] -} \ No newline at end of file +} diff --git a/contracts/examples/nft-subscription/src/lib.rs b/contracts/examples/nft-subscription/src/lib.rs index b9c4fcdb8d..7b0b63096e 100644 --- a/contracts/examples/nft-subscription/src/lib.rs +++ b/contracts/examples/nft-subscription/src/lib.rs @@ -1,7 +1,6 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; use multiversx_sc_modules::{default_issue_callbacks, subscription}; @@ -36,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("*")] @@ -49,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("*")] @@ -62,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("*")] @@ -75,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/scenario_go_test.rs b/contracts/examples/nft-subscription/tests/nft_subscription_scenario_go_test.rs similarity index 100% rename from contracts/examples/nft-subscription/tests/scenario_go_test.rs rename to contracts/examples/nft-subscription/tests/nft_subscription_scenario_go_test.rs index 504c7992b0..d3cdc1eada 100644 --- a/contracts/examples/nft-subscription/tests/scenario_go_test.rs +++ b/contracts/examples/nft-subscription/tests/nft_subscription_scenario_go_test.rs @@ -5,8 +5,8 @@ fn world() -> ScenarioWorld { } #[test] -fn test_subscription_go() { - world().run("scenarios/test_subscription.scen.json"); +fn init_go() { + world().run("scenarios/init.scen.json"); } #[test] @@ -15,6 +15,6 @@ fn mint_nft_go() { } #[test] -fn init_go() { - world().run("scenarios/init.scen.json"); +fn test_subscription_go() { + world().run("scenarios/test_subscription.scen.json"); } 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 d37faa2bca..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 @@ -1,23 +1,26 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { - todo!() + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + "mxsc:output/nft-subscription.mxsc.json", + nft_subscription::ContractBuilder, + ); + blockchain } #[test] -#[ignore = "not supported"] -fn test_subscription_rs() { - world().run("scenarios/test_subscription.scen.json"); +fn init_rs() { + world().run("scenarios/init.scen.json"); } #[test] -#[ignore = "not supported"] fn mint_nft_rs() { world().run("scenarios/mint_nft.scen.json"); } #[test] -#[ignore = "not supported"] -fn init_rs() { - world().run("scenarios/init.scen.json"); +fn test_subscription_rs() { + world().run("scenarios/test_subscription.scen.json"); } diff --git a/contracts/examples/nft-subscription/wasm/Cargo.lock b/contracts/examples/nft-subscription/wasm/Cargo.lock index c28b59de7c..6e5fbb7c3f 100644 --- a/contracts/examples/nft-subscription/wasm/Cargo.lock +++ b/contracts/examples/nft-subscription/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,61 +34,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/nft-subscription/wasm/Cargo.toml b/contracts/examples/nft-subscription/wasm/Cargo.toml index b746e31e95..1e0dc6a6c8 100644 --- a/contracts/examples/nft-subscription/wasm/Cargo.toml +++ b/contracts/examples/nft-subscription/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "nft-subscription-wasm" version = "0.0.0" -authors = ["Thouny "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.nft-subscription] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 76a79ce530..07b9b6e288 100644 --- a/contracts/examples/nft-subscription/wasm/src/lib.rs +++ b/contracts/examples/nft-subscription/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 919c6bd2d4..cd0e12daaf 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/scenario" diff --git a/contracts/examples/order-book/factory/meta/Cargo.toml b/contracts/examples/order-book/factory/meta/Cargo.toml index 36b341611f..ba8b635dee 100644 --- a/contracts/examples/order-book/factory/meta/Cargo.toml +++ b/contracts/examples/order-book/factory/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.order-book-factory] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 1227754195..fb83863ae3 100644 --- a/contracts/examples/order-book/factory/src/lib.rs +++ b/contracts/examples/order-book/factory/src/lib.rs @@ -1,7 +1,6 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; #[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone)] pub struct TokenIdPair { @@ -24,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 22671739cd..41a5615328 100644 --- a/contracts/examples/order-book/factory/wasm/Cargo.lock +++ b/contracts/examples/order-book/factory/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,19 +98,13 @@ 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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "order-book-factory" version = "0.0.0" @@ -154,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/order-book/factory/wasm/Cargo.toml b/contracts/examples/order-book/factory/wasm/Cargo.toml index 58c01aab9a..3762fbfdf9 100644 --- a/contracts/examples/order-book/factory/wasm/Cargo.toml +++ b/contracts/examples/order-book/factory/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "order-book-factory-wasm" version = "0.0.0" @@ -5,12 +11,7 @@ edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = [ ".",] - -[dev-dependencies] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -18,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.order-book-factory] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/order-book/factory/wasm/src/lib.rs b/contracts/examples/order-book/factory/wasm/src/lib.rs index 58288a47cc..be215e6f41 100644 --- a/contracts/examples/order-book/factory/wasm/src/lib.rs +++ b/contracts/examples/order-book/factory/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 38ff196bae..505715ebbc 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/scenario" diff --git a/contracts/examples/order-book/pair/meta/Cargo.toml b/contracts/examples/order-book/pair/meta/Cargo.toml index 18f4bf6e5a..217fb07ee4 100644 --- a/contracts/examples/order-book/pair/meta/Cargo.toml +++ b/contracts/examples/order-book/pair/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.order-book-pair] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/steps/deploy.steps.json b/contracts/examples/order-book/pair/scenarios/steps/deploy.steps.json index 0923c12285..7d76b2b4df 100644 --- a/contracts/examples/order-book/pair/scenarios/steps/deploy.steps.json +++ b/contracts/examples/order-book/pair/scenarios/steps/deploy.steps.json @@ -16,7 +16,7 @@ "id": "deploy-router", "tx": { "from": "address:owner", - "contractCode": "file:../../output/order-book-pair.wasm", + "contractCode": "mxsc:../../output/order-book-pair.mxsc.json", "arguments": [ "str:WEGLD-abcdef", "str:BUSD-abcdef" diff --git a/contracts/examples/order-book/pair/src/common.rs b/contracts/examples/order-book/pair/src/common.rs index 17a5704073..1c4b2e893c 100644 --- a/contracts/examples/order-book/pair/src/common.rs +++ b/contracts/examples/order-book/pair/src/common.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; pub const MAX_ORDERS_PER_USER: usize = 100; pub const PERCENT_BASE_POINTS: u64 = 100_000; diff --git a/contracts/examples/order-book/pair/src/events.rs b/contracts/examples/order-book/pair/src/events.rs index 997ae9990c..ddbd6a3496 100644 --- a/contracts/examples/order-book/pair/src/events.rs +++ b/contracts/examples/order-book/pair/src/events.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; use super::common::{Order, OrderType}; diff --git a/contracts/examples/order-book/pair/src/global.rs b/contracts/examples/order-book/pair/src/global.rs index 371e661b71..9ed0718048 100644 --- a/contracts/examples/order-book/pair/src/global.rs +++ b/contracts/examples/order-book/pair/src/global.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; #[multiversx_sc::module] pub trait GlobalOperationModule { diff --git a/contracts/examples/order-book/pair/src/lib.rs b/contracts/examples/order-book/pair/src/lib.rs index e50b70c0e9..69e3a9f8c5 100644 --- a/contracts/examples/order-book/pair/src/lib.rs +++ b/contracts/examples/order-book/pair/src/lib.rs @@ -1,7 +1,6 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; mod common; mod events; diff --git a/contracts/examples/order-book/pair/src/orders.rs b/contracts/examples/order-book/pair/src/orders.rs index 65803fb495..1ec11afee4 100644 --- a/contracts/examples/order-book/pair/src/orders.rs +++ b/contracts/examples/order-book/pair/src/orders.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; use crate::common::{FEE_PENALTY_INCREASE_EPOCHS, FEE_PENALTY_INCREASE_PERCENT}; @@ -354,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/src/validation.rs b/contracts/examples/order-book/pair/src/validation.rs index 14f1478e1d..488edbdb24 100644 --- a/contracts/examples/order-book/pair/src/validation.rs +++ b/contracts/examples/order-book/pair/src/validation.rs @@ -1,5 +1,4 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; use crate::common::{FeeConfig, FeeConfigEnum}; 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 a9dc12297f..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,10 +2,9 @@ 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( - "file:output/order-book-pair.wasm", + "mxsc:output/order-book-pair.mxsc.json", order_book_pair::ContractBuilder, ); blockchain diff --git a/contracts/examples/order-book/pair/wasm/Cargo.lock b/contracts/examples/order-book/pair/wasm/Cargo.lock index 5b12e0670c..0a340293b6 100644 --- a/contracts/examples/order-book/pair/wasm/Cargo.lock +++ b/contracts/examples/order-book/pair/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,19 +98,13 @@ 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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "order-book-pair" version = "0.0.0" @@ -154,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/order-book/pair/wasm/Cargo.toml b/contracts/examples/order-book/pair/wasm/Cargo.toml index b2003b8cbd..ae2c10d4d8 100644 --- a/contracts/examples/order-book/pair/wasm/Cargo.toml +++ b/contracts/examples/order-book/pair/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "order-book-pair-wasm" version = "0.0.0" @@ -5,12 +11,7 @@ edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = [ ".",] - -[dev-dependencies] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -18,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.order-book-pair] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/order-book/pair/wasm/src/lib.rs b/contracts/examples/order-book/pair/wasm/src/lib.rs index 4342227175..2a4b058a13 100644 --- a/contracts/examples/order-book/pair/wasm/src/lib.rs +++ b/contracts/examples/order-book/pair/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 5b454c1745..787526a9ea 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/ping-pong-egld/README.md b/contracts/examples/ping-pong-egld/README.md new file mode 100644 index 0000000000..7fadb4a01f --- /dev/null +++ b/contracts/examples/ping-pong-egld/README.md @@ -0,0 +1,3 @@ +# PingPong + +`PingPong` is a simple Smart Contract. diff --git a/contracts/examples/ping-pong-egld/meta/Cargo.toml b/contracts/examples/ping-pong-egld/meta/Cargo.toml index 2c49afb5ae..71ff709c5f 100644 --- a/contracts/examples/ping-pong-egld/meta/Cargo.toml +++ b/contracts/examples/ping-pong-egld/meta/Cargo.toml @@ -1,13 +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.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/mxsc-template.toml b/contracts/examples/ping-pong-egld/mxsc-template.toml new file mode 100644 index 0000000000..403b768403 --- /dev/null +++ b/contracts/examples/ping-pong-egld/mxsc-template.toml @@ -0,0 +1,18 @@ +name = "ping-pong-egld" +contract_trait = "PingPong" +src_file = "ping_pong.rs" +rename_pairs = [ + [ + "blockchain.set_current_dir_from_workspace(\"contracts/examples/ping-pong-egld\");", + "// blockchain.set_current_dir_from_workspace(\"relative path to your workspace, if applicable\");", + ], +] +files_include = [ + "meta", + "scenarios", + "src", + "tests", + "Cargo.toml", + "README.md", + "multiversx.json", +] diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-after-deadline.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-after-deadline.scen.json index 24fb3ef5c9..8d27b65e46 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-after-deadline.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-after-deadline.scen.json @@ -57,7 +57,7 @@ "str:activationTimestamp": "780", "str:deadline": "123,780" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-before-activation.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-before-activation.scen.json index 89f93de0b1..37490334e9 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-before-activation.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-before-activation.scen.json @@ -57,7 +57,7 @@ "str:activationTimestamp": "780", "str:deadline": "123,780" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-before-beginning.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-before-beginning.scen.json index df83538fc2..862f552106 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-before-beginning.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-before-beginning.scen.json @@ -59,7 +59,7 @@ "str:activationTimestamp": "780", "str:deadline": "123,780" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-second-user.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-second-user.scen.json index fe4ea09e1a..fc9af8b7f7 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-second-user.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-second-user.scen.json @@ -63,7 +63,7 @@ "str:userStatus|0x0000002": "1", "str:user_count": "2" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-twice.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-twice.scen.json index 8d8843a979..6b36e51205 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-twice.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-twice.scen.json @@ -61,7 +61,7 @@ "str:userStatus|0x0000001": "1", "str:user_count": "1" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-wrong-ammount.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-wrong-ammount.scen.json index 76ff7127c7..b80ed7ad3b 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-wrong-ammount.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping-wrong-ammount.scen.json @@ -51,7 +51,7 @@ "str:activationTimestamp": "780", "str:deadline": "123,780" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping.scen.json index 88751bf945..78c5b08bd0 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-ping.scen.json @@ -62,7 +62,7 @@ "str:userStatus|0x0000001": "1", "str:user_count": "1" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-after-pong.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-after-pong.scen.json index f59d854a63..3575a5f292 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-after-pong.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-after-pong.scen.json @@ -62,7 +62,7 @@ "str:userStatus|0x0000001": "2", "str:user_count": "1" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-interrupted-1.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-interrupted-1.scen.json index c8ce0cdee4..2ab1990c83 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-interrupted-1.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all-interrupted-1.scen.json @@ -68,7 +68,7 @@ "str:user_count": "2", "str:pongAllLastUser": "0" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } }, 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 8673c8b8b1..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,500,000", + "gasLimit": "3,500,000", "gasPrice": "0" }, "expect": { @@ -44,7 +44,7 @@ }, "address:participant1": { "nonce": "2", - "balance": "1,800,000,000,000", + "balance": "1,300,000,000,000", "storage": {} }, "address:participant2": { @@ -54,21 +54,20 @@ }, "sc:ping-pong": { "nonce": "0", - "balance": "500,000,000,000", + "balance": "1,000,000,000,000", "storage": { "str:pingAmount": "500,000,000,000", "str:activationTimestamp": "780", "str:deadline": "123,780", "str:user_address_to_id|address:participant1": "1", "str:user_id_to_address|0x0000001": "address:participant1", - "str:userStatus|0x0000001": "2", + "str:userStatus|0x0000001": "1", "str:user_address_to_id|address:participant2": "2", "str:user_id_to_address|0x0000002": "address:participant2", "str:userStatus|0x0000002": "1", - "str:user_count": "2", - "str:pongAllLastUser": "1" + "str:user_count": "2" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } }, @@ -127,7 +126,7 @@ "str:userStatus|0x0000002": "2", "str:user_count": "2" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } }, diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all.steps.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all.steps.json index d9eb446aa7..da2ddbebcc 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all.steps.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-all.steps.json @@ -56,7 +56,7 @@ "str:userStatus|0x0000002": "2", "str:user_count": "2" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-before-deadline.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-before-deadline.scen.json index 4856e3d274..60c4610d32 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-before-deadline.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-before-deadline.scen.json @@ -60,7 +60,7 @@ "str:userStatus|0x0000001": "1", "str:user_count": "1" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-twice.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-twice.scen.json index 56f14fb477..a6e4bfb11f 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-twice.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-twice.scen.json @@ -54,7 +54,7 @@ "str:userStatus|0x0000001": "2", "str:user_count": "1" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-without-ping.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-without-ping.scen.json index b6816006c9..5a78c10956 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-without-ping.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong-without-ping.scen.json @@ -56,7 +56,7 @@ "str:activationTimestamp": "780", "str:deadline": "123,780" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong.scen.json index 572e0e4738..f7540b9a24 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-call-pong.scen.json @@ -60,7 +60,7 @@ "str:userStatus|0x0000001": "2", "str:user_count": "1" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/scenarios/ping-pong-init.scen.json b/contracts/examples/ping-pong-egld/scenarios/ping-pong-init.scen.json index f11c609c13..f730f35291 100644 --- a/contracts/examples/ping-pong-egld/scenarios/ping-pong-init.scen.json +++ b/contracts/examples/ping-pong-egld/scenarios/ping-pong-init.scen.json @@ -31,7 +31,7 @@ "id": "deploy", "tx": { "from": "address:my_address", - "contractCode": "file:../output/ping-pong-egld.wasm", + "contractCode": "mxsc:../output/ping-pong-egld.mxsc.json", "arguments": [ "500,000,000,000", "123,000", @@ -73,7 +73,7 @@ "str:activationTimestamp": "780", "str:deadline": "123,780" }, - "code": "file:../output/ping-pong-egld.wasm" + "code": "mxsc:../output/ping-pong-egld.mxsc.json" } } } diff --git a/contracts/examples/ping-pong-egld/src/ping_pong.rs b/contracts/examples/ping-pong-egld/src/ping_pong.rs index 26b5e74880..683c2a2ed5 100644 --- a/contracts/examples/ping-pong-egld/src/ping_pong.rs +++ b/contracts/examples/ping-pong-egld/src/ping_pong.rs @@ -1,6 +1,6 @@ #![no_std] -multiversx_sc::imports!(); +use multiversx_sc::imports::*; mod user_status; @@ -47,6 +47,9 @@ pub trait PingPong { self.max_funds().set(max_funds.into_option()); } + #[upgrade] + fn upgrade(&self) {} + /// User sends some EGLD to be locked in the contract for a period of time. /// Optional `_data` argument is ignored. #[payable("EGLD")] @@ -104,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/src/user_status.rs b/contracts/examples/ping-pong-egld/src/user_status.rs index d49da4b213..291981b0d7 100644 --- a/contracts/examples/ping-pong-egld/src/user_status.rs +++ b/contracts/examples/ping-pong-egld/src/user_status.rs @@ -1,4 +1,4 @@ -multiversx_sc::derive_imports!(); +use multiversx_sc::derive_imports::*; #[derive(TopEncode, TopDecode, TypeAbi, PartialEq, Eq, Clone, Copy)] pub enum UserStatus { 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 fb7c98bedb..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,10 +2,9 @@ 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( - "file:output/ping-pong-egld.wasm", + "mxsc:output/ping-pong-egld.mxsc.json", ping_pong_egld::ContractBuilder, ); blockchain diff --git a/contracts/examples/ping-pong-egld/wasm/Cargo.lock b/contracts/examples/ping-pong-egld/wasm/Cargo.lock index ab6919fbf0..538fba1557 100755 --- a/contracts/examples/ping-pong-egld/wasm/Cargo.lock +++ b/contracts/examples/ping-pong-egld/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,19 +98,13 @@ 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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "ping-pong-egld" version = "0.0.2" @@ -146,7 +114,7 @@ dependencies = [ [[package]] name = "ping-pong-egld-wasm" -version = "0.0.1" +version = "0.0.0" dependencies = [ "multiversx-sc-wasm-adapter", "ping-pong-egld", @@ -154,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/ping-pong-egld/wasm/Cargo.toml b/contracts/examples/ping-pong-egld/wasm/Cargo.toml index d1bb6ca604..7fad7880a3 100644 --- a/contracts/examples/ping-pong-egld/wasm/Cargo.toml +++ b/contracts/examples/ping-pong-egld/wasm/Cargo.toml @@ -1,14 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "ping-pong-egld-wasm" -version = "0.0.1" -authors = [ "Bruda Claudiu-Marcel ",] +version = "0.0.0" edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -16,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.ping-pong-egld] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/ping-pong-egld/wasm/src/lib.rs b/contracts/examples/ping-pong-egld/wasm/src/lib.rs index fffb64cbed..35bade6af2 100644 --- a/contracts/examples/ping-pong-egld/wasm/src/lib.rs +++ b/contracts/examples/ping-pong-egld/wasm/src/lib.rs @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 +// Upgrade: 1 // Endpoints: 10 // Async Callback (empty): 1 -// Total number of exported functions: 12 +// Total number of exported functions: 13 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { ping_pong_egld ( init => init + upgrade => upgrade ping => ping pong => pong pongAll => pong_all diff --git a/contracts/examples/proxy-pause/Cargo.toml b/contracts/examples/proxy-pause/Cargo.toml index 3a70ce4d61..4fbe63692b 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 3f6295b111..0bd4f2c3c7 100644 --- a/contracts/examples/proxy-pause/meta/Cargo.toml +++ b/contracts/examples/proxy-pause/meta/Cargo.toml @@ -3,13 +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.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/init.scen.json b/contracts/examples/proxy-pause/scenarios/init.scen.json index 98cb9830cc..e086e6e2ad 100644 --- a/contracts/examples/proxy-pause/scenarios/init.scen.json +++ b/contracts/examples/proxy-pause/scenarios/init.scen.json @@ -12,7 +12,7 @@ "sc:check-pause": { "nonce": "1", "balance": "0", - "code": "file:../../check-pause/output/check-pause.wasm", + "code": "mxsc:../../check-pause/output/check-pause.mxsc.json", "owner": "sc:proxy-pause" } }, @@ -29,7 +29,7 @@ "id": "1-deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/proxy-pause.wasm", + "contractCode": "mxsc:../output/proxy-pause.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/examples/proxy-pause/scenarios/pause-and-unpause.scen.json b/contracts/examples/proxy-pause/scenarios/pause-and-unpause.scen.json index 11ac973087..2204756cbf 100644 --- a/contracts/examples/proxy-pause/scenarios/pause-and-unpause.scen.json +++ b/contracts/examples/proxy-pause/scenarios/pause-and-unpause.scen.json @@ -22,7 +22,6 @@ "false" ], "status": "", - "logs": [], "gas": "*", "refund": "*" } @@ -41,7 +40,6 @@ "expect": { "out": [], "status": "", - "logs": [], "gas": "*", "refund": "*" } @@ -62,7 +60,6 @@ "true" ], "status": "", - "logs": [], "gas": "*", "refund": "*" } @@ -81,7 +78,6 @@ "expect": { "out": [], "status": "", - "logs": [], "gas": "*", "refund": "*" } @@ -102,7 +98,6 @@ "false" ], "status": "", - "logs": [], "gas": "*", "refund": "*" } 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 2a83923866..aa5f07e7d6 100644 --- a/contracts/examples/proxy-pause/src/proxy_pause.rs +++ b/contracts/examples/proxy-pause/src/proxy_pause.rs @@ -1,19 +1,7 @@ #![no_std] -multiversx_sc::imports!(); - -mod pause_proxy { - multiversx_sc::imports!(); - - #[multiversx_sc::proxy] - pub trait Pausable { - #[endpoint] - fn pause(&self); - - #[endpoint] - fn unpause(&self); - } -} +use multiversx_sc::imports::*; +pub mod pause_sc_proxy; #[multiversx_sc::contract] pub trait PauseProxy { @@ -48,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) { @@ -81,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 63d81f0fbd..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,12 +2,14 @@ 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("file:output/proxy-pause.wasm", proxy_pause::ContractBuilder); + blockchain.register_contract( + "mxsc:output/proxy-pause.mxsc.json", + proxy_pause::ContractBuilder, + ); blockchain.register_contract( - "file:../check-pause/output/check-pause.wasm", + "mxsc:../check-pause/output/check-pause.mxsc.json", check_pause::ContractBuilder, ); blockchain diff --git a/contracts/examples/proxy-pause/wasm/Cargo.lock b/contracts/examples/proxy-pause/wasm/Cargo.lock index 54ae01c907..bfb8efe9bc 100644 --- a/contracts/examples/proxy-pause/wasm/Cargo.lock +++ b/contracts/examples/proxy-pause/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,24 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -163,9 +131,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/proxy-pause/wasm/Cargo.toml b/contracts/examples/proxy-pause/wasm/Cargo.toml index e52b262ecc..dcb6fdeefb 100644 --- a/contracts/examples/proxy-pause/wasm/Cargo.toml +++ b/contracts/examples/proxy-pause/wasm/Cargo.toml @@ -1,17 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "proxy-pause-wasm" version = "0.0.0" -authors = [ "you",] edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = [ ".",] - -[dev-dependencies] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -19,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.proxy-pause] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/proxy-pause/wasm/src/lib.rs b/contracts/examples/proxy-pause/wasm/src/lib.rs index 74694867b2..e2a1a07417 100644 --- a/contracts/examples/proxy-pause/wasm/src/lib.rs +++ b/contracts/examples/proxy-pause/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 0a1d10b915..ce4d09995e 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/rewards-distribution/meta/Cargo.toml b/contracts/examples/rewards-distribution/meta/Cargo.toml index 1056013f43..99b1d29acf 100644 --- a/contracts/examples/rewards-distribution/meta/Cargo.toml +++ b/contracts/examples/rewards-distribution/meta/Cargo.toml @@ -10,6 +10,7 @@ authors = ["Claudiu-Marcel Bruda "] [dependencies.rewards-distribution] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 59672da272..7300fcaf88 100644 --- a/contracts/examples/rewards-distribution/src/rewards_distribution.rs +++ b/contracts/examples/rewards-distribution/src/rewards_distribution.rs @@ -1,24 +1,27 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; 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, @@ -40,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); @@ -176,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); @@ -267,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( @@ -418,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 { @@ -438,16 +446,3 @@ fn ticket_from_storage(position: u64, ticket_id: u64) -> u64 { ticket_id } } - -mod seed_nft_minter { - multiversx_sc::imports!(); - - #[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.rs b/contracts/examples/rewards-distribution/tests/mock_seed_nft_minter.rs index 0c7a12d297..d4312c8920 100644 --- a/contracts/examples/rewards-distribution/tests/mock_seed_nft_minter.rs +++ b/contracts/examples/rewards-distribution/tests/mock_seed_nft_minter.rs @@ -1,4 +1,4 @@ -multiversx_sc::imports!(); +use multiversx_sc::imports::*; #[multiversx_sc::contract] pub trait MockSeedNftMinter { 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 1305483959..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 = "file:output/rewards-distribution.wasm"; -const SEED_NFT_MINTER_ADDRESS_EXPR: &str = "sc:seed-nft-minter"; -const SEED_NFT_MINTER_PATH_EXPR: &str = "file:../seed-nft-minter/output/seed-nft-minter.wasm"; - -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..f9b64545bd --- /dev/null +++ b/contracts/examples/rewards-distribution/tests/rewards_distribution_integration_test.rs @@ -0,0 +1,304 @@ +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, 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, +} + +impl RewardsDistributionTestState { + fn new() -> Self { + let mut world = world(); + + world.account(OWNER_ADDRESS).nonce(1); + + Self { world } + } + + 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 + .tx() + .from(OWNER_ADDRESS) + .to(REWARDS_DISTRIBUTION_ADDRESS) + .whitebox(rewards_distribution::contract_obj, |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 edc7d068be..f2247ece99 100644 --- a/contracts/examples/rewards-distribution/wasm/Cargo.lock +++ b/contracts/examples/rewards-distribution/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,61 +34,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/rewards-distribution/wasm/Cargo.toml b/contracts/examples/rewards-distribution/wasm/Cargo.toml index 652e0b9c93..2273edf1c0 100644 --- a/contracts/examples/rewards-distribution/wasm/Cargo.toml +++ b/contracts/examples/rewards-distribution/wasm/Cargo.toml @@ -1,28 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "rewards-distribution-wasm" version = "0.0.0" -authors = ["Claudiu-Marcel Bruda "] edition = "2021" publish = false [lib] crate-type = ["cdylib"] -[workspace] -members = ["."] - -[dev-dependencies] - [profile.release] codegen-units = 1 opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.rewards-distribution] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/rewards-distribution/wasm/src/lib.rs b/contracts/examples/rewards-distribution/wasm/src/lib.rs index c5ad2e090a..34397de228 100644 --- a/contracts/examples/rewards-distribution/wasm/src/lib.rs +++ b/contracts/examples/rewards-distribution/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 37bf288eee..c983de4a98 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/seed-nft-minter/meta/Cargo.toml b/contracts/examples/seed-nft-minter/meta/Cargo.toml index 491ee7ae83..591c68f63c 100644 --- a/contracts/examples/seed-nft-minter/meta/Cargo.toml +++ b/contracts/examples/seed-nft-minter/meta/Cargo.toml @@ -10,6 +10,7 @@ authors = ["Claudiu-Marcel Bruda "] [dependencies.seed-nft-minter] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 df22a12919..54f8bf2586 100644 --- a/contracts/examples/seed-nft-minter/src/distribution_module.rs +++ b/contracts/examples/seed-nft-minter/src/distribution_module.rs @@ -1,9 +1,9 @@ -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +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, @@ -33,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 f24ea67fc3..a65a4175d7 100644 --- a/contracts/examples/seed-nft-minter/src/nft_module.rs +++ b/contracts/examples/seed-nft-minter/src/nft_module.rs @@ -1,7 +1,6 @@ use crate::distribution_module; -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; use multiversx_sc_modules::default_issue_callbacks; @@ -66,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 5e42c7a765..1a6ac5ffe2 100644 --- a/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs +++ b/contracts/examples/seed-nft-minter/src/seed_nft_minter.rs @@ -1,9 +1,9 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::{derive_imports::*, imports::*}; mod distribution_module; +pub mod nft_marketplace_proxy; mod nft_module; use distribution_module::Distribution; @@ -87,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() { @@ -114,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 { - 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 057f9d9648..1bb06b4df3 100644 --- a/contracts/examples/seed-nft-minter/wasm/Cargo.lock +++ b/contracts/examples/seed-nft-minter/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,61 +34,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/seed-nft-minter/wasm/Cargo.toml b/contracts/examples/seed-nft-minter/wasm/Cargo.toml index 2e8eb3ca47..dd696afd0a 100644 --- a/contracts/examples/seed-nft-minter/wasm/Cargo.toml +++ b/contracts/examples/seed-nft-minter/wasm/Cargo.toml @@ -1,17 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "seed-nft-minter-wasm" version = "0.0.0" -authors = ["Claudiu-Marcel Bruda "] edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = [ ".",] - -[dev-dependencies] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -19,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.seed-nft-minter] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/seed-nft-minter/wasm/src/lib.rs b/contracts/examples/seed-nft-minter/wasm/src/lib.rs index 4388b47b97..5f0e0090d6 100644 --- a/contracts/examples/seed-nft-minter/wasm/src/lib.rs +++ b/contracts/examples/seed-nft-minter/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 f0a3f35179..6c54444762 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/examples/token-release/meta/Cargo.toml b/contracts/examples/token-release/meta/Cargo.toml index c88211b8ec..82bd2039ca 100644 --- a/contracts/examples/token-release/meta/Cargo.toml +++ b/contracts/examples/token-release/meta/Cargo.toml @@ -9,7 +9,7 @@ publish = false [dependencies.token-release] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" - +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/test-add-group.scen.json b/contracts/examples/token-release/scenarios/test-add-group.scen.json index eebfeac6c5..d3d0083ae3 100644 --- a/contracts/examples/token-release/scenarios/test-add-group.scen.json +++ b/contracts/examples/token-release/scenarios/test-add-group.scen.json @@ -70,7 +70,7 @@ "5-release_ticks": "u64:4" } }, - "code": "file:../output/token-release.wasm" + "code": "mxsc:../output/token-release.mxsc.json" } } } diff --git a/contracts/examples/token-release/scenarios/test-add-user.scen.json b/contracts/examples/token-release/scenarios/test-add-user.scen.json index b6ffc71dcc..c689568590 100644 --- a/contracts/examples/token-release/scenarios/test-add-user.scen.json +++ b/contracts/examples/token-release/scenarios/test-add-user.scen.json @@ -96,7 +96,7 @@ "5-release_ticks": "u64:4" } }, - "code": "file:../output/token-release.wasm" + "code": "mxsc:../output/token-release.mxsc.json" } } } diff --git a/contracts/examples/token-release/scenarios/test-change-user.scen.json b/contracts/examples/token-release/scenarios/test-change-user.scen.json index d6df994358..59dbc4a2aa 100644 --- a/contracts/examples/token-release/scenarios/test-change-user.scen.json +++ b/contracts/examples/token-release/scenarios/test-change-user.scen.json @@ -125,7 +125,7 @@ "5-release_ticks": "u64:4" } }, - "code": "file:../output/token-release.wasm" + "code": "mxsc:../output/token-release.mxsc.json" } } } diff --git a/contracts/examples/token-release/scenarios/test-claim.scen.json b/contracts/examples/token-release/scenarios/test-claim.scen.json index 4098e14991..71ad0fc98a 100644 --- a/contracts/examples/token-release/scenarios/test-claim.scen.json +++ b/contracts/examples/token-release/scenarios/test-claim.scen.json @@ -115,7 +115,7 @@ "5-release_ticks": "u64:4" } }, - "code": "file:../output/token-release.wasm" + "code": "mxsc:../output/token-release.mxsc.json" } } } diff --git a/contracts/examples/token-release/scenarios/test-end-setup.scen.json b/contracts/examples/token-release/scenarios/test-end-setup.scen.json index 378eae1f48..8b515574ac 100644 --- a/contracts/examples/token-release/scenarios/test-end-setup.scen.json +++ b/contracts/examples/token-release/scenarios/test-end-setup.scen.json @@ -79,7 +79,7 @@ "5-release_ticks": "u64:4" } }, - "code": "file:../output/token-release.wasm" + "code": "mxsc:../output/token-release.mxsc.json" } } } diff --git a/contracts/examples/token-release/scenarios/test-init.scen.json b/contracts/examples/token-release/scenarios/test-init.scen.json index e0392c4f1c..8273a2ee25 100644 --- a/contracts/examples/token-release/scenarios/test-init.scen.json +++ b/contracts/examples/token-release/scenarios/test-init.scen.json @@ -37,7 +37,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/token-release.wasm", + "contractCode": "mxsc:../output/token-release.mxsc.json", "arguments": [ "str:FIRSTTOKEN-123456" ], @@ -76,7 +76,7 @@ "str:setupPeriodStatus": "1", "str:tokenIdentifier": "str:FIRSTTOKEN-123456" }, - "code": "file:../output/token-release.wasm" + "code": "mxsc:../output/token-release.mxsc.json" } } }, @@ -127,7 +127,7 @@ "str:setupPeriodStatus": "1", "str:tokenIdentifier": "str:FIRSTTOKEN-123456" }, - "code": "file:../output/token-release.wasm", + "code": "mxsc:../output/token-release.mxsc.json", "owner": "address:owner" } } diff --git a/contracts/examples/token-release/src/contract_data.rs b/contracts/examples/token-release/src/contract_data.rs index c40f1ac8a5..d224761986 100644 --- a/contracts/examples/token-release/src/contract_data.rs +++ b/contracts/examples/token-release/src/contract_data.rs @@ -1,6 +1,6 @@ use multiversx_sc::{api::ManagedTypeApi, types::BigUint}; -multiversx_sc::derive_imports!(); +use multiversx_sc::derive_imports::*; #[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, PartialEq, Eq, TypeAbi, Clone)] pub enum UnlockType { diff --git a/contracts/examples/token-release/src/token_release.rs b/contracts/examples/token-release/src/token_release.rs index d4f1eba44b..b0acd8a0e7 100644 --- a/contracts/examples/token-release/src/token_release.rs +++ b/contracts/examples/token-release/src/token_release.rs @@ -1,7 +1,6 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::imports::*; mod contract_data; @@ -313,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 ca1a7cad5a..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,10 +2,9 @@ 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( - "file:output/token-release.wasm", + "mxsc:output/token-release.mxsc.json", token_release::ContractBuilder, ); blockchain diff --git a/contracts/examples/token-release/wasm/Cargo.lock b/contracts/examples/token-release/wasm/Cargo.lock index bc79841bb7..6c4f299bb7 100644 --- a/contracts/examples/token-release/wasm/Cargo.lock +++ b/contracts/examples/token-release/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -167,26 +135,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" - -[[package]] -name = "syn" -version = "1.0.109" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "2.0.38" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -202,7 +159,7 @@ dependencies = [ [[package]] name = "token-release-wasm" -version = "0.0.1" +version = "0.0.0" dependencies = [ "multiversx-sc-wasm-adapter", "token-release", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/examples/token-release/wasm/Cargo.toml b/contracts/examples/token-release/wasm/Cargo.toml index 806bcd2da3..acb28e3e7c 100644 --- a/contracts/examples/token-release/wasm/Cargo.toml +++ b/contracts/examples/token-release/wasm/Cargo.toml @@ -1,14 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "token-release-wasm" -version = "0.0.1" -authors = [ "you",] +version = "0.0.0" edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -16,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.token-release] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/examples/token-release/wasm/src/lib.rs b/contracts/examples/token-release/wasm/src/lib.rs index 0e526c756c..4dd7699632 100644 --- a/contracts/examples/token-release/wasm/src/lib.rs +++ b/contracts/examples/token-release/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 fbd831887f..818273469f 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.44.0" +version = "0.53.0" path = "../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" -[dev-dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../framework/meta" +[dev-dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 a3e8556834..a011b156ba 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,12 +14,12 @@ }, "framework": { "name": "multiversx-sc", - "version": "0.44.0" + "version": "0.53.0" } }, "docs": [ "Contract whose sole purpose is to verify that", - "the ABI generation framework works sa expected.", + "the ABI generation framework works as expected.", "", "Note: any change in this contract must also be reflected in `abi_test_expected.abi.json`,", "including Rust 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,31 @@ } ] }, + { + "name": "operation_completion_status", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "OperationCompletionStatus" + } + ] + }, + { + "name": "takes_object_with_managed_buffer_read_to_end", + "mutability": "readonly", + "inputs": [ + { + "name": "arg", + "type": "AbiWithManagedBufferReadToEnd" + } + ], + "outputs": [ + { + "type": "bytes" + } + ] + }, { "name": "payable_egld", "mutability": "mutable", @@ -446,6 +487,22 @@ { "ticker": "OnlyInEsdt", "type": "OnlyShowsUpInEsdtAttr" + }, + { + "ticker": "ExplicitDiscriminant", + "type": "ExplicitDiscriminant" + }, + { + "ticker": "ExplicitDiscriminantMixed", + "type": "ExplicitDiscriminantMixed" + }, + { + "ticker": "ManagedDecimalVar", + "type": "ManagedDecimal" + }, + { + "ticker": "ManagedDecimalConst", + "type": "ManagedDecimalWrapper" } ], "hasCallback": false, @@ -566,6 +623,26 @@ } ] }, + "AbiWithManagedBufferReadToEnd": { + "type": "struct", + "docs": [ + "Its only purpose is to test that the ABI generator works fine." + ], + "fields": [ + { + "name": "endpoint", + "type": "bytes" + }, + { + "name": "gas", + "type": "u64" + }, + { + "name": "flush", + "type": "bytes-read-to-end" + } + ] + }, "EsdtLocalRole": { "type": "enum", "variants": [ @@ -690,6 +767,87 @@ } ] }, + "ExplicitDiscriminant": { + "type": "enum", + "docs": [ + "An enum with similar explicit discriminants" + ], + "variants": [ + { + "name": "Zero", + "discriminant": 0 + }, + { + "name": "Thirty", + "discriminant": 30 + }, + { + "name": "Twelve", + "discriminant": 12 + }, + { + "name": "Fifty", + "discriminant": 50 + }, + { + "name": "FiftyOne", + "discriminant": 51 + } + ] + }, + "ExplicitDiscriminantMixed": { + "type": "enum", + "docs": [ + "An enum with different explicit discriminants" + ], + "variants": [ + { + "name": "Zero", + "discriminant": 0 + }, + { + "name": "Unit", + "discriminant": 3 + }, + { + "name": "Tuple", + "discriminant": 4, + "fields": [ + { + "name": "0", + "type": "u16" + } + ] + }, + { + "name": "Five", + "discriminant": 5 + }, + { + "name": "Struct", + "discriminant": 1, + "fields": [ + { + "name": "a", + "type": "u8" + }, + { + "name": "b", + "type": "u16" + } + ] + } + ] + }, + "ManagedDecimalWrapper": { + "type": "struct", + "fields": [ + { + "name": "field", + "type": "ManagedDecimal<2>" + } + ] + }, "OnlyShowsUpAsNested01": { "type": "struct", "docs": [ @@ -830,6 +988,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 90266ddfde..0719553ee0 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,12 +14,12 @@ }, "framework": { "name": "multiversx-sc", - "version": "0.44.0" + "version": "0.53.0" } }, "docs": [ "Contract whose sole purpose is to verify that", - "the ABI generation framework works sa expected.", + "the ABI generation framework works as expected.", "", "Note: any change in this contract must also be reflected in `abi_test_expected.abi.json`,", "including Rust docs." @@ -123,6 +123,22 @@ { "ticker": "OnlyInEsdt", "type": "OnlyShowsUpInEsdtAttr" + }, + { + "ticker": "ExplicitDiscriminant", + "type": "ExplicitDiscriminant" + }, + { + "ticker": "ExplicitDiscriminantMixed", + "type": "ExplicitDiscriminantMixed" + }, + { + "ticker": "ManagedDecimalVar", + "type": "ManagedDecimal" + }, + { + "ticker": "ManagedDecimalConst", + "type": "ManagedDecimalWrapper" } ], "hasCallback": false, @@ -243,6 +259,26 @@ } ] }, + "AbiWithManagedBufferReadToEnd": { + "type": "struct", + "docs": [ + "Its only purpose is to test that the ABI generator works fine." + ], + "fields": [ + { + "name": "endpoint", + "type": "bytes" + }, + { + "name": "gas", + "type": "u64" + }, + { + "name": "flush", + "type": "bytes-read-to-end" + } + ] + }, "EsdtLocalRole": { "type": "enum", "variants": [ @@ -367,6 +403,87 @@ } ] }, + "ExplicitDiscriminant": { + "type": "enum", + "docs": [ + "An enum with similar explicit discriminants" + ], + "variants": [ + { + "name": "Zero", + "discriminant": 0 + }, + { + "name": "Thirty", + "discriminant": 30 + }, + { + "name": "Twelve", + "discriminant": 12 + }, + { + "name": "Fifty", + "discriminant": 50 + }, + { + "name": "FiftyOne", + "discriminant": 51 + } + ] + }, + "ExplicitDiscriminantMixed": { + "type": "enum", + "docs": [ + "An enum with different explicit discriminants" + ], + "variants": [ + { + "name": "Zero", + "discriminant": 0 + }, + { + "name": "Unit", + "discriminant": 3 + }, + { + "name": "Tuple", + "discriminant": 4, + "fields": [ + { + "name": "0", + "type": "u16" + } + ] + }, + { + "name": "Five", + "discriminant": 5 + }, + { + "name": "Struct", + "discriminant": 1, + "fields": [ + { + "name": "a", + "type": "u8" + }, + { + "name": "b", + "type": "u16" + } + ] + } + ] + }, + "ManagedDecimalWrapper": { + "type": "struct", + "fields": [ + { + "name": "field", + "type": "ManagedDecimal<2>" + } + ] + }, "OnlyShowsUpAsNested01": { "type": "struct", "docs": [ @@ -507,6 +624,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 d47adc3d81..bc634e03fa 100644 --- a/contracts/feature-tests/abi-tester/meta/Cargo.toml +++ b/contracts/feature-tests/abi-tester/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.abi-tester] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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_enum.rs b/contracts/feature-tests/abi-tester/src/abi_enum.rs index c43f0c4d0a..3b8db35407 100644 --- a/contracts/feature-tests/abi-tester/src/abi_enum.rs +++ b/contracts/feature-tests/abi-tester/src/abi_enum.rs @@ -9,3 +9,24 @@ pub enum AbiEnum { SomethingMore(u8, OnlyShowsUpAsNested08), SomeStruct { a: u16, b: OnlyShowsUpAsNested09 }, } + +/// An enum with similar explicit discriminants +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +pub enum ExplicitDiscriminant { + Zero, + Thirty = 30, + Twelve = 12, + Fifty = 50, + FiftyOne, +} + +/// An enum with different explicit discriminants +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi)] +#[repr(u8)] +pub enum ExplicitDiscriminantMixed { + Zero, + Unit = 3, + Tuple(u16), + Five, + Struct { a: u8, b: u16 } = 1, +} 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..c13a4a4e2d --- /dev/null +++ b/contracts/feature-tests/abi-tester/src/abi_proxy.rs @@ -0,0 +1,586 @@ +// 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 takes_object_with_managed_buffer_read_to_end< + Arg0: ProxyArg>, + >( + self, + arg: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("takes_object_with_managed_buffer_read_to_end") + .argument(&arg) + .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() + } +} + +#[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(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct AbiWithManagedBufferReadToEnd +where + Api: ManagedTypeApi, +{ + pub endpoint: ManagedBuffer, + pub gas: u64, + pub flush: ManagedBufferReadToEnd, +} + +#[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 2cc1fc4db4..fe5d3246d1 100644 --- a/contracts/feature-tests/abi-tester/src/abi_test_type.rs +++ b/contracts/feature-tests/abi-tester/src/abi_test_type.rs @@ -1,12 +1,13 @@ use crate::only_nested::*; use multiversx_sc::{ api::ManagedTypeApi, - types::{BigUint, Box, ManagedBuffer}, + types::{BigUint, Box, ConstDecimals, ManagedBuffer, ManagedBufferReadToEnd, ManagedDecimal}, }; 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,13 +30,30 @@ 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, } + +#[type_abi] +pub struct ManagedDecimalWrapper { + #[allow(dead_code)] + pub field: ManagedDecimal>, +} + +/// Its only purpose is to test that the ABI generator works fine. +#[type_abi] +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode)] +pub struct AbiWithManagedBufferReadToEnd { + pub endpoint: ManagedBuffer, + pub gas: u64, + pub flush: ManagedBufferReadToEnd, +} diff --git a/contracts/feature-tests/abi-tester/src/abi_tester.rs b/contracts/feature-tests/abi-tester/src/abi_tester.rs index 71e3b680fd..f5ce735a8c 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; @@ -11,7 +12,7 @@ use abi_test_type::*; use only_nested::*; /// Contract whose sole purpose is to verify that -/// the ABI generation framework works sa expected. +/// the ABI generation framework works as expected. /// /// Note: any change in this contract must also be reflected in `abi_test_expected.abi.json`, /// including Rust docs. @@ -22,12 +23,22 @@ use only_nested::*; #[esdt_attribute("STRUCT1", AbiEnum)] #[esdt_attribute("STRUCT2", AbiManagedType)] #[esdt_attribute("OnlyInEsdt", OnlyShowsUpInEsdtAttr)] +#[esdt_attribute("ExplicitDiscriminant", ExplicitDiscriminant)] +#[esdt_attribute("ExplicitDiscriminantMixed", ExplicitDiscriminantMixed)] +#[esdt_attribute("ManagedDecimalVar", ManagedDecimal)] +#[esdt_attribute("ManagedDecimalConst", ManagedDecimalWrapper)] pub trait AbiTester { /// Contract constructor. #[init] #[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")] @@ -156,6 +167,19 @@ pub trait AbiTester { None } + #[view] + fn operation_completion_status(&self) -> OperationCompletionStatus { + OperationCompletionStatus::Completed + } + + #[view] + fn takes_object_with_managed_buffer_read_to_end( + &self, + arg: AbiWithManagedBufferReadToEnd, + ) -> ManagedBuffer { + arg.flush.into_managed_buffer() + } + #[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 73e1f2fa60..dec0b4181e 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 @@ -17,41 +17,23 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 a8e0d34347..c20d1e1904 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 @@ -1,23 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "abi-tester-ev-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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.abi-tester] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 18c772a83b..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 957adc05ec..7bb4039082 100755 --- a/contracts/feature-tests/abi-tester/wasm/Cargo.lock +++ b/contracts/feature-tests/abi-tester/wasm/Cargo.lock @@ -17,41 +17,23 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/abi-tester/wasm/Cargo.toml b/contracts/feature-tests/abi-tester/wasm/Cargo.toml index bac39df607..2275167c26 100644 --- a/contracts/feature-tests/abi-tester/wasm/Cargo.toml +++ b/contracts/feature-tests/abi-tester/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "abi-tester-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.abi-tester] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 346df34aef..96d934bfa2 100644 --- a/contracts/feature-tests/abi-tester/wasm/src/lib.rs +++ b/contracts/feature-tests/abi-tester/wasm/src/lib.rs @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 27 +// Upgrade: 1 +// Endpoints: 29 // Async Callback (empty): 1 -// Total number of exported functions: 29 +// Total number of exported functions: 32 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,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 @@ -46,6 +44,8 @@ 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 + takes_object_with_managed_buffer_read_to_end => takes_object_with_managed_buffer_read_to_end 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 dbbd90397e..efb7e93a84 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.44.0" +version = "0.53.0" path = "../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 ecce1af911..6683a757a0 100644 --- a/contracts/feature-tests/alloc-features/meta/Cargo.toml +++ b/contracts/feature-tests/alloc-features/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.alloc-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/sc-config.toml b/contracts/feature-tests/alloc-features/sc-config.toml index d16a678ca5..afa78b123b 100644 --- a/contracts/feature-tests/alloc-features/sc-config.toml +++ b/contracts/feature-tests/alloc-features/sc-config.toml @@ -6,3 +6,13 @@ main = "alloc-features" add-unlabelled = true allocator = "static64k" stack-size = "32k" + +[contracts.alloc-mem-fail] +name = "alloc-mem-fail" +allocator = "fail" +add-labels = ["alloc-mem-fail"] + +[contracts.alloc-mem-leaking] +name = "alloc-mem-leaking" +allocator = "leaking" +add-labels = ["alloc-mem-leaking"] diff --git a/contracts/feature-tests/alloc-features/scenarios/alloc_mem_fail.scen.json b/contracts/feature-tests/alloc-features/scenarios/alloc_mem_fail.scen.json new file mode 100644 index 0000000000..5185e53638 --- /dev/null +++ b/contracts/feature-tests/alloc-features/scenarios/alloc_mem_fail.scen.json @@ -0,0 +1,39 @@ +{ + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:alloc-mem-fail": { + "nonce": "0", + "balance": "0", + "code": "file:../output/alloc-mem-fail.wasm" + }, + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scCall", + "id": "1", + "tx": { + "from": "address:an_account", + "to": "sc:alloc-mem-fail", + "function": "alloc_with_fail_memory", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:memory allocation forbidden", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} diff --git a/contracts/feature-tests/alloc-features/scenarios/alloc_mem_leaking.scen.json b/contracts/feature-tests/alloc-features/scenarios/alloc_mem_leaking.scen.json new file mode 100644 index 0000000000..0cae3b7303 --- /dev/null +++ b/contracts/feature-tests/alloc-features/scenarios/alloc_mem_leaking.scen.json @@ -0,0 +1,40 @@ +{ + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:alloc-mem-leaking": { + "nonce": "0", + "balance": "0", + "code": "file:../output/alloc-mem-leaking.wasm" + }, + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scCall", + "id": "1", + "tx": { + "from": "address:an_account", + "to": "sc:alloc-mem-leaking", + "function": "alloc_with_leaking_memory", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "1" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} diff --git a/contracts/feature-tests/alloc-features/scenarios/boxed_bytes_zeros.scen.json b/contracts/feature-tests/alloc-features/scenarios/boxed_bytes_zeros.scen.json index d0d31a7663..33e86d7432 100644 --- a/contracts/feature-tests/alloc-features/scenarios/boxed_bytes_zeros.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/boxed_bytes_zeros.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_async_result_empty.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_async_result_empty.scen.json index 7d0d74fb58..359d598b7a 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_async_result_empty.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_async_result_empty.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_big_int_nested_alloc.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_big_int_nested_alloc.scen.json index 4388cccbf0..a96d4c94c4 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_big_int_nested_alloc.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_big_int_nested_alloc.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "nonce": "*", "balance": "*", "storage": {}, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_boxed_bytes.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_boxed_bytes.scen.json index ef74e11856..1999f2fdae 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_boxed_bytes.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_boxed_bytes.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -71,7 +71,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "2", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_multi_value_tuples_alloc.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_multi_value_tuples_alloc.scen.json index c8a7ec9be2..7de219ba85 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_multi_value_tuples_alloc.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_multi_value_tuples_alloc.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_ser_ex_1.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_ser_ex_1.scen.json index 0717a5d7d2..c5c19db0b6 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_ser_ex_1.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_ser_ex_1.scen.json @@ -7,7 +7,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_slice_u8.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_slice_u8.scen.json index e98c42810f..f6ebd27ff7 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_slice_u8.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_slice_u8.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -71,7 +71,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "2", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_str.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_str.scen.json index 9c1ad6bbab..aa58fe565c 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_str.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_str.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_str_box.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_str_box.scen.json index d6049adae6..83294f04ca 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_str_box.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_str_box.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_string.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_string.scen.json index a7bdffb68c..771de8673f 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_string.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_string.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_varargs_u32_alloc.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_varargs_u32_alloc.scen.json index 910625476e..209997904e 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_varargs_u32_alloc.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_varargs_u32_alloc.scen.json @@ -7,7 +7,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/echo_vec_u8.scen.json b/contracts/feature-tests/alloc-features/scenarios/echo_vec_u8.scen.json index 89af972dd1..1d257ba8f6 100644 --- a/contracts/feature-tests/alloc-features/scenarios/echo_vec_u8.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/echo_vec_u8.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -71,7 +71,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "2", diff --git a/contracts/feature-tests/alloc-features/scenarios/managed_buffer_concat_2.scen.json b/contracts/feature-tests/alloc-features/scenarios/managed_buffer_concat_2.scen.json index 4ea91a35ea..0c05c39311 100644 --- a/contracts/feature-tests/alloc-features/scenarios/managed_buffer_concat_2.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/managed_buffer_concat_2.scen.json @@ -6,7 +6,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/managed_buffer_load_slice.scen.json b/contracts/feature-tests/alloc-features/scenarios/managed_buffer_load_slice.scen.json index 32a6d6ac64..400d13d0e9 100644 --- a/contracts/feature-tests/alloc-features/scenarios/managed_buffer_load_slice.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/managed_buffer_load_slice.scen.json @@ -6,7 +6,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/managed_buffer_overwrite.scen.json b/contracts/feature-tests/alloc-features/scenarios/managed_buffer_overwrite.scen.json index 7a1b652cd4..c35643017f 100644 --- a/contracts/feature-tests/alloc-features/scenarios/managed_buffer_overwrite.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/managed_buffer_overwrite.scen.json @@ -6,7 +6,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/managed_buffer_set_slice.scen.json b/contracts/feature-tests/alloc-features/scenarios/managed_buffer_set_slice.scen.json index 91586be839..5518c77f6d 100644 --- a/contracts/feature-tests/alloc-features/scenarios/managed_buffer_set_slice.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/managed_buffer_set_slice.scen.json @@ -6,7 +6,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/alloc-features/scenarios/only_owner_legacy.scen.json b/contracts/feature-tests/alloc-features/scenarios/only_owner_legacy.scen.json index 7ab1e5baa5..e60d5be50c 100644 --- a/contracts/feature-tests/alloc-features/scenarios/only_owner_legacy.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/only_owner_legacy.scen.json @@ -16,7 +16,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm", + "code": "mxsc:../output/alloc-features.mxsc.json", "owner": "address:owner" } } @@ -74,7 +74,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/alloc-features.wasm", + "code": "mxsc:../output/alloc-features.mxsc.json", "owner": "address:owner" }, "address:an_account": { 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 b608d270a1..b4fac3e261 100644 --- a/contracts/feature-tests/alloc-features/scenarios/sc_result.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/sc_result.scen.json @@ -6,7 +6,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -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/scenarios/storage_address.scen.json b/contracts/feature-tests/alloc-features/scenarios/storage_address.scen.json index 0c1662520b..8194fa47db 100644 --- a/contracts/feature-tests/alloc-features/scenarios/storage_address.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/storage_address.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "storage": { "str:addr": "str:____________address_____________" }, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/alloc-features/scenarios/storage_opt_address.scen.json b/contracts/feature-tests/alloc-features/scenarios/storage_opt_address.scen.json index e1234137e8..da423aa5dc 100644 --- a/contracts/feature-tests/alloc-features/scenarios/storage_opt_address.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/storage_opt_address.scen.json @@ -14,7 +14,7 @@ "str:____________address_too_long____________" ] }, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -36,7 +36,7 @@ "expect": { "out": [], "status": "4", - "message": "str:storage decode error: input too long", + "message": "str:storage decode error (key: opt_addr): input too long", "logs": "*", "gas": "*", "refund": "*" @@ -72,7 +72,7 @@ "storage": { "str:opt_addr": "1|str:____________address_____________" }, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "+": "" } @@ -168,7 +168,7 @@ "storage": { "str:opt_addr": "" }, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "+": "" } diff --git a/contracts/feature-tests/alloc-features/scenarios/storage_vec_u8.scen.json b/contracts/feature-tests/alloc-features/scenarios/storage_vec_u8.scen.json index 6a5dec1899..b47f2c3bde 100644 --- a/contracts/feature-tests/alloc-features/scenarios/storage_vec_u8.scen.json +++ b/contracts/feature-tests/alloc-features/scenarios/storage_vec_u8.scen.json @@ -8,7 +8,7 @@ "sc:alloc-features": { "nonce": "0", "balance": "0", - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "storage": { "str:vec_u8": "123" }, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -107,7 +107,7 @@ "storage": { "str:vec_u8": "0" }, - "code": "file:../output/alloc-features.wasm" + "code": "mxsc:../output/alloc-features.mxsc.json" }, "address:an_account": { "nonce": "*", 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 75485d8796..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!(); @@ -8,6 +7,7 @@ pub mod echo_managed_alloc; pub mod elliptic_curve_features_legacy; pub mod macro_features_legacy; pub mod managed_buffer_features_alloc; +pub mod memory_types; pub mod storage_direct_load_alloc; pub mod storage_direct_store_alloc; pub mod type_features_alloc; @@ -30,6 +30,7 @@ pub trait AllocFeatures: + storage_direct_load_alloc::StorageLoadFeatures + storage_direct_store_alloc::StorageStoreFeatures + type_features_alloc::AllocTypeFeatures + + memory_types::MemoryTypes { #[init] fn init(&self) {} diff --git a/contracts/feature-tests/alloc-features/src/echo_alloc.rs b/contracts/feature-tests/alloc-features/src/echo_alloc.rs index 22e334c229..39f7b185c0 100644 --- a/contracts/feature-tests/alloc-features/src/echo_alloc.rs +++ b/contracts/feature-tests/alloc-features/src/echo_alloc.rs @@ -2,9 +2,6 @@ multiversx_sc::imports!(); use crate::types::*; -// String is not part of the standard imports because we want to discourage its use -use multiversx_sc::types::String; - /// Test serialization for heap-allocated types. #[multiversx_sc::module] pub trait EchoAllocTypes { 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 3e91e7dec7..d5e5f5ef77 100644 --- a/contracts/feature-tests/alloc-features/src/macro_features_legacy.rs +++ b/contracts/feature-tests/alloc-features/src/macro_features_legacy.rs @@ -1,6 +1,6 @@ -multiversx_sc::imports!(); +#![allow(deprecated)] -use multiversx_sc::types::String; +multiversx_sc::imports!(); /// Legacy, deprecated macros. Will b removed once they get removed. /// @@ -11,12 +11,12 @@ pub trait MacroFeaturesLegacy { #[view] fn only_owner_legacy(&self) -> SCResult<()> { multiversx_sc::only_owner!(self, "Custom only owner message"); - Ok(()) + SCResult::Ok(()) } #[view] fn return_sc_error(&self) -> SCResult<()> { - sc_error!("return_sc_error") + multiversx_sc::sc_error!("return_sc_error") } #[view] @@ -25,18 +25,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()) } @@ -53,15 +42,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"))?; - 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")?; - Ok(unwrapped) + arg.ok_or("option argument is none").into() } #[endpoint] diff --git a/contracts/feature-tests/alloc-features/src/memory_types.rs b/contracts/feature-tests/alloc-features/src/memory_types.rs new file mode 100644 index 0000000000..50ee7ed4bb --- /dev/null +++ b/contracts/feature-tests/alloc-features/src/memory_types.rs @@ -0,0 +1,19 @@ +multiversx_sc::imports!(); + +/// Storage tests: direct load from storage to the heap. +#[multiversx_sc::module] +pub trait MemoryTypes { + #[endpoint] + #[label("alloc-mem-fail")] + fn alloc_with_fail_memory(&self) -> i32 { + let _x = String::from("H"); + 1 + } + + #[endpoint] + #[label("alloc-mem-leaking")] + fn alloc_with_leaking_memory(&self) -> i32 { + let _ = Box::new(42); + 1 + } +} diff --git a/contracts/feature-tests/alloc-features/tests/alloc_features_general_test.rs b/contracts/feature-tests/alloc-features/tests/alloc_features_general_test.rs index 5a17183dd2..2987b2d740 100644 --- a/contracts/feature-tests/alloc-features/tests/alloc_features_general_test.rs +++ b/contracts/feature-tests/alloc-features/tests/alloc_features_general_test.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + use multiversx_sc::types::{SCResult, StaticSCError}; use multiversx_sc_scenario::api::StaticApi; diff --git a/contracts/feature-tests/alloc-features/tests/alloc_features_scenario_go_test.rs b/contracts/feature-tests/alloc-features/tests/alloc_features_scenario_go_test.rs index 107a2aba38..b7c52c6c04 100644 --- a/contracts/feature-tests/alloc-features/tests/alloc_features_scenario_go_test.rs +++ b/contracts/feature-tests/alloc-features/tests/alloc_features_scenario_go_test.rs @@ -64,6 +64,16 @@ fn echo_vec_u_8_go() { world().run("scenarios/echo_vec_u8.scen.json"); } +#[test] +fn fail_memory_go() { + world().run("scenarios/alloc_mem_fail.scen.json"); +} + +#[test] +fn leaking_memory_go() { + world().run("scenarios/alloc_mem_leaking.scen.json"); +} + #[test] fn managed_buffer_concat_2_go() { world().run("scenarios/managed_buffer_concat_2.scen.json"); 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 69ad5b573f..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,15 +2,28 @@ 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_contract( - "file:output/alloc-features.wasm", + blockchain.register_partial_contract::( + "mxsc:output/alloc-features.mxsc.json", alloc_features::ContractBuilder, + "alloc-features", + ); + + blockchain.register_partial_contract::( + "mxsc:output/alloc-mem-fail.mxsc.json", + alloc_features::ContractBuilder, + "alloc-mem-fail", + ); + + blockchain.register_partial_contract::( + "mxsc:output/alloc-mem-leaking.mxsc.json", + alloc_features::ContractBuilder, + "alloc-mem-leaking", ); blockchain } + #[test] fn boxed_bytes_zeros_rs() { world().run("scenarios/boxed_bytes_zeros.scen.json"); @@ -71,6 +84,18 @@ fn echo_vec_u_8_rs() { world().run("scenarios/echo_vec_u8.scen.json"); } +#[test] +#[ignore] +fn fail_memory_rs() { + world().run("scenarios/alloc_mem_fail.scen.json"); +} + +#[test] +#[ignore] +fn leaking_memory_rs() { + world().run("scenarios/alloc_mem_leaking.scen.json"); +} + #[test] fn managed_buffer_concat_2_rs() { world().run("scenarios/managed_buffer_concat_2.scen.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 new file mode 100644 index 0000000000..53444451ec --- /dev/null +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.lock @@ -0,0 +1,178 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "alloc-features" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "alloc-mem-fail-wasm" +version = "0.0.0" +dependencies = [ + "alloc-features", + "multiversx-sc-wasm-adapter", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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.53.0" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.0" +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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +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/alloc-features/wasm-alloc-mem-fail/Cargo.toml b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.toml new file mode 100644 index 0000000000..69b3e410ec --- /dev/null +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/Cargo.toml @@ -0,0 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "alloc-mem-fail-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.alloc-features] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.53.0" +path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] 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 new file mode 100644 index 0000000000..f6acd5959c --- /dev/null +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-fail/src/lib.rs @@ -0,0 +1,87 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 63 +// Async Callback (empty): 1 +// Total number of exported functions: 65 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + alloc_features + ( + init => init + echo_h256 => echo_h256 + echo_boxed_array_u8 => echo_boxed_array_u8 + echo_boxed_bytes => echo_boxed_bytes + echo_slice_u8 => echo_slice_u8 + echo_vec_u8 => echo_vec_u8 + echo_string => echo_string + echo_str => echo_str + echo_str_box => echo_str_box + echo_async_result_empty => echo_async_result_empty + echo_large_boxed_byte_array => echo_large_boxed_byte_array + echo_boxed_ser_example_1 => echo_boxed_ser_example_1 + echo_multi_value_tuples => echo_multi_value_tuples + echo_ser_example_1 => echo_ser_example_1 + echo_vec_of_managed_buffer => echo_vec_of_managed_buffer + echo_big_int_vec => echo_big_int_vec + echo_varags_u32 => echo_varags_u32 + echo_varags_big_uint => echo_varags_big_uint + compute_get_values => compute_get_values + compute_create_ec => compute_create_ec + compute_get_ec_length => compute_get_ec_length + compute_get_priv_key_byte_length => compute_get_priv_key_byte_length + compute_ec_add => compute_ec_add + compute_ec_double => compute_ec_double + compute_is_on_curve_ec => compute_is_on_curve_ec + compute_scalar_mult => compute_scalar_mult + compute_scalar_base_mult => compute_scalar_base_mult + compute_marshal_ec => compute_marshal_ec + compute_marshal_compressed_ec => compute_marshal_compressed_ec + compute_unmarshal_ec => compute_unmarshal_ec + compute_unmarshal_compressed_ec => compute_unmarshal_compressed_ec + compute_generate_key_ec => compute_generate_key_ec + only_owner_legacy => only_owner_legacy + return_sc_error => return_sc_error + result_ok => result_ok + 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 + result_echo_2 => result_echo_2 + result_echo_3 => result_echo_3 + mbuffer_from_slice => mbuffer_from_slice + mbuffer_from_boxed_bytes => mbuffer_from_boxed_bytes + mbuffer_overwrite => mbuffer_overwrite + mbuffer_append_bytes => mbuffer_append_bytes + mbuffer_load_slice => mbuffer_load_slice + mbuffer_set_slice => mbuffer_set_slice + managed_address_from => managed_address_from + load_vec_u8 => load_vec_u8 + load_addr => load_addr + load_opt_addr => load_opt_addr + is_empty_opt_addr => is_empty_opt_addr + load_ser_1 => load_ser_1 + store_vec_u8 => store_vec_u8 + store_addr => store_addr + store_opt_addr => store_opt_addr + store_ser_1 => store_ser_1 + compare_h256 => compare_h256 + h256_is_zero => h256_is_zero + boxed_bytes_zeros => boxed_bytes_zeros + boxed_bytes_concat_2 => boxed_bytes_concat_2 + boxed_bytes_split => boxed_bytes_split + vec_concat_const => vec_concat_const + alloc_with_fail_memory => alloc_with_fail_memory + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} 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 new file mode 100644 index 0000000000..62cb854988 --- /dev/null +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.lock @@ -0,0 +1,178 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "alloc-features" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "alloc-mem-leaking-wasm" +version = "0.0.0" +dependencies = [ + "alloc-features", + "multiversx-sc-wasm-adapter", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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.53.0" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.0" +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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +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/alloc-features/wasm-alloc-mem-leaking/Cargo.toml b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.toml new file mode 100644 index 0000000000..a1196dc641 --- /dev/null +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/Cargo.toml @@ -0,0 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "alloc-mem-leaking-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.alloc-features] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.53.0" +path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] 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 new file mode 100644 index 0000000000..9056a19d65 --- /dev/null +++ b/contracts/feature-tests/alloc-features/wasm-alloc-mem-leaking/src/lib.rs @@ -0,0 +1,87 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 63 +// Async Callback (empty): 1 +// Total number of exported functions: 65 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(leaking); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + alloc_features + ( + init => init + echo_h256 => echo_h256 + echo_boxed_array_u8 => echo_boxed_array_u8 + echo_boxed_bytes => echo_boxed_bytes + echo_slice_u8 => echo_slice_u8 + echo_vec_u8 => echo_vec_u8 + echo_string => echo_string + echo_str => echo_str + echo_str_box => echo_str_box + echo_async_result_empty => echo_async_result_empty + echo_large_boxed_byte_array => echo_large_boxed_byte_array + echo_boxed_ser_example_1 => echo_boxed_ser_example_1 + echo_multi_value_tuples => echo_multi_value_tuples + echo_ser_example_1 => echo_ser_example_1 + echo_vec_of_managed_buffer => echo_vec_of_managed_buffer + echo_big_int_vec => echo_big_int_vec + echo_varags_u32 => echo_varags_u32 + echo_varags_big_uint => echo_varags_big_uint + compute_get_values => compute_get_values + compute_create_ec => compute_create_ec + compute_get_ec_length => compute_get_ec_length + compute_get_priv_key_byte_length => compute_get_priv_key_byte_length + compute_ec_add => compute_ec_add + compute_ec_double => compute_ec_double + compute_is_on_curve_ec => compute_is_on_curve_ec + compute_scalar_mult => compute_scalar_mult + compute_scalar_base_mult => compute_scalar_base_mult + compute_marshal_ec => compute_marshal_ec + compute_marshal_compressed_ec => compute_marshal_compressed_ec + compute_unmarshal_ec => compute_unmarshal_ec + compute_unmarshal_compressed_ec => compute_unmarshal_compressed_ec + compute_generate_key_ec => compute_generate_key_ec + only_owner_legacy => only_owner_legacy + return_sc_error => return_sc_error + result_ok => result_ok + 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 + result_echo_2 => result_echo_2 + result_echo_3 => result_echo_3 + mbuffer_from_slice => mbuffer_from_slice + mbuffer_from_boxed_bytes => mbuffer_from_boxed_bytes + mbuffer_overwrite => mbuffer_overwrite + mbuffer_append_bytes => mbuffer_append_bytes + mbuffer_load_slice => mbuffer_load_slice + mbuffer_set_slice => mbuffer_set_slice + managed_address_from => managed_address_from + load_vec_u8 => load_vec_u8 + load_addr => load_addr + load_opt_addr => load_opt_addr + is_empty_opt_addr => is_empty_opt_addr + load_ser_1 => load_ser_1 + store_vec_u8 => store_vec_u8 + store_addr => store_addr + store_opt_addr => store_opt_addr + store_ser_1 => store_ser_1 + compare_h256 => compare_h256 + h256_is_zero => h256_is_zero + boxed_bytes_zeros => boxed_bytes_zeros + boxed_bytes_concat_2 => boxed_bytes_concat_2 + boxed_bytes_split => boxed_bytes_split + vec_concat_const => vec_concat_const + alloc_with_leaking_memory => alloc_with_leaking_memory + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/contracts/feature-tests/alloc-features/wasm/Cargo.lock b/contracts/feature-tests/alloc-features/wasm/Cargo.lock index a7d34893c8..67b914f300 100644 --- a/contracts/feature-tests/alloc-features/wasm/Cargo.lock +++ b/contracts/feature-tests/alloc-features/wasm/Cargo.lock @@ -2,18 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "alloc-features" version = "0.0.0" @@ -31,27 +19,21 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/alloc-features/wasm/Cargo.toml b/contracts/feature-tests/alloc-features/wasm/Cargo.toml index 35a10e9264..3757b931a8 100644 --- a/contracts/feature-tests/alloc-features/wasm/Cargo.toml +++ b/contracts/feature-tests/alloc-features/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "alloc-features-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.alloc-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 b9a70a4985..3b8d0b84e3 100644 --- a/contracts/feature-tests/alloc-features/wasm/src/lib.rs +++ b/contracts/feature-tests/alloc-features/wasm/src/lib.rs @@ -1,20 +1,16 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 64 +// Endpoints: 62 // Async Callback (empty): 1 -// Total number of exported functions: 66 +// Total number of exported functions: 64 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); @@ -56,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 f9a89b42dd..6a512e08db 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" 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 3cc8861248..69597ba7e3 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.44.0" +version = "0.53.0" 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 652f15022c..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, @@ -61,13 +47,13 @@ impl BasicFeaturesInteract { .await; let wallet_address = interactor.register_wallet(test_wallets::mike()); let code_expr = BytesValue::interpret_from( - "file:../output/basic-features-storage-bytes.wasm", + "mxsc:../output/basic-features-storage-bytes.mxsc.json", &InterpreterContext::default(), ); 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 e809ffdeec..77577df1da 100644 --- a/contracts/feature-tests/basic-features/meta/Cargo.toml +++ b/contracts/feature-tests/basic-features/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.basic-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/sc-config.toml b/contracts/feature-tests/basic-features/sc-config.toml index c4bbf5062d..cdba7ce722 100644 --- a/contracts/feature-tests/basic-features/sc-config.toml +++ b/contracts/feature-tests/basic-features/sc-config.toml @@ -3,7 +3,28 @@ main = "basic-features" [contracts.basic-features] +[contracts.basic-features.profile] +overflow-checks = true # needed for overflow tests + [contracts.basic-features-storage-bytes] add-unlabelled = false add-endpoints = ["init", "load_bytes", "store_bytes"] kill_legacy_callback = true + +[contracts.basic-features-crypto] +ei = "1.4" +add-unlabelled = false +add-endpoints = ["init"] +add-labels = ["crypto-ei-1.4"] +kill_legacy_callback = true + +[[proxy]] +path = "src/basic_features_proxy.rs" +add-unlabelled = false +add-endpoints = [ + "init", + "store_bytes", + "load_bytes", + "returns_egld_decimal", + "echo_managed_option", +] diff --git a/contracts/feature-tests/basic-features/scenarios/big_int_from_i64.scen.json b/contracts/feature-tests/basic-features/scenarios/big_int_from_i64.scen.json index 05fbc74ae6..5c56a11590 100644 --- a/contracts/feature-tests/basic-features/scenarios/big_int_from_i64.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/big_int_from_i64.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/big_int_to_i64.scen.json b/contracts/feature-tests/basic-features/scenarios/big_int_to_i64.scen.json index d260e734b2..2a526cff5f 100644 --- a/contracts/feature-tests/basic-features/scenarios/big_int_to_i64.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/big_int_to_i64.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/big_num_conversions.scen.json b/contracts/feature-tests/basic-features/scenarios/big_num_conversions.scen.json index 3db2c9e308..ab207714f4 100644 --- a/contracts/feature-tests/basic-features/scenarios/big_num_conversions.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/big_num_conversions.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/big_uint_eq_u64.scen.json b/contracts/feature-tests/basic-features/scenarios/big_uint_eq_u64.scen.json index abb3d019b9..3b6e224ebf 100644 --- a/contracts/feature-tests/basic-features/scenarios/big_uint_eq_u64.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/big_uint_eq_u64.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/big_uint_from_u64.scen.json b/contracts/feature-tests/basic-features/scenarios/big_uint_from_u64.scen.json index 36310f2726..6083fac2e9 100644 --- a/contracts/feature-tests/basic-features/scenarios/big_uint_from_u64.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/big_uint_from_u64.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/big_uint_log2.json b/contracts/feature-tests/basic-features/scenarios/big_uint_log2.json index a7f03797b3..e4e6d5c974 100644 --- a/contracts/feature-tests/basic-features/scenarios/big_uint_log2.json +++ b/contracts/feature-tests/basic-features/scenarios/big_uint_log2.json @@ -9,7 +9,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -42,6 +42,54 @@ "gas": "*", "refund": "*" } + }, + { + "step": "scCall", + "id": "log2 from 1", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "value": "0", + "function": "log2_big_uint", + "arguments": [ + "1" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "log2 from 0", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "value": "0", + "function": "log2_big_uint", + "arguments": [ + "0" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/basic-features/scenarios/big_uint_pow.json b/contracts/feature-tests/basic-features/scenarios/big_uint_pow.scen.json similarity index 81% rename from contracts/feature-tests/basic-features/scenarios/big_uint_pow.json rename to contracts/feature-tests/basic-features/scenarios/big_uint_pow.scen.json index 39485016ff..378068fe2e 100644 --- a/contracts/feature-tests/basic-features/scenarios/big_uint_pow.json +++ b/contracts/feature-tests/basic-features/scenarios/big_uint_pow.scen.json @@ -8,14 +8,11 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", - "balance": "0", - "storage": {}, - "code": "" + "balance": "0" } } }, @@ -25,7 +22,6 @@ "tx": { "from": "address:an_account", "to": "sc:basic-features", - "value": "0", "function": "pow_big_uint", "arguments": [ "10", diff --git a/contracts/feature-tests/basic-features/scenarios/big_uint_sqrt.scen.json b/contracts/feature-tests/basic-features/scenarios/big_uint_sqrt.scen.json index fd89e697b3..b0bb89ea5e 100644 --- a/contracts/feature-tests/basic-features/scenarios/big_uint_sqrt.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/big_uint_sqrt.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/big_uint_to_u64.scen.json b/contracts/feature-tests/basic-features/scenarios/big_uint_to_u64.scen.json index 235a147280..545a3d2371 100644 --- a/contracts/feature-tests/basic-features/scenarios/big_uint_to_u64.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/big_uint_to_u64.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/block_info.scen.json b/contracts/feature-tests/basic-features/scenarios/block_info.scen.json index 555175d091..47dbc4f513 100644 --- a/contracts/feature-tests/basic-features/scenarios/block_info.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/block_info.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/codec_err.scen.json b/contracts/feature-tests/basic-features/scenarios/codec_err.scen.json index 5f03b8bdb6..025d91127f 100644 --- a/contracts/feature-tests/basic-features/scenarios/codec_err.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/codec_err.scen.json @@ -6,7 +6,7 @@ "step": "setState", "accounts": { "sc:basic-features": { - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": {} } @@ -53,7 +53,7 @@ "expect": { "out": [], "status": "4", - "message": "str:storage decode error: deliberate top decode error" + "message": "str:storage decode error (key: load_with_value_err): deliberate top decode error" } }, { diff --git a/contracts/feature-tests/basic-features/scenarios/count_ones.scen.json b/contracts/feature-tests/basic-features/scenarios/count_ones.scen.json index 22aae164ba..f15dfa3b12 100644 --- a/contracts/feature-tests/basic-features/scenarios/count_ones.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/count_ones.scen.json @@ -9,7 +9,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_elliptic_curves.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_elliptic_curves.scen.json index 306abac354..cf3dee28b0 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_elliptic_curves.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_elliptic_curves.scen.json @@ -7,7 +7,7 @@ "sc:features_contract": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_keccak256.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_keccak256.scen.json index 8ba030a518..e23758b0a7 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_keccak256.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_keccak256.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_ripemd160.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_ripemd160.scen.json index 6ff6b77d16..f049d09c97 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_ripemd160.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_ripemd160.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_sha256.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_sha256.scen.json index 936c86ab7a..b910566062 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_sha256.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_sha256.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls.scen.json index 76b5f8d7c2..fc67a3745b 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls.scen.json @@ -9,7 +9,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -19,7 +19,7 @@ }, { "step": "scCall", - "id": "3", + "id": "verify_bls_signature - Ok", "tx": { "from": "address:an_account", "to": "sc:basic-features", @@ -33,14 +33,36 @@ "gasPrice": "0" }, "expect": { - "out": [ - "0x01" - ], + "out": [], "status": "", "logs": "*", "gas": "*", "refund": "*" } + }, + { + "step": "scCall", + "id": "verify_bls_signature - Fail", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "verify_bls_signature", + "arguments": [ + "0xb5823f6e564251cc03ce7bad3da83e72576e92795d3500bba1acb30ec9a94dce87bb8aa794d67b2d61d15c33f28f6c0c23ba1dfcbf21e8f8b46286ff871afabac925303ddcaddce6254fcff6d3155797db40b3d3b5865e8fc0bd770b3d79b381", + "0x6d65737361676520746f206265207369676e6564", + "0x0032a2ddf341c08d1eb7232f05dc34e4454155e676b58c40fddf9a036562ac2c01533d2d557cb49d73aa9d7a89744696" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "10", + "message": "str:err blsSignatureDeserialize 0032a2ddf341c08d1eb7232f05dc34e4454155e676b58c40fddf9a036562ac2c01533d2d557cb49d73aa9d7a89744696", + "logs": "*", + "gas": "*", + "refund": "*" + } } ] } diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_aggregated_signature.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_aggregated_signature.scen.json new file mode 100644 index 0000000000..546c0d4c9f --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_aggregated_signature.scen.json @@ -0,0 +1,80 @@ +{ + "name": "crypto", + "comment": "does not currently work with scenarios-rs, because verify_bls function is not yet mocked", + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:basic-features-crypto": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features-crypto.mxsc.json" + }, + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scCall", + "id": "bls multi - ok", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features-crypto", + "function": "verify_bls_aggregated_signature", + "arguments": [ + [ + "nested:0x95f1d96b582f35294eb7dd4589b158e108e1d94cd0dd71ef16140e9b37126ec52dac6f57397f1e041acd7bb77df1d214f9f894e3b7fbf7abeaabc9fab8ff5c2ef05f9841322f301fdb900ac59479c334ac76a2d4ff992cd49bc9b530c25ee293", + "nested:0x97aa2862418eb4ea74fddcb511eef9b771e07ff901e7e6abb35847a4bb81e58f189fc9bce4186c6129014fb43002300e959702ef4b9d0c32ebe4d795457095d65b5414efb36edbb8dc66d84a445a92472d4a31cedd4700d5ebb885eb11d3430b", + "nested:0x37b73265936a2aaafe652a4dd451a1851c2dbbb32208604787479b31033e2a354615562ea2a5488f9134843362477a139050a0e798dd5ce0f01b35b8d473454ae99633aadde9237f84c87eb366144cca4de3d2cc6acc35e522a3294bf1186800", + "nested:0xf46c10d114dcd3019dd4bcd4152fda678c56144eb177c67a6411213b86e206e4e56a9aad1eab0313b13031fda046d715ec4a02612b083dfae0d82a23b643e1a89756c0df3d65c27e87a9c1289628d1a8404f0668a3d87c7451ba1c78fc452693", + "nested:0xaa0a97917df9240c537c89e873d7baa5ce1796e8fedfb23cf682b80fa19b8baae35af3754f9b8149985cb2a1fbda0f02c2942d2c99d9af556c9a5e90b8170e6a96379a45dd69351abfb814a16b5665abb7ddb8b096ee9f273de81845cda9728a" + ], + "str:message0", + "0xae12858363e8caa5b398d3febdd7bc01bc2fae1fef8f486ff4d84a5f3342f2d38085904eb10b73c0879a45d23585ce8f" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "bls multi - fail", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features-crypto", + "function": "verify_bls_aggregated_signature", + "arguments": [ + [ + "nested:0x95f1d96b582f35294eb7dd4589b158e108e1d94cd0dd71ef16140e9b37126ec52dac6f57397f1e041acd7bb77df1d214f9f894e3b7fbf7abeaabc9fab8ff5c2ef05f9841322f301fdb900ac59479c334ac76a2d4ff992cd49bc9b530c25ee293", + "nested:0x97aa2862418eb4ea74fddcb511eef9b771e07ff901e7e6abb35847a4bb81e58f189fc9bce4186c6129014fb43002300e959702ef4b9d0c32ebe4d795457095d65b5414efb36edbb8dc66d84a445a92472d4a31cedd4700d5ebb885eb11d3430b", + "nested:0x37b73265936a2aaafe652a4dd451a1851c2dbbb32208604787479b31033e2a354615562ea2a5488f9134843362477a139050a0e798dd5ce0f01b35b8d473454ae99633aadde9237f84c87eb366144cca4de3d2cc6acc35e522a3294bf1186800", + "nested:0xf46c10d114dcd3019dd4bcd4152fda678c56144eb177c67a6411213b86e206e4e56a9aad1eab0313b13031fda046d715ec4a02612b083dfae0d82a23b643e1a89756c0df3d65c27e87a9c1289628d1a8404f0668a3d87c7451ba1c78fc452693", + "nested:0xaa0a97917df9240c537c89e873d7baa5ce1796e8fedfb23cf682b80fa19b8baae35af3754f9b8149985cb2a1fbda0f02c2942d2c99d9af556c9a5e90b8170e6a96379a45dd69351abfb814a16b5665abb7ddb8b096ee9f273de81845cda9728a" + ], + "str:message0", + "0x0012858363e8caa5b398d3febdd7bc01bc2fae1fef8f486ff4d84a5f3342f2d38085904eb10b73c0879a45d23585ce8f" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "10", + "message": "str:err blsSignatureDeserialize 0012858363e8caa5b398d3febdd7bc01bc2fae1fef8f486ff4d84a5f3342f2d38085904eb10b73c0879a45d23585ce8f", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_share.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_share.scen.json new file mode 100644 index 0000000000..fa7c21611b --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_bls_share.scen.json @@ -0,0 +1,68 @@ +{ + "name": "crypto", + "comment": "does not currently work with scenarios-rs, because function is not yet mocked", + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:basic-features-crypto": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features-crypto.mxsc.json" + }, + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scCall", + "id": "verify_bls_signature_share - Ok", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features-crypto", + "function": "verify_bls_signature_share", + "arguments": [ + "0x3e886a4c6e109a151f4105aee65a5192d150ef1fa68d3cd76964a0b086006dbe4324c989deb0e4416c6d6706db1b1910eb2732f08842fb4886067b9ed191109ac2188d76002d2e11da80a3f0ea89fee6b59c834cc478a6bd49cb8a193b1abb16", + "0xe96bd0f36b70c5ccc0c4396343bd7d8255b8a526c55fa1e218511fafe6539b8e", + "0x04725db195e37aa237cdbbda76270d4a229b6e7a3651104dc58c4349c0388e8546976fe54a04240530b99064e434c90f" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "verify_bls_signature_share - Fail", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features-crypto", + "function": "verify_bls_signature_share", + "arguments": [ + "0x3e886a4c6e109a151f4105aee65a5192d150ef1fa68d3cd76964a0b086006dbe4324c989deb0e4416c6d6706db1b1910eb2732f08842fb4886067b9ed191109ac2188d76002d2e11da80a3f0ea89fee6b59c834cc478a6bd49cb8a193b1abb16", + "0xe96bd0f36b70c5ccc0c4396343bd7d8255b8a526c55fa1e218511fafe6539b8e", + "0xff725db195e37aa237cdbbda76270d4a229b6e7a3651104dc58c4349c0388e8546976fe54a04240530b99064e434c90f" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "10", + "message": "str:err blsSignatureDeserialize ff725db195e37aa237cdbbda76270d4a229b6e7a3651104dc58c4349c0388e8546976fe54a04240530b99064e434c90f", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_ed25519.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_ed25519.scen.json index d6cd549069..63fe079a72 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_verify_ed25519.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_ed25519.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256k1.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256k1.scen.json index e2eaec5525..7810299d50 100644 --- a/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256k1.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256k1.scen.json @@ -9,7 +9,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256r1.scen.json b/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256r1.scen.json new file mode 100644 index 0000000000..1c35b46271 --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/crypto_verify_secp256r1.scen.json @@ -0,0 +1,67 @@ +{ + "name": "crypto", + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:basic-features-crypto": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features-crypto.mxsc.json" + }, + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scCall", + "id": "secp256r1 - ok", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features-crypto", + "function": "verify_secp256r1_signature", + "arguments": [ + "0x02bc52274edebbef8878eacc4d1e0ed4fb213e5b0737389701ae8d59c403325720", + "0xbf9facf48b2219db73b50c7ff59ceef2ada56632c71afc555d6bb4072d7634d1d9353acd53517ffb9a06935a89a6454fcaa40c69becf9f8029a271fd252ea55307d00d6e97a30719d48d6b7f993af24e9c54381cba02a113238eaee9d741cababeb21aaf", + "0xc7877497444274267a4ea6f42deefde23a12e44f1ec1b437018e5c0e2834ce376dec1b81ebeacf5fbc6882e69af7cafad47bbb96cfb09e8d77d12afff7543052" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "secp256r1 - fail", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features-crypto", + "function": "verify_secp256r1_signature", + "arguments": [ + "0x02bc52274edebbef8878eacc4d1e0ed4fb213e5b0737389701ae8d59c403325720", + "0xbf9facf48b2219db73b50c7ff59ceef2ada56632c71afc555d6bb4072d7634d1d9353acd53517ffb9a06935a89a6454fcaa40c69becf9f8029a271fd252ea55307d00d6e97a30719d48d6b7f993af24e9c54381cba02a113238eaee9d741cababeb21aaf", + "0x00877497444274267a4ea6f42deefde23a12e44f1ec1b437018e5c0e2834ce376dec1b81ebeacf5fbc6882e69af7cafad47bbb96cfb09e8d77d12afff7543052" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "10", + "message": "str:signature verification failed", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/scenarios/echo_array_u8.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_array_u8.scen.json index 3136f8ef8b..51b779c8d1 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_array_u8.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_array_u8.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -68,7 +68,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "2", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_arrayvec.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_arrayvec.scen.json index 24cc10b42a..c77d3eda3b 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_arrayvec.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_arrayvec.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_big_int_nested.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_big_int_nested.scen.json index f7eed44828..d7e2e01a55 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_big_int_nested.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_big_int_nested.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -92,7 +92,7 @@ "nonce": "*", "balance": "*", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_big_int_top.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_big_int_top.scen.json index 8e9055850c..da94065821 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_big_int_top.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_big_int_top.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -230,7 +230,7 @@ "nonce": "*", "balance": "*", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_big_uint.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_big_uint.scen.json index 2cec2f82d4..480111ebb3 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_big_uint.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_big_uint.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -138,7 +138,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_i32.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_i32.scen.json index ad8ad4af9c..bf57566319 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_i32.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_i32.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -204,7 +204,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "8", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_i64.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_i64.scen.json index 25f9bfa7a4..5f56933939 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_i64.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_i64.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -227,7 +227,7 @@ "nonce": "*", "balance": "*", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_ignore.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_ignore.scen.json index d08702b108..e53e7b4fec 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_ignore.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_ignore.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_managed_async_result_empty.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_managed_async_result_empty.scen.json index 6d4870aa9a..a3e1167c7a 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_managed_async_result_empty.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_managed_async_result_empty.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_managed_bytes.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_managed_bytes.scen.json index 97989a6f2b..88dbe4b8ca 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_managed_bytes.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_managed_bytes.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_managed_vec.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_managed_vec.scen.json index f9b1f4a398..aca55e1466 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_managed_vec.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_managed_vec.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_multi_value_tuples.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_multi_value_tuples.scen.json index 77ad2753af..bf91b38357 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_multi_value_tuples.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_multi_value_tuples.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_nothing.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_nothing.scen.json index 6891130259..5d11936798 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_nothing.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_nothing.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_tuple_into_multiresult.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_tuple_into_multiresult.scen.json index edd45fa11d..65f186f6cc 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_tuple_into_multiresult.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_tuple_into_multiresult.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_u64.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_u64.scen.json index 96f0ad1238..9257892545 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_u64.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_u64.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -137,7 +137,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_usize.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_usize.scen.json index f50cfa91da..d99b969f21 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_usize.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_usize.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -137,7 +137,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_varargs_managed_eager.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_varargs_managed_eager.scen.json index 27d7d42bb7..d66af41a87 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_varargs_managed_eager.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_varargs_managed_eager.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_varargs_managed_sum.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_varargs_managed_sum.scen.json index 1d7b3efa62..ece4592cfe 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_varargs_managed_sum.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_varargs_managed_sum.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/echo_varargs_u32.scen.json b/contracts/feature-tests/basic-features/scenarios/echo_varargs_u32.scen.json index bdf80a8de3..55b1eb47c4 100644 --- a/contracts/feature-tests/basic-features/scenarios/echo_varargs_u32.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/echo_varargs_u32.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/events.scen.json b/contracts/feature-tests/basic-features/scenarios/events.scen.json index 4d1928e2d9..3f299401b8 100644 --- a/contracts/feature-tests/basic-features/scenarios/events.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/events.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -38,7 +38,9 @@ "topics": [ "str:event_a" ], - "data": "0" + "data": [ + "0" + ] } ], "gas": "*", @@ -68,7 +70,9 @@ "topics": [ "str:event_a" ], - "data": "0" + "data": [ + "0" + ] }, { "address": "*", @@ -76,7 +80,9 @@ "topics": [ "str:event_a" ], - "data": "1" + "data": [ + "1" + ] }, { "address": "sc:basic-features", @@ -84,7 +90,9 @@ "topics": [ "str:event_a" ], - "data": "2" + "data": [ + "2" + ] } ], "gas": "*", @@ -114,7 +122,9 @@ "topics": [ "str:event_a" ], - "data": "0" + "data": [ + "0" + ] }, "+" ], @@ -151,8 +161,10 @@ "str:arg2_an_address_______________s3" ], "data": [ - "biguint:1", - "biguint:2" + [ + "biguint:1", + "biguint:2" + ] ] } ], diff --git a/contracts/feature-tests/basic-features/scenarios/get_caller.scen.json b/contracts/feature-tests/basic-features/scenarios/get_caller.scen.json index 85990b93fb..9e659b2bfc 100644 --- a/contracts/feature-tests/basic-features/scenarios/get_caller.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/get_caller.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/get_code_metadata.scen.json b/contracts/feature-tests/basic-features/scenarios/get_code_metadata.scen.json new file mode 100644 index 0000000000..e60601f359 --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/get_code_metadata.scen.json @@ -0,0 +1,90 @@ +{ + "steps": [ + { + "step": "setState", + "accounts": { + "sc:basic-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features.mxsc.json", + "codeMetadata": "0x0104" + }, + "sc:basic-features-2": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features.mxsc.json", + "codeMetadata": "0x0100" + }, + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scCall", + "id": "get_code_metadata", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "get_code_metadata", + "arguments": [ + "sc:basic-features" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x0104" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "get_code_metadata-2", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "get_code_metadata", + "arguments": [ + "sc:basic-features-2" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x0100" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "get_code_metadata-missing-address", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "get_code_metadata", + "arguments": [ + "sc:missing" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "10", + "message": "str:account not found: 000000000000000005006d697373696e675f5f5f5f5f5f5f5f5f5f5f5f5f5f5f" + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/scenarios/get_cumulated_validator_rewards.scen.json b/contracts/feature-tests/basic-features/scenarios/get_cumulated_validator_rewards.scen.json index 2ae50abaed..8fae020595 100644 --- a/contracts/feature-tests/basic-features/scenarios/get_cumulated_validator_rewards.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/get_cumulated_validator_rewards.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:viewer": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/get_shard_of_address.scen.json b/contracts/feature-tests/basic-features/scenarios/get_shard_of_address.scen.json index 55df0c8647..1aaf838611 100644 --- a/contracts/feature-tests/basic-features/scenarios/get_shard_of_address.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/get_shard_of_address.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -23,7 +23,9 @@ "from": "address:an_account", "to": "sc:basic-features", "function": "get_shard_of_address", - "arguments": ["sc:basic-features"], + "arguments": [ + "sc:basic-features" + ], "gasLimit": "50,000,000", "gasPrice": "0" }, @@ -43,7 +45,9 @@ "tx": { "to": "sc:basic-features", "function": "get_shard_of_address", - "arguments": ["sc:basic-features"] + "arguments": [ + "sc:basic-features" + ] }, "expect": { "out": [ diff --git a/contracts/feature-tests/basic-features/scenarios/is_builtin_function.scen.json b/contracts/feature-tests/basic-features/scenarios/is_builtin_function.scen.json new file mode 100644 index 0000000000..dde9bc8887 --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/is_builtin_function.scen.json @@ -0,0 +1,65 @@ +{ + "steps": [ + { + "step": "setState", + "accounts": { + "sc:basic-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features.mxsc.json", + "codeMetadata": "0x0104" + }, + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scCall", + "id": "is builtin function - true", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "is_builtin_function", + "arguments": [ + "str:ESDTTransfer" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x01" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "is builtin function - false", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "is_builtin_function", + "arguments": [ + "str:anyFunction" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/scenarios/managed_address_array.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_address_array.scen.json index 309844fb09..ac0810369d 100644 --- a/contracts/feature-tests/basic-features/scenarios/managed_address_array.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/managed_address_array.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/managed_address_managed_buffer.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_address_managed_buffer.scen.json index 80e63c2f85..0b8af730e2 100644 --- a/contracts/feature-tests/basic-features/scenarios/managed_address_managed_buffer.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/managed_address_managed_buffer.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/managed_buffer_concat.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_buffer_concat.scen.json index c698ccdda5..2b3a866b42 100644 --- a/contracts/feature-tests/basic-features/scenarios/managed_buffer_concat.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/managed_buffer_concat.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/managed_buffer_copy_slice.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_buffer_copy_slice.scen.json index e6837ef855..52ff3bcbfd 100644 --- a/contracts/feature-tests/basic-features/scenarios/managed_buffer_copy_slice.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/managed_buffer_copy_slice.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/managed_buffer_eq.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_buffer_eq.scen.json index ee171cd386..823abd84eb 100644 --- a/contracts/feature-tests/basic-features/scenarios/managed_buffer_eq.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/managed_buffer_eq.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/managed_buffer_set_random.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_buffer_set_random.scen.json index 66f06f1ee8..52d73f9ac9 100644 --- a/contracts/feature-tests/basic-features/scenarios/managed_buffer_set_random.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/managed_buffer_set_random.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/managed_decimal.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_decimal.scen.json new file mode 100644 index 0000000000..479b8931c3 --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/managed_decimal.scen.json @@ -0,0 +1,232 @@ +{ + "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": "scCall", + "id": "1", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_addition", + "arguments": [ + "4", + "5" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "9" + ] + } + }, + { + "step": "scCall", + "id": "1", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_subtraction", + "arguments": [ + "9", + "4" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "5" + ] + } + }, + { + "step": "scCall", + "id": "2", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_subtraction", + "arguments": [ + "2", + "8" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:cannot subtract because result would be negative", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "3", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_eq", + "arguments": [ + "13", + "13" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x01" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "4", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_trunc", + "arguments": [], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "313" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "5", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_into_raw_units", + "arguments": [], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "12345" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "6", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_addition_var", + "arguments": [ + "biguint:4|u32:2", + "biguint:5|u32:2" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "biguint:9|u32:2" + ] + } + }, + { + "step": "scCall", + "id": "7", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_subtraction_var", + "arguments": [ + "biguint:9|u32:2", + "biguint:4|u32:2" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "biguint:5|u32:2" + ] + } + }, + { + "step": "scCall", + "id": "8", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_subtraction_var", + "arguments": [ + "biguint:2|u32:2", + "biguint:8|u32:2" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:cannot subtract because result would be negative", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "9", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_eq_var", + "arguments": [ + "biguint:11|u32:2", + "biguint:11|u32:2" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "true" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + } + ] +} \ No newline at end of file diff --git a/contracts/feature-tests/basic-features/scenarios/managed_decimal_logarithm.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_decimal_logarithm.scen.json new file mode 100644 index 0000000000..6ee41eaa4d --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/managed_decimal_logarithm.scen.json @@ -0,0 +1,202 @@ +{ + "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": "scCall", + "id": "managed_decimal_ln(23)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_ln", + "arguments": [ + "23,000000000" + ], + "gasLimit": "25,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "+3,135553845" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "managed_decimal_ln(378,298)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_ln", + "arguments": [ + "378,298000000" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x0161cc16aa" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "managed_decimal_log2(23)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_log2", + "arguments": [ + "23,000000000" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "4,523648008" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "managed_decimal_log2(218,345)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_log2", + "arguments": [ + "218,345000000" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "7,770385327" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "managed_decimal_log2_var(23)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_log2_var", + "arguments": [ + "0x00000005055ae8260000000009" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "4,523648008" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "managed_decimal_ln_var(23)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_ln_var", + "arguments": [ + "0x00000005055ae8260000000009" + ], + "gasLimit": "25,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "+3,135553845" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "managed_decimal_ln_var(378,298)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_ln_var", + "arguments": [ + "0x00000005581451628000000009" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x0161cc16aa" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "managed_decimal_log2_var(218,345)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "managed_decimal_log2_var", + "arguments": [ + "0x0000000532d6604c4000000009" + ], + "gasLimit": "1,000,000,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "7,770385327" + ], + "status": "", + "message": "*", + "gas": "*", + "refund": "*" + } + } + ] +} \ No newline at end of file diff --git a/contracts/feature-tests/basic-features/scenarios/managed_vec_address_push.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_vec_address_push.scen.json index f9d179e635..eb5b33c456 100644 --- a/contracts/feature-tests/basic-features/scenarios/managed_vec_address_push.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/managed_vec_address_push.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", 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 7966e1c8b5..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": "file:../output/basic-features.wasm" - }, - "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/managed_vec_biguint_push.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_vec_biguint_push.scen.json index 8bbad52ddd..0d3ef768e4 100644 --- a/contracts/feature-tests/basic-features/scenarios/managed_vec_biguint_push.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/managed_vec_biguint_push.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/new_address.scen.json b/contracts/feature-tests/basic-features/scenarios/new_address.scen.json new file mode 100644 index 0000000000..a37eb2db30 --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/new_address.scen.json @@ -0,0 +1,48 @@ +{ + "steps": [ + { + "step": "setState", + "accounts": { + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scDeploy", + "id": "deploy", + "tx": { + "from": "address:an_account", + "contractCode": "mxsc:../output/basic-features.mxsc.json", + "arguments": [], + "gasLimit": "200,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": [], + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:an_account": { + "nonce": "*", + "balance": "0", + "storage": {}, + "code": "" + }, + "0x0000000000000000050011111111616e5f6163636f756e745f5f5f5f5f005f5f": { + "nonce": "0", + "balance": "0", + "storage": {}, + "code": "mxsc:../output/basic-features.mxsc.json" + } + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/scenarios/only_owner.scen.json b/contracts/feature-tests/basic-features/scenarios/only_owner.scen.json index 0e0a943710..cb977da246 100644 --- a/contracts/feature-tests/basic-features/scenarios/only_owner.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/only_owner.scen.json @@ -16,7 +16,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm", + "code": "mxsc:../output/basic-features.mxsc.json", "owner": "address:owner" } } @@ -74,7 +74,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm", + "code": "mxsc:../output/basic-features.mxsc.json", "owner": "address:owner" }, "address:an_account": { diff --git a/contracts/feature-tests/basic-features/scenarios/only_user_account.scen.json b/contracts/feature-tests/basic-features/scenarios/only_user_account.scen.json index ac24e2a36a..c7ee531d31 100644 --- a/contracts/feature-tests/basic-features/scenarios/only_user_account.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/only_user_account.scen.json @@ -12,12 +12,12 @@ "sc:evil-caller-sc": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, diff --git a/contracts/feature-tests/basic-features/scenarios/out_of_gas.scen.json b/contracts/feature-tests/basic-features/scenarios/out_of_gas.scen.json index ef19a23859..b7c9dd2c1a 100644 --- a/contracts/feature-tests/basic-features/scenarios/out_of_gas.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/out_of_gas.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/panic.scen.json b/contracts/feature-tests/basic-features/scenarios/panic.scen.json index 011efc8287..b3031c6fe0 100644 --- a/contracts/feature-tests/basic-features/scenarios/panic.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/panic.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -43,7 +43,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "1", diff --git a/contracts/feature-tests/basic-features/scenarios/return_codes.scen.json b/contracts/feature-tests/basic-features/scenarios/return_codes.scen.json index 0760f26fca..0f15a7d168 100644 --- a/contracts/feature-tests/basic-features/scenarios/return_codes.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/return_codes.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/sc_properties.scen.json b/contracts/feature-tests/basic-features/scenarios/sc_properties.scen.json index 787d2a3f1a..6585664181 100644 --- a/contracts/feature-tests/basic-features/scenarios/sc_properties.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/sc_properties.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm", + "code": "mxsc:../output/basic-features.mxsc.json", "owner": "address:someone_else" }, "address:an_account": { @@ -75,7 +75,7 @@ "id": "1", "tx": { "from": "address:an_account", - "contractCode": "file:../output/basic-features.wasm", + "contractCode": "mxsc:../output/basic-features.mxsc.json", "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" @@ -121,7 +121,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm", + "code": "mxsc:../output/basic-features.mxsc.json", "owner": "address:someone_else" }, "address:an_account": { @@ -134,7 +134,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm", + "code": "mxsc:../output/basic-features.mxsc.json", "owner": "address:an_account" } } diff --git a/contracts/feature-tests/basic-features/scenarios/small_num_overflow.scen.json b/contracts/feature-tests/basic-features/scenarios/small_num_overflow.scen.json new file mode 100644 index 0000000000..d81ffc5306 --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/small_num_overflow.scen.json @@ -0,0 +1,430 @@ +{ + "name": "overflow", + "gasSchedule": "v3", + "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": "scCall", + "id": "no_overflow_u8", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_u8", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_u8", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_u8", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "no_overflow_i8", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_i8", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_i8", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_i8", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "-2" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "no_overflow_u16", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_u16", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_u16", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_u16", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "no_overflow_i16", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_i16", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_i16", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_i16", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "-2" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "no_overflow_u32", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_u32", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_u32", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_u32", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "no_overflow_i32", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_i32", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_i32", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_i32", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "-2" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "no_overflow_u64", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_u64", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_u64", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_u64", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "no_overflow_i64", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_i64", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_i64", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_i64", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "-2" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "no_overflow_usize", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_usize", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_usize", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_usize", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "no_overflow_isize", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "no_overflow_isize", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:panic occurred", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "overflow_isize", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "overflow_isize", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "-2" + ], + "status": "0", + "logs": "*", + "gas": "*", + "refund": "*" + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/scenarios/storage_big_int.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_big_int.scen.json index 36d2415114..4f2e6f23e2 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_big_int.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_big_int.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "storage": { "str:big_int": "123" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -107,7 +107,7 @@ "storage": { "str:big_int": "0" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_big_uint.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_big_uint.scen.json index 4740549fba..e2896b0e1f 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_big_uint.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_big_uint.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "storage": { "str:big_uint": "123" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -107,7 +107,7 @@ "storage": { "str:big_uint": "0" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_bool.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_bool.scen.json index c5601f3df4..1d8f9fda39 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_bool.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_bool.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "storage": { "str:bool": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -107,7 +107,7 @@ "storage": { "str:bool": "false" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_clear.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_clear.scen.json index b8d13db78e..9b844953f9 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_clear.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_clear.scen.json @@ -11,7 +11,7 @@ "storage": { "str:nr_to_clear": "42" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -66,7 +66,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "2", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_i64.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_i64.scen.json index 589c9e1a5e..d9f3bc0ec9 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_i64.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_i64.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "storage": { "str:i64": "123" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -107,7 +107,7 @@ "storage": { "str:i64": "0" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", 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 a43426b22c..6fb3ab0c59 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 @@ -11,7 +11,7 @@ "storage": { "str:i64": "0x008000000000000000" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -33,7 +33,7 @@ "expect": { "out": [], "status": "*", - "message": "str:storage decode error: input too long", + "message": "str:storage decode error (key: i64): argument out of range", "logs": "*", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/basic-features/scenarios/storage_load_from_address.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_load_from_address.scen.json index 7df71919bf..300113dc1d 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_load_from_address.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_load_from_address.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:external-contract": { "nonce": "0", @@ -16,7 +16,7 @@ "storage": { "str:external-key": "str:external-value" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_managed_address.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_managed_address.scen.json index 5280f8cbce..deb20bc061 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_managed_address.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_managed_address.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "storage": { "str:addr": "str:____________address_____________" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_map1.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_map1.scen.json index 32439e97cb..95afef9271 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_map1.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_map1.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -47,7 +47,7 @@ "storage": { "str:map1__________address_1_____________": "123" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -111,7 +111,7 @@ "storage": { "str:map1__________address_1_____________": "0" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_map2.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_map2.scen.json index 53c4a0132b..26e36e4f96 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_map2.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_map2.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -48,7 +48,7 @@ "storage": { "str:map2|str:__________address_1_____________|str:__________address_2_____________": "123" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -114,7 +114,7 @@ "storage": { "str:map2|str:__________address_1_____________|str:__________address_2_____________": "0" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_map3.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_map3.scen.json index 397186d2be..0dcaee928a 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_map3.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_map3.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -47,7 +47,7 @@ "storage": { "str:map3|0x00000057": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -111,7 +111,7 @@ "storage": { "str:map3|0x00000057": "false" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_address_to_id.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_address_to_id.scen.json index 975534a92e..91493a8d0c 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_address_to_id.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_address_to_id.scen.json @@ -8,12 +8,12 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_fungible_token.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_fungible_token.scen.json index 2651b97cca..190b33f2aa 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_fungible_token.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_fungible_token.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -30,7 +30,7 @@ ] } }, - "code": "file:../../esdt-system-sc-mock/output/esdt-system-sc-mock.wasm" + "code": "mxsc:../../esdt-system-sc-mock/output/esdt-system-sc-mock.mxsc.json" } } }, @@ -68,7 +68,7 @@ "storage": { "str:fungibleTokenMapper": "str:TICKER-000000" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -94,7 +94,7 @@ "storage": { "str:nrIssuedTokens": "1" }, - "code": "file:../../esdt-system-sc-mock/output/esdt-system-sc-mock.wasm" + "code": "mxsc:../../esdt-system-sc-mock/output/esdt-system-sc-mock.mxsc.json" } } }, @@ -111,7 +111,7 @@ "storage": { "str:fungibleTokenMapper": "" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, @@ -151,7 +151,7 @@ "storage": { "str:fungibleTokenMapper": "str:TICKER-111111" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -177,7 +177,7 @@ "storage": { "str:nrIssuedTokens": "2" }, - "code": "file:../../esdt-system-sc-mock/output/esdt-system-sc-mock.wasm" + "code": "mxsc:../../esdt-system-sc-mock/output/esdt-system-sc-mock.mxsc.json" } } }, @@ -194,7 +194,7 @@ "storage": { "str:fungibleTokenMapper": "" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, @@ -233,7 +233,7 @@ "storage": { "str:fungibleTokenMapper": "str:TICKER-222222" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -259,7 +259,7 @@ "storage": { "str:nrIssuedTokens": "3" }, - "code": "file:../../esdt-system-sc-mock/output/esdt-system-sc-mock.wasm" + "code": "mxsc:../../esdt-system-sc-mock/output/esdt-system-sc-mock.mxsc.json" } } }, @@ -277,7 +277,7 @@ "storage": { "str:fungibleTokenMapper": "" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, @@ -318,7 +318,7 @@ "storage": { "str:fungibleTokenMapper": "str:TICKER-333333" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -344,7 +344,7 @@ "storage": { "str:nrIssuedTokens": "4" }, - "code": "file:../../esdt-system-sc-mock/output/esdt-system-sc-mock.wasm" + "code": "mxsc:../../esdt-system-sc-mock/output/esdt-system-sc-mock.mxsc.json" } } }, @@ -361,7 +361,7 @@ "storage": { "str:fungibleTokenMapper": "str:TICKER-333333" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, @@ -397,7 +397,7 @@ "str:fungibleTokenMapper": "str:TICKER-333333", "str:rolesSet": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "+": "" } @@ -427,7 +427,7 @@ "str:fungibleTokenMapper": "str:TICKER-333333", "str:rolesSet": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, @@ -478,7 +478,7 @@ "str:fungibleTokenMapper": "str:TICKER-333333", "str:rolesSet": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "+": "" } @@ -538,7 +538,7 @@ "str:fungibleTokenMapper": "str:TICKER-333333", "str:rolesSet": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "+": "" } @@ -588,7 +588,7 @@ "str:fungibleTokenMapper": "str:TICKER-333333", "str:rolesSet": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "+": "" } @@ -766,7 +766,7 @@ "storage": { "str:fungibleTokenMapper": "" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, 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 new file mode 100644 index 0000000000..2a0ff501a8 --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address.scen.json @@ -0,0 +1,375 @@ +{ + "name": "storage mapper get at address", + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:caller": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features.mxsc.json" + }, + "sc:to-be-called": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features.mxsc.json" + }, + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scCall", + "id": "set contract address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "set_contract_address", + "arguments": [ + "sc:to-be-called" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "fill set mapper", + "tx": { + "from": "address:an_account", + "to": "sc:to-be-called", + "function": "fill_set_mapper", + "arguments": [ + "10" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "sc:caller": { + "nonce": "0", + "balance": "0", + "storage": { + "str:contract_address": "sc:to-be-called" + }, + "code": "mxsc:../output/basic-features.mxsc.json" + }, + "sc:to-be-called": { + "nonce": "0", + "balance": "0", + "storage": "*", + "code": "mxsc:../output/basic-features.mxsc.json" + }, + "address:an_account": { + "nonce": "*", + "balance": "*", + "storage": {}, + "code": "" + } + } + }, + { + "step": "scCall", + "id": "is empty at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "is_empty_at_address", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "contains at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "contains_at_address", + "arguments": [ + "5" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x01" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "len at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "len_at_address", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "10" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "next at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "next_at_address", + "arguments": [ + "5" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "6" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "previous at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "previous_at_address", + "arguments": [ + "5" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "4" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "front at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "front_at_address", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "1" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "back at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "back_at_address", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "10" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "fill map mapper", + "tx": { + "from": "address:an_account", + "to": "sc:to-be-called", + "function": "fill_map_mapper", + "arguments": [ + "5" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "keys at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "keys_at_address", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x0000271100002712000027130000271400002715" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "values at address", + "tx": { + "from": "address:an_account", + "to": "sc:caller", + "function": "values_at_address", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0x0000000100000002000000030000000400000005" + ], + "status": "", + "logs": "*", + "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": "*" + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address_extra_key.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address_extra_key.scen.json new file mode 100644 index 0000000000..d2802f41d2 --- /dev/null +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_get_at_address_extra_key.scen.json @@ -0,0 +1,90 @@ +{ + "name": "storage mapper get at address", + "gasSchedule": "v3", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:basic-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features.mxsc.json" + }, + "sc:with-storage": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features.mxsc.json" + }, + "address:an_account": { + "nonce": "0", + "balance": "0" + } + } + }, + { + "step": "scCall", + "id": "set single_value_with_keys", + "tx": { + "from": "address:an_account", + "to": "sc:with-storage", + "function": "set_single_value_mapper_with_key", + "arguments": [ + "5", + "str:to-read" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scQuery", + "id": "check single_value_with_keys", + "tx": { + "to": "sc:basic-features", + "function": "get_value_from_address_with_keys", + "arguments": [ + "sc:with-storage", + "5" + ] + }, + "expect": { + "out": [ + "str:to-read" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "sc:basic-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/basic-features.mxsc.json" + }, + "sc:with-storage": { + "nonce": "0", + "balance": "0", + "storage": { + "str:single_value_mapper_with_key|0x00000005": "str:to-read" + }, + "code": "mxsc:../output/basic-features.mxsc.json" + }, + "address:an_account": { + "nonce": "*", + "balance": "0" + } + } + } + ] +} diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_linked_list.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_linked_list.scen.json index 16ae4158e1..29aef32466 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_linked_list.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_linked_list.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -66,7 +66,7 @@ "str:list_mapper.node|u32:1": "u32:123|u32:1|u32:0|u32:0", "str:list_mapper.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -239,7 +239,7 @@ "str:list_mapper.node|u32:2": "u32:111|u32:2|u32:0|u32:1", "str:list_mapper.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -301,7 +301,7 @@ "str:list_mapper.node|u32:2": "u32:111|u32:2|u32:0|u32:0", "str:list_mapper.info": "u32:1|u32:2|u32:2|u32:2" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -339,7 +339,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -713,7 +713,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_map.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_map.scen.json index d2ec89206f..e3ba28d22b 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_map.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_map.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -72,7 +72,7 @@ "str:map_mapper.mapped|u32:123": "456", "str:map_mapper.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -209,7 +209,7 @@ "str:map_mapper.mapped|u32:111": "222", "str:map_mapper.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -296,7 +296,7 @@ "str:map_mapper.mapped|u32:111": "222", "str:map_mapper.info": "u32:1|u32:2|u32:2|u32:2" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -336,7 +336,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -376,7 +376,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -423,7 +423,7 @@ "str:map_mapper.value|u32:1": "123", "str:map_mapper.mapped|u32:123": "50" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -470,7 +470,7 @@ "str:map_mapper.value|u32:1": "123", "str:map_mapper.mapped|u32:123": "92" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -517,7 +517,7 @@ "str:map_mapper.value|u32:1": "123", "str:map_mapper.mapped|u32:123": "92" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -568,7 +568,7 @@ "str:map_mapper.value|u32:2": "142", "str:map_mapper.mapped|u32:142": "60" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -649,7 +649,7 @@ "str:map_mapper.value|u32:3": "167", "str:map_mapper.mapped|u32:167": "400" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -732,7 +732,7 @@ "str:map_mapper.value|u32:4": "78", "str:map_mapper.mapped|u32:78": "1078" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_map_storage.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_map_storage.scen.json index ac78a733a1..4d50190144 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_map_storage.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_map_storage.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -99,7 +99,7 @@ "str:map_storage_mapper.storage|u32:42|str:.mapped|u32:420": "421", "str:map_storage_mapper.storage|u32:42|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -231,7 +231,7 @@ "str:map_storage_mapper.storage|u32:43|str:.mapped|u32:430": "431", "str:map_storage_mapper.storage|u32:43|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -318,7 +318,7 @@ "str:map_storage_mapper.storage|u32:43|str:.mapped|u32:430": "431", "str:map_storage_mapper.storage|u32:43|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -368,7 +368,7 @@ "str:map_storage_mapper.storage|u32:43|str:.mapped|u32:430": "431", "str:map_storage_mapper.storage|u32:43|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -404,7 +404,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -443,7 +443,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -520,7 +520,7 @@ "str:map_storage_mapper.storage|u32:42|str:.node_id|u32:5": "1", "str:map_storage_mapper.storage|u32:42|str:.mapped|u32:5": "30" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -606,7 +606,7 @@ "str:map_storage_mapper.storage|u32:42|str:.node_id|u32:15": "2", "str:map_storage_mapper.storage|u32:42|str:.mapped|u32:15": "100" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -727,7 +727,7 @@ "str:map_storage_mapper.storage|u32:77|str:.node_id|u32:444": "2", "str:map_storage_mapper.storage|u32:77|str:.mapped|u32:444": "50" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_non_fungible_token.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_non_fungible_token.scen.json index 449115630a..e3a982447f 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_non_fungible_token.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_non_fungible_token.scen.json @@ -16,7 +16,7 @@ ] } }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -25,7 +25,7 @@ "0x000000000000000000010000000000000000000000000000000000000002ffff": { "nonce": "0", "balance": "0", - "code": "file:../../esdt-system-sc-mock/output/esdt-system-sc-mock.wasm" + "code": "mxsc:../../esdt-system-sc-mock/output/esdt-system-sc-mock.mxsc.json" } } }, @@ -70,7 +70,7 @@ "storage": { "str:nonFungibleTokenMapper": "" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, @@ -167,7 +167,7 @@ ] } }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -259,7 +259,7 @@ ] } }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -329,7 +329,7 @@ ] } }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_queue.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_queue.scen.json index d5a1718738..44224aecf8 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_queue.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_queue.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -67,7 +67,7 @@ "str:queue_mapper.value|u32:1": "123", "str:queue_mapper.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -154,7 +154,7 @@ "str:queue_mapper.value|u32:2": "111", "str:queue_mapper.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -217,7 +217,7 @@ "str:queue_mapper.value|u32:2": "111", "str:queue_mapper.info": "u32:1|u32:2|u32:2|u32:2" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -255,7 +255,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_set.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_set.scen.json index 210a1c67c3..3e5b59ed9d 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_set.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_set.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -70,7 +70,7 @@ "str:set_mapper.node_id|u32:123": "1", "str:set_mapper.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -161,7 +161,7 @@ "str:set_mapper.node_id|u32:111": "2", "str:set_mapper.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -229,7 +229,7 @@ "str:set_mapper.node_id|u32:111": "2", "str:set_mapper.info": "u32:1|u32:2|u32:2|u32:2" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -269,7 +269,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -298,6 +298,209 @@ "gas": "*", "refund": "*" } + }, + { + "step": "scCall", + "id": "first-insert", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "set_mapper_insert", + "arguments": [ + "111" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "true" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "second-insert", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "set_mapper_insert", + "arguments": [ + "222" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "true" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "third-insert", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "set_mapper_insert", + "arguments": [ + "333" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "true" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "check-front", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "set_mapper_front", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "111" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "check-back", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "set_mapper_back", + "arguments": [], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "333" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "check-next", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "set_mapper_next", + "arguments": [ + "222" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "333" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "check-next-out-of-bounds", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "set_mapper_next", + "arguments": [ + "333" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "0" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "check-previous", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "set_mapper_previous", + "arguments": [ + "222" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "111" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "check-iter-from", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "set_mapper_iter_from_and_count", + "arguments": [ + "222" + ], + "gasLimit": "50,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "2" + ], + "status": "", + "logs": "*", + "gas": "*", + "refund": "*" + } } ] } diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_single_value.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_single_value.scen.json index 88f2dc82ce..192e773371 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_single_value.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_single_value.scen.json @@ -8,12 +8,12 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -178,13 +178,13 @@ "storage": { "str:my_single_value_mapper": "+234" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -308,13 +308,13 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -355,13 +355,13 @@ "storage": { "str:my_single_value_mapper": "42" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -402,13 +402,13 @@ "storage": { "str:my_single_value_mapper": "42" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_token_attributes.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_token_attributes.scen.json index a3cdb3e025..9b2a586cf2 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_token_attributes.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_token_attributes.scen.json @@ -8,7 +8,7 @@ "sc:contract": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:owner": { "nonce": "0", @@ -125,7 +125,7 @@ "str:TokenAttributes.mapping|nested:str:BOB-abcdef": "2", "str:TokenAttributes.mapping|nested:str:ALICE-abcdef": "1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, @@ -508,7 +508,7 @@ "str:TokenAttributes.mapping|nested:str:BOB-abcdef": "2", "str:TokenAttributes.mapping|nested:str:ALICE-abcdef": "1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } }, @@ -615,7 +615,7 @@ "str:TokenAttributes.mapping|nested:str:BOB-abcdef": "2", "str:TokenAttributes.mapping|nested:str:ALICE-abcdef": "1" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" } } } diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_unique_id.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_unique_id.scen.json index 61016ccddc..37f01b7d31 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_unique_id.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_unique_id.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -51,7 +51,7 @@ "str:unique_id_mapper.item|u32:4": "", "str:unique_id_mapper.item|u32:5": "" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -145,7 +145,7 @@ "str:unique_id_mapper.item|u32:4": "", "str:unique_id_mapper.item|u32:5": "" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -261,7 +261,7 @@ "str:unique_id_mapper.item|u32:4": "", "str:unique_id_mapper.item|u32:5": "" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_vec.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_vec.scen.json index de100c5db8..5fef8a4c7e 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_vec.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_vec.scen.json @@ -8,12 +8,12 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -157,13 +157,13 @@ "str:vec_mapper.item|u32:1": "123", "str:vec_mapper.item|u32:2": "111" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_mapper_whitelist.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_mapper_whitelist.scen.json index aeb76c95ae..f1332e11b5 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_mapper_whitelist.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_mapper_whitelist.scen.json @@ -7,12 +7,12 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -73,13 +73,13 @@ "storage": { "str:whitelistMapper|nested:str:item": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -167,13 +167,13 @@ "str:whitelistMapper|nested:str:item": "true", "str:whitelistMapper|nested:str:item2": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -213,13 +213,13 @@ "storage": { "str:whitelistMapper|nested:str:item2": "true" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:extra-instance": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_opt_managed_addr.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_opt_managed_addr.scen.json index fea0793e6c..81f66436e9 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_opt_managed_addr.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_opt_managed_addr.scen.json @@ -14,7 +14,7 @@ "str:____________address_too_long____________" ] }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -36,7 +36,7 @@ "expect": { "out": [], "status": "4", - "message": "str:storage decode error: input too long", + "message": "str:storage decode error (key: opt_addr): input too long", "logs": "*", "gas": "*", "refund": "*" @@ -72,7 +72,7 @@ "storage": { "str:opt_addr": "1|str:____________address_____________" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "+": "" } @@ -168,7 +168,7 @@ "storage": { "str:opt_addr": "" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "+": "" } diff --git a/contracts/feature-tests/basic-features/scenarios/storage_raw_api_features.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_raw_api_features.scen.json index 920a49bfe3..a5817ab5d0 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_raw_api_features.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_raw_api_features.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "sc:other": { "nonce": "0", @@ -16,7 +16,7 @@ "storage": { "str:otherStorage": "str:myValue" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -55,7 +55,7 @@ "storage": { "str:coolKey": "str:12345" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "+": "" } diff --git a/contracts/feature-tests/basic-features/scenarios/storage_reserved.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_reserved.scen.json index d465ad7015..99f42f58a2 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_reserved.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_reserved.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_u64.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_u64.scen.json index cd115057eb..d2cd5cc029 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_u64.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_u64.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "storage": { "str:u64": "123" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -107,7 +107,7 @@ "storage": { "str:u64": "0" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_u64_bad.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_u64_bad.scen.json index c4d8fc1179..c7597fd010 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_u64_bad.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_u64_bad.scen.json @@ -11,7 +11,7 @@ "storage": { "str:u64": "0x010000000000000000" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -33,7 +33,7 @@ "expect": { "out": [], "status": "4", - "message": "str:storage decode error: input too long", + "message": "str:storage decode error (key: u64): input too long", "logs": "*", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/basic-features/scenarios/storage_usize.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_usize.scen.json index 9104c4953a..e828b13e4a 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_usize.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_usize.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -46,7 +46,7 @@ "storage": { "str:usize": "123" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", @@ -107,7 +107,7 @@ "storage": { "str:usize": "0" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/basic-features/scenarios/storage_usize_bad.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_usize_bad.scen.json index 710e519692..e74cc2ca90 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_usize_bad.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_usize_bad.scen.json @@ -11,7 +11,7 @@ "storage": { "str:usize": "0x0100000000" }, - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -33,7 +33,7 @@ "expect": { "out": [], "status": "4", - "message": "str:storage decode error: input too long", + "message": "str:storage decode error (key: usize): input too long", "logs": "*", "gas": "*", "refund": "*" diff --git a/contracts/feature-tests/basic-features/scenarios/struct_eq.scen.json b/contracts/feature-tests/basic-features/scenarios/struct_eq.scen.json index 3bb871f700..b7f50c4e78 100644 --- a/contracts/feature-tests/basic-features/scenarios/struct_eq.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/struct_eq.scen.json @@ -6,7 +6,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/basic-features.wasm" + "code": "mxsc:../output/basic-features.mxsc.json" }, "address:an_account": { "nonce": "0", 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 da587b2317..1ee7519f10 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; @@ -11,17 +11,21 @@ pub mod codec_err_test; pub mod crypto_features; pub mod echo; pub mod echo_managed; +pub mod egld_decimal; pub mod elliptic_curve_features; pub mod event_features; pub mod macro_features; pub mod managed_address_features; pub mod managed_buffer_features; +pub mod managed_decimal_features; pub mod managed_vec_features; pub mod non_zero_features; +pub mod small_num_overflow_test_ops; pub mod storage_direct_load; pub mod storage_direct_store; pub mod storage_mapper_address_to_id; pub mod storage_mapper_fungible_token; +pub mod storage_mapper_get_at_address; pub mod storage_mapper_linked_list; pub mod storage_mapper_map; pub mod storage_mapper_map_storage; @@ -31,6 +35,7 @@ pub mod storage_mapper_set; pub mod storage_mapper_single; pub mod storage_mapper_token_attributes; pub mod storage_mapper_unique_id_mapper; +pub mod storage_mapper_unordered_set; pub mod storage_mapper_vec; pub mod storage_mapper_whitelist; pub mod storage_raw_api_features; @@ -70,10 +75,15 @@ pub trait BasicFeatures: + storage_mapper_fungible_token::FungibleTokenMapperFeatures + storage_mapper_non_fungible_token::NonFungibleTokenMapperFeatures + storage_mapper_unique_id_mapper::UniqueIdMapperFeatures + + storage_mapper_unordered_set::UnorderedSetMapperFeatures + struct_eq::StructEquals + + small_num_overflow_test_ops::SmallIntOverflow + token_identifier_features::TokenIdentifierFeatures + non_zero_features::TypeFeatures + + egld_decimal::EgldDecimal + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + + storage_mapper_get_at_address::StorageMapperGetAtAddress + + managed_decimal_features::ManagedDecimalFeatures { #[init] fn init(&self) {} @@ -96,4 +106,7 @@ pub trait BasicFeatures: arg1 } + + #[storage_mapper("coolTree")] + fn cool_tree(&self) -> OrderedBinaryTreeMapper; } 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..78e267f6bc --- /dev/null +++ b/contracts/feature-tests/basic-features/src/basic_features_proxy.rs @@ -0,0 +1,162 @@ +// 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 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, +{ + /// This tests how is generated type name in proxy + pub fn echo_managed_option< + Arg0: ProxyArg>>, + >( + self, + mo: Arg0, + ) -> TxTypedCall>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("echo_managed_option") + .argument(&mo) + .original_result() + } + + 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/big_num_methods.rs b/contracts/feature-tests/basic-features/src/big_num_methods.rs index 086f89761b..25d83b21fb 100644 --- a/contracts/feature-tests/basic-features/src/big_num_methods.rs +++ b/contracts/feature-tests/basic-features/src/big_num_methods.rs @@ -14,12 +14,12 @@ pub trait BigIntMethods { #[endpoint] fn log2_big_uint(&self, a: BigUint) -> u32 { - a.log2() + a.log2_floor().unwrap_or_default() } #[endpoint] fn log2_big_uint_ref(&self, a: &BigUint) -> u32 { - a.log2() + a.log2_floor().unwrap_or_default() } #[endpoint] @@ -48,7 +48,7 @@ pub trait BigIntMethods { } #[endpoint] - fn biguint_overwrite_u64(&self, bu: BigUint, small: u64) -> BigUint { + fn biguint_overwrite_u64(&self, mut bu: BigUint, small: u64) -> BigUint { bu.overwrite_u64(small); bu } diff --git a/contracts/feature-tests/basic-features/src/blockchain_api_features.rs b/contracts/feature-tests/basic-features/src/blockchain_api_features.rs index 73538d8aca..9f0545811f 100644 --- a/contracts/feature-tests/basic-features/src/blockchain_api_features.rs +++ b/contracts/feature-tests/basic-features/src/blockchain_api_features.rs @@ -42,4 +42,14 @@ pub trait BlockchainApiFeatures { fn get_cumulated_validator_rewards(&self) -> BigUint { self.blockchain().get_cumulated_validator_rewards() } + + #[endpoint] + fn get_code_metadata(&self, address: ManagedAddress) -> CodeMetadata { + self.blockchain().get_code_metadata(&address) + } + + #[endpoint] + fn is_builtin_function(&self, function_name: ManagedBuffer) -> bool { + self.blockchain().is_builtin_function(&function_name) + } } 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/crypto_features.rs b/contracts/feature-tests/basic-features/src/crypto_features.rs index 56c543163c..0588146780 100644 --- a/contracts/feature-tests/basic-features/src/crypto_features.rs +++ b/contracts/feature-tests/basic-features/src/crypto_features.rs @@ -24,7 +24,7 @@ pub trait CryptoFeatures { key: ManagedBuffer, message: ManagedBuffer, signature: ManagedBuffer, - ) -> bool { + ) { self.crypto().verify_bls(&key, &message, &signature) } @@ -64,4 +64,39 @@ pub trait CryptoFeatures { fn compute_secp256k1_der_signature(&self, r: ManagedBuffer, s: ManagedBuffer) -> ManagedBuffer { self.crypto().encode_secp256k1_der_signature(&r, &s) } + + #[endpoint] + #[label("crypto-ei-1.4")] + fn verify_secp256r1_signature( + &self, + key: ManagedBuffer, + message: ManagedBuffer, + signature: ManagedBuffer, + ) { + self.crypto().verify_secp256r1(&key, &message, &signature) + } + + #[endpoint] + #[label("crypto-ei-1.4")] + fn verify_bls_signature_share( + &self, + key: ManagedBuffer, + message: ManagedBuffer, + signature: ManagedBuffer, + ) { + self.crypto() + .verify_bls_signature_share(&key, &message, &signature) + } + + #[endpoint] + #[label("crypto-ei-1.4")] + fn verify_bls_aggregated_signature( + &self, + key: ManagedVec, + message: ManagedBuffer, + signature: ManagedBuffer, + ) { + self.crypto() + .verify_bls_aggregated_signature(&key, &message, &signature) + } } diff --git a/contracts/feature-tests/basic-features/src/echo_managed.rs b/contracts/feature-tests/basic-features/src/echo_managed.rs index 62ee33a7a7..17084a26c8 100644 --- a/contracts/feature-tests/basic-features/src/echo_managed.rs +++ b/contracts/feature-tests/basic-features/src/echo_managed.rs @@ -1,4 +1,4 @@ -multiversx_sc::imports!(); +use multiversx_sc::imports::*; /// Test endpoint argument and result serialization. #[multiversx_sc::module] @@ -23,6 +23,12 @@ pub trait EchoManagedTypes { ma } + /// This tests how is generated type name in proxy + #[endpoint] + fn echo_managed_option(&self, mo: ManagedOption) -> ManagedOption { + mo + } + /// This tests that nested serialization of big ints within unmanaged types works. #[endpoint] fn echo_big_int_managed_vec(&self, x: ManagedVec) -> ManagedVec { diff --git a/contracts/feature-tests/basic-features/src/egld_decimal.rs b/contracts/feature-tests/basic-features/src/egld_decimal.rs new file mode 100644 index 0000000000..0b27ed84c6 --- /dev/null +++ b/contracts/feature-tests/basic-features/src/egld_decimal.rs @@ -0,0 +1,11 @@ +multiversx_sc::imports!(); + +/// Used for testing the egld_decimal function return type +#[multiversx_sc::module] +pub trait EgldDecimal { + #[payable("EGLD")] + #[endpoint] + fn returns_egld_decimal(&self) -> ManagedDecimal> { + self.call_value().egld_decimal() + } +} diff --git a/contracts/feature-tests/basic-features/src/managed_decimal_features.rs b/contracts/feature-tests/basic-features/src/managed_decimal_features.rs new file mode 100644 index 0000000000..4bb3233c70 --- /dev/null +++ b/contracts/feature-tests/basic-features/src/managed_decimal_features.rs @@ -0,0 +1,102 @@ +use multiversx_sc::imports::*; + +#[multiversx_sc::module] +pub trait ManagedDecimalFeatures { + #[endpoint] + fn managed_decimal_addition( + &self, + first: ManagedDecimal>, + second: ManagedDecimal>, + ) -> ManagedDecimal> { + first + second + } + + #[endpoint] + fn managed_decimal_subtraction( + &self, + first: ManagedDecimal>, + second: ManagedDecimal>, + ) -> ManagedDecimal> { + first - second + } + + #[endpoint] + fn managed_decimal_eq( + &self, + first: ManagedDecimal>, + second: ManagedDecimal>, + ) -> bool { + first.eq(&second) + } + + #[endpoint] + fn managed_decimal_trunc(&self) -> BigUint { + let dec = ManagedDecimal::from_raw_units(BigUint::from(31332u64), 2usize); + dec.trunc() + } + + #[endpoint] + fn managed_decimal_into_raw_units(&self) -> BigUint { + let dec = ManagedDecimal::from_raw_units(BigUint::from(12345u64), 2usize); + dec.into_raw_units().clone() + } + + #[endpoint] + fn managed_decimal_ln( + &self, + x: ManagedDecimal>, + ) -> ManagedDecimalSigned> { + x.ln().unwrap_or_else(|| sc_panic!("cannot be zero")) + } + + #[endpoint] + fn managed_decimal_log2( + &self, + x: ManagedDecimal>, + ) -> ManagedDecimalSigned> { + x.log2().unwrap_or_else(|| sc_panic!("cannot be zero")) + } + + #[endpoint] + fn managed_decimal_addition_var( + &self, + first: ManagedDecimal, + second: ManagedDecimal, + ) -> ManagedDecimal { + first + second + } + + #[endpoint] + fn managed_decimal_subtraction_var( + &self, + first: ManagedDecimal, + second: ManagedDecimal, + ) -> ManagedDecimal { + first - second + } + + #[endpoint] + fn managed_decimal_eq_var( + &self, + first: ManagedDecimal, + second: ManagedDecimal, + ) -> bool { + first.eq(&second) + } + + #[endpoint] + fn managed_decimal_ln_var( + &self, + x: ManagedDecimal, + ) -> ManagedDecimalSigned> { + x.ln().unwrap_or_else(|| sc_panic!("cannot be zero")) + } + + #[endpoint] + fn managed_decimal_log2_var( + &self, + x: ManagedDecimal, + ) -> ManagedDecimalSigned> { + x.log2().unwrap_or_else(|| sc_panic!("cannot be zero")) + } +} 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/small_num_overflow_test_ops.rs b/contracts/feature-tests/basic-features/src/small_num_overflow_test_ops.rs new file mode 100644 index 0000000000..6104f00dbe --- /dev/null +++ b/contracts/feature-tests/basic-features/src/small_num_overflow_test_ops.rs @@ -0,0 +1,115 @@ +multiversx_sc::imports!(); + +/// Used for testing overflow on small int types +#[multiversx_sc::module] +#[allow(clippy::redundant_clone)] +pub trait SmallIntOverflow { + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_usize(&self) -> usize { + usize::MAX + 1 + } + + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_u8(&self) -> u8 { + u8::MAX + 1 + } + + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_u16(&self) -> u16 { + u16::MAX + 1 + } + + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_u32(&self) -> u32 { + u32::MAX + 1 + } + + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_u64(&self) -> u64 { + u64::MAX + 1 + } + #[endpoint] + fn overflow_usize(&self) -> usize { + usize::MAX.wrapping_add(1) + } + + #[endpoint] + fn overflow_u8(&self) -> u8 { + u8::MAX.wrapping_add(1) + } + + #[endpoint] + fn overflow_u16(&self) -> u16 { + u16::MAX.wrapping_add(1) + } + + #[endpoint] + fn overflow_u32(&self) -> u32 { + u32::MAX.wrapping_add(1) + } + + #[endpoint] + fn overflow_u64(&self) -> u64 { + u64::MAX.wrapping_add(1) + } + + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_isize(&self) -> isize { + isize::MAX + isize::MAX + } + + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_i8(&self) -> i8 { + i8::MAX + i8::MAX + } + + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_i16(&self) -> i16 { + i16::MAX + i16::MAX + } + + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_i32(&self) -> i32 { + i32::MAX + i32::MAX + } + + #[endpoint] + #[allow(arithmetic_overflow)] + fn no_overflow_i64(&self) -> i64 { + i64::MAX + i64::MAX + } + + #[endpoint] + fn overflow_isize(&self) -> isize { + isize::MAX.wrapping_add(isize::MAX) + } + + #[endpoint] + fn overflow_i8(&self) -> i8 { + i8::MAX.wrapping_add(i8::MAX) + } + + #[endpoint] + fn overflow_i16(&self) -> i16 { + i16::MAX.wrapping_add(i16::MAX) + } + + #[endpoint] + fn overflow_i32(&self) -> i32 { + i32::MAX.wrapping_add(i32::MAX) + } + + #[endpoint] + fn overflow_i64(&self) -> i64 { + i64::MAX.wrapping_add(i64::MAX) + } +} diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_address_to_id.rs b/contracts/feature-tests/basic-features/src/storage_mapper_address_to_id.rs index ff50875276..9bc0803fd3 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_address_to_id.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_address_to_id.rs @@ -43,5 +43,5 @@ pub trait AddressToIdMapperFeatures { } #[storage_mapper("address_ids")] - fn address_ids(&self) -> AddressToIdMapper; + fn address_ids(&self) -> AddressToIdMapper; } 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 new file mode 100644 index 0000000000..324df37021 --- /dev/null +++ b/contracts/feature-tests/basic-features/src/storage_mapper_get_at_address.rs @@ -0,0 +1,149 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +/// Module that calls another contract to read the content of a SetMapper remotely +#[multiversx_sc::module] +pub trait StorageMapperGetAtAddress { + #[storage_mapper("contract_address")] + fn contract_address(&self) -> SingleValueMapper; + + #[endpoint] + fn set_contract_address(&self, address: ManagedAddress) { + self.contract_address().set(address) + } + + #[endpoint] + fn is_empty_at_address(&self) -> bool { + let address = self.contract_address().get(); + self.set_mapper_from_address(address).is_empty() + } + + #[endpoint] + fn contains_at_address(&self, item: u32) -> bool { + let address = self.contract_address().get(); + self.set_mapper_from_address(address).contains(&item) + } + + #[endpoint] + fn len_at_address(&self) -> usize { + let address = self.contract_address().get(); + self.set_mapper_from_address(address).len() + } + + #[endpoint] + fn next_at_address(&self, item: u32) -> u32 { + let address = self.contract_address().get(); + self.set_mapper_from_address(address).next(&item).unwrap() + } + + #[endpoint] + fn previous_at_address(&self, item: u32) -> u32 { + let address = self.contract_address().get(); + self.set_mapper_from_address(address) + .previous(&item) + .unwrap() + } + + #[endpoint] + fn front_at_address(&self) -> u32 { + let address = self.contract_address().get(); + self.set_mapper_from_address(address).front().unwrap() + } + + #[endpoint] + fn back_at_address(&self) -> u32 { + let address = self.contract_address().get(); + self.set_mapper_from_address(address).back().unwrap() + } + + #[endpoint] + fn keys_at_address(&self) -> ManagedVec { + let address = self.contract_address().get(); + self.map_mapper_from_address(address).keys().collect() + } + + #[endpoint] + fn values_at_address(&self) -> ManagedVec { + let address = self.contract_address().get(); + self.map_mapper_from_address(address).values().collect() + } + + #[endpoint] + fn contains_unordered_at_address(&self, item: u32) -> bool { + let address = self.contract_address().get(); + self.unordered_set_mapper_from_address(address) + .contains(&item) + } + + #[endpoint] + fn get_by_index(&self, index: usize) -> u32 { + let address = self.contract_address().get(); + self.unordered_set_mapper_from_address(address) + .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")] + fn set_mapper(&self) -> SetMapper; + + #[storage_mapper_from_address("set_mapper")] + fn set_mapper_from_address(&self, address: ManagedAddress) -> SetMapper; + + #[storage_mapper("map_mapper")] + fn map_mapper(&self) -> MapMapper; + + #[storage_mapper_from_address("map_mapper")] + fn map_mapper_from_address( + &self, + address: ManagedAddress, + ) -> MapMapper; + + #[storage_mapper("unordered_set_mapper")] + fn unordered_set_mapper(&self) -> UnorderedSetMapper; + + #[storage_mapper_from_address("unordered_set_mapper")] + fn unordered_set_mapper_from_address( + &self, + address: ManagedAddress, + ) -> UnorderedSetMapper; + + #[endpoint] + fn fill_set_mapper(&self, value: u32) { + for item in 1u32..=value { + self.set_mapper().insert(item); + } + } + + #[endpoint] + fn fill_map_mapper(&self, value: u32) { + for item in 1u32..=value { + let key = 10_000u32 + item; + 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); + } + } + + #[storage_mapper_from_address("single_value_mapper_with_key")] + fn single_value_from_address_with_keys( + &self, + address: ManagedAddress, + extra_key: usize, + ) -> SingleValueMapper; + + #[view] + fn get_value_from_address_with_keys( + &self, + address: ManagedAddress, + extra_key: usize, + ) -> ManagedBuffer { + self.single_value_from_address_with_keys(address, extra_key) + .get() + } +} diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_map_storage.rs b/contracts/feature-tests/basic-features/src/storage_mapper_map_storage.rs index 4e334d9846..0179d9bab9 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_map_storage.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_map_storage.rs @@ -46,24 +46,19 @@ pub trait MapStorageMapperFeatures { } #[endpoint] - fn map_storage_mapper_insert_value( - &self, - item: u32, - key: u32, - value: u32, - ) -> SCResult> { + fn map_storage_mapper_insert_value(&self, item: u32, key: u32, value: u32) -> Option { let map_storage_mapper = self.map_storage_mapper(); if let Some(mut map) = map_storage_mapper.get(&item) { - return Ok(map.insert(key, value)); + return map.insert(key, value); } sc_panic!("No storage!") } #[endpoint] - fn map_storage_mapper_get_value(&self, item: u32, key: u32) -> SCResult> { + fn map_storage_mapper_get_value(&self, item: u32, key: u32) -> Option { let map_storage_mapper = self.map_storage_mapper(); if let Some(map) = map_storage_mapper.get(&item) { - return Ok(map.get(&key)); + return map.get(&key); } sc_panic!("No storage!") } 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_queue.rs b/contracts/feature-tests/basic-features/src/storage_mapper_queue.rs index 262de7513b..ba228ff2b5 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_queue.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_queue.rs @@ -20,9 +20,9 @@ pub trait QueueMapperFeatures { } #[endpoint] - fn queue_mapper_front(&self) -> SCResult { + fn queue_mapper_front(&self) -> u32 { if let Some(front) = self.queue_mapper().front() { - return Ok(front); + return front; } sc_panic!("Queue empty!") } diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_set.rs b/contracts/feature-tests/basic-features/src/storage_mapper_set.rs index b77004f3ab..8a7771f90a 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_set.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_set.rs @@ -24,4 +24,39 @@ pub trait SetMapperFeatures { let mut set_mapper = self.set_mapper(); set_mapper.remove(&item) } + + #[endpoint] + fn set_mapper_front(&self) -> u32 { + let set_mapper = self.set_mapper(); + set_mapper.front().unwrap_or_default() + } + + #[endpoint] + fn set_mapper_back(&self) -> u32 { + let set_mapper = self.set_mapper(); + set_mapper.back().unwrap_or_default() + } + + #[endpoint] + fn set_mapper_next(&self, item: u32) -> u32 { + let set_mapper = self.set_mapper(); + set_mapper.next(&item).unwrap_or_default() + } + + #[endpoint] + fn set_mapper_previous(&self, item: u32) -> u32 { + let set_mapper = self.set_mapper(); + set_mapper.previous(&item).unwrap_or_default() + } + + #[endpoint] + fn set_mapper_iter_from_and_count(&self, item: u32) -> u32 { + let set_mapper = self.set_mapper(); + let mut count = 0; + for _element in set_mapper.iter_from(&item) { + count += 1; + } + + count + } } diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_single.rs b/contracts/feature-tests/basic-features/src/storage_mapper_single.rs index 64972340d5..f8e8228038 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_single.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_single.rs @@ -7,6 +7,15 @@ pub trait SingleValueMapperFeatures { #[storage_mapper("my_single_value_mapper")] fn map_my_single_value_mapper(&self) -> SingleValueMapper; + #[storage_mapper_from_address("my_single_value_mapper")] + fn map_my_single_value_mapper_from_address( + &self, + address: ManagedAddress, + ) -> SingleValueMapper; + + #[storage_mapper("single_value_mapper_with_key")] + fn single_value_mapper_with_key(&self, extra_key: usize) -> SingleValueMapper; + #[endpoint] fn my_single_value_mapper_increment_1(&self, amount: BigInt) { let my_single_value_mapper = self.map_my_single_value_mapper(); @@ -53,12 +62,17 @@ pub trait SingleValueMapperFeatures { #[endpoint] fn is_empty_at_address_single_value_mapper(&self, address: ManagedAddress) -> bool { - self.map_my_single_value_mapper() - .is_empty_at_address(&address) + self.map_my_single_value_mapper_from_address(address) + .is_empty() } #[endpoint] fn raw_byte_length_single_value_mapper(&self) -> usize { self.map_my_single_value_mapper().raw_byte_length() } + + #[endpoint] + fn set_single_value_mapper_with_key(&self, key: usize, value: ManagedBuffer) { + self.single_value_mapper_with_key(key).set(value); + } } 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/storage_mapper_unordered_set.rs b/contracts/feature-tests/basic-features/src/storage_mapper_unordered_set.rs index de4e189a9b..9bca7f9378 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_unordered_set.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_unordered_set.rs @@ -4,24 +4,24 @@ multiversx_sc::imports!(); #[multiversx_sc::module] pub trait UnorderedSetMapperFeatures { #[view] - #[storage_mapper("set_mapper")] - fn set_mapper(&self) -> UnorderedSetMapper; + #[storage_mapper("unordered_set_mapper")] + fn unordered_set_mapper(&self) -> UnorderedSetMapper; #[endpoint] - fn set_mapper_insert(&self, item: u32) -> bool { - let mut set_mapper = self.set_mapper(); + fn unordered_set_mapper_insert(&self, item: u32) -> bool { + let mut set_mapper = self.unordered_set_mapper(); set_mapper.insert(item) } #[endpoint] - fn set_mapper_contains(&self, item: u32) -> bool { - let set_mapper = self.set_mapper(); + fn unordered_set_mapper_contains(&self, item: u32) -> bool { + let set_mapper = self.unordered_set_mapper(); set_mapper.contains(&item) } #[endpoint] - fn set_mapper_remove(&self, item: u32) -> bool { - let mut set_mapper = self.set_mapper(); - set_mapper.remove(&item) + fn unordered_set_mapper_remove(&self, item: u32) -> bool { + let mut set_mapper = self.unordered_set_mapper(); + set_mapper.swap_remove(&item) } } diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_vec.rs b/contracts/feature-tests/basic-features/src/storage_mapper_vec.rs index 6f05c290b4..b6205789f8 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_vec.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_vec.rs @@ -7,6 +7,9 @@ pub trait VecMapperFeatures { #[storage_mapper("vec_mapper")] fn vec_mapper(&self) -> VecMapper; + #[storage_mapper_from_address("vec_mapper")] + fn vec_mapper_from_address(&self, address: ManagedAddress) -> VecMapper; + #[endpoint] fn vec_mapper_push(&self, item: u32) { let mut vec_mapper = self.vec_mapper(); @@ -20,7 +23,7 @@ pub trait VecMapperFeatures { #[view] fn vec_mapper_get_at_address(&self, address: ManagedAddress, index: usize) -> u32 { - self.vec_mapper().get_at_address(&address, index) + self.vec_mapper_from_address(address).get(index) } #[view] @@ -30,6 +33,6 @@ pub trait VecMapperFeatures { #[view] fn vec_mapper_len_at_address(&self, address: ManagedAddress) -> usize { - self.vec_mapper().len_at_address(&address) + self.vec_mapper_from_address(address).len() } } diff --git a/contracts/feature-tests/basic-features/src/storage_mapper_whitelist.rs b/contracts/feature-tests/basic-features/src/storage_mapper_whitelist.rs index 7a0974f370..ee9f255081 100644 --- a/contracts/feature-tests/basic-features/src/storage_mapper_whitelist.rs +++ b/contracts/feature-tests/basic-features/src/storage_mapper_whitelist.rs @@ -19,7 +19,7 @@ pub trait StorageMapperWhitelistFeatures { #[endpoint] fn check_contains_at_address(&self, address: ManagedAddress, item: ManagedBuffer) -> bool { - self.whitelist_mapper().contains_at_address(&address, &item) + self.whitelist_mapper_from_address(address).contains(&item) } #[endpoint] @@ -29,10 +29,16 @@ pub trait StorageMapperWhitelistFeatures { #[endpoint] fn require_contains_at_address(&self, address: ManagedAddress, item: ManagedBuffer) { - self.whitelist_mapper() - .require_whitelisted_at_address(&address, &item); + self.whitelist_mapper_from_address(address) + .require_whitelisted(&item) } #[storage_mapper("whitelistMapper")] fn whitelist_mapper(&self) -> WhitelistMapper; + + #[storage_mapper_from_address("whitelistMapper")] + fn whitelist_mapper_from_address( + &self, + address: ManagedAddress, + ) -> WhitelistMapper; } 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 new file mode 100644 index 0000000000..3f9589e01f --- /dev/null +++ b/contracts/feature-tests/basic-features/tests/basic_features_egld_decimal_test.rs @@ -0,0 +1,56 @@ +use imports::{MxscPath, ReturnsResult, TestAddress, TestSCAddress}; +use multiversx_sc::types::{BigUint, ConstDecimals, ManagedDecimal}; +use multiversx_sc_scenario::{api::StaticApi, imports, ScenarioTxRun, ScenarioWorld}; + +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, +} + +impl BasicFeaturesState { + fn new() -> Self { + let mut world = world(); + let basic_features_code = + world.code_expression(BASIC_FEATURES_PATH.eval_to_expr().as_str()); + + world.account(OWNER_ADDRESS).nonce(1).balance(100); + world + .account(BASIC_FEATURES_ADDRESS) + .nonce(1) + .code(basic_features_code); + + Self { world } + } +} +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(BASIC_FEATURES_PATH, basic_features::ContractBuilder); + blockchain +} + +#[test] +fn egld_decimal_blackbox_test() { + let mut state = BasicFeaturesState::new(); + + let egld_decimal_result = state + .world + .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_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 new file mode 100644 index 0000000000..d2cc2d269b --- /dev/null +++ b/contracts/feature-tests/basic-features/tests/basic_features_is_builtin_function_rs_test.rs @@ -0,0 +1,17 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + "mxsc:output/basic-features.mxsc.json", + basic_features::ContractBuilder, + ); + + blockchain +} + +#[test] +fn is_builtin_function_test() { + world().run("scenarios/is_builtin_function.scen.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 new file mode 100644 index 0000000000..238e4f0f4e --- /dev/null +++ b/contracts/feature-tests/basic-features/tests/basic_features_managed_decimal_test.rs @@ -0,0 +1,20 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + blockchain.register_contract( + "mxsc:output/basic-features.mxsc.json", + basic_features::ContractBuilder, + ); + blockchain +} + +#[test] +fn managed_decimal_test() { + world().run("scenarios/managed_decimal.scen.json"); +} + +#[test] +fn managed_decimal_logarithm_test() { + world().run("scenarios/managed_decimal_logarithm.scen.json"); +} diff --git a/contracts/feature-tests/basic-features/tests/basic_features_managed_option_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_managed_option_test.rs new file mode 100644 index 0000000000..38d5730c03 --- /dev/null +++ b/contracts/feature-tests/basic-features/tests/basic_features_managed_option_test.rs @@ -0,0 +1,41 @@ +use imports::{MxscPath, ReturnsResult, TestAddress, TestSCAddress}; +use multiversx_sc::types::{BigUint, ManagedOption}; +use multiversx_sc_scenario::{api::StaticApi, imports, ScenarioTxRun, ScenarioWorld}; + +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"); + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(BASIC_FEATURES_PATH, basic_features::ContractBuilder); + + blockchain.account(OWNER_ADDRESS).nonce(1); + blockchain + .account(BASIC_FEATURES_ADDRESS) + .nonce(1) + .code(BASIC_FEATURES_PATH); + + blockchain +} + +#[test] +fn managed_option_test() { + let mut world = world(); + + let type_number: BigUint = BigUint::zero(); + let expected_type_managed_option: ManagedOption> = + ManagedOption::some(type_number); + + let output = world + .tx() + .from(OWNER_ADDRESS) + .to(BASIC_FEATURES_ADDRESS) + .typed(basic_features::basic_features_proxy::BasicFeaturesProxy) + .echo_managed_option(expected_type_managed_option.clone()) + .returns(ReturnsResult) + .run(); + + assert_eq!(output, expected_type_managed_option); +} 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 new file mode 100644 index 0000000000..fe48caecba --- /dev/null +++ b/contracts/feature-tests/basic-features/tests/basic_features_ordered_binary_tree_test.rs @@ -0,0 +1,113 @@ +#![allow(deprecated)] + +use basic_features::BasicFeatures; + +use multiversx_sc_scenario::imports::*; + +#[test] +fn ordered_binary_tree_test() { + let mut b_mock = BlockchainStateWrapper::new(); + let user = b_mock.create_user_account(&rust_biguint!(0)); + let sc_wrapper = b_mock.create_sc_account( + &rust_biguint!(0), + Some(&user), + basic_features::contract_obj, + "rand wasm path", + ); + + b_mock + .execute_tx(&user, &sc_wrapper, &rust_biguint!(0), |sc| { + let mut my_tree_mapper = sc.cool_tree(); + let opt_root = my_tree_mapper.get_root(); + assert_eq!(opt_root, None); + + my_tree_mapper.insert_element(5u32.into()); + //////////////////// 5 ///////////////////////////// + + let opt_root = my_tree_mapper.get_root(); + assert_eq!( + opt_root, + Some(OrderedBinaryTreeNode { + current_node_id: 1, + left_id: NULL_NODE_ID, + right_id: NULL_NODE_ID, + parent_id: NULL_NODE_ID, + data: managed_biguint!(5) + }) + ); + + let depth = my_tree_mapper.get_depth(&opt_root.unwrap()); + assert_eq!(depth, 1); + + my_tree_mapper.insert_element(3u32.into()); + my_tree_mapper.insert_element(4u32.into()); + my_tree_mapper.insert_element(8u32.into()); + //////////////////// 5 ///////////////////////////// + //////////// 3 ///////////// 8 ////////////////////// + /////////////// 4 ///////////////////////////////////// + + let opt_root = my_tree_mapper.get_root(); + assert_eq!( + opt_root, + Some(OrderedBinaryTreeNode { + current_node_id: 1, + left_id: 2, + right_id: 4, + parent_id: NULL_NODE_ID, + data: managed_biguint!(5) + }) + ); + + let opt_found_item = my_tree_mapper.iterative_search(opt_root.clone(), &4u32.into()); + assert_eq!( + opt_found_item, + Some(OrderedBinaryTreeNode { + current_node_id: 3, + left_id: NULL_NODE_ID, + right_id: NULL_NODE_ID, + parent_id: 2, + data: 4u32.into() + }) + ); + + let opt_found_item = my_tree_mapper.recursive_search(opt_root.clone(), &4u32.into()); + assert_eq!( + opt_found_item, + Some(OrderedBinaryTreeNode { + current_node_id: 3, + left_id: NULL_NODE_ID, + right_id: NULL_NODE_ID, + parent_id: 2, + data: 4u32.into() + }) + ); + + let opt_found_item = my_tree_mapper.recursive_search(opt_root.clone(), &50u32.into()); + assert_eq!(opt_found_item, None); + + let depth = my_tree_mapper.get_depth(&opt_root.unwrap()); + assert_eq!(depth, 3); + + my_tree_mapper.delete_node(4u32.into()); + + let opt_root = my_tree_mapper.get_root(); + let depth = my_tree_mapper.get_depth(&opt_root.unwrap()); + assert_eq!(depth, 2); + + my_tree_mapper.insert_element(4u32.into()); + my_tree_mapper.delete_node(5u32.into()); + + let opt_root = my_tree_mapper.get_root(); + assert_eq!( + opt_root, + Some(OrderedBinaryTreeNode { + current_node_id: 4, + left_id: 2, + right_id: NULL_NODE_ID, + parent_id: NULL_NODE_ID, + data: 8u32.into() + }) + ); + }) + .assert_ok(); +} 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 25d234ec9b..58bee7c1da 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 @@ -29,6 +29,11 @@ fn big_uint_from_u_64_go() { world().run("scenarios/big_uint_from_u64.scen.json"); } +#[test] +fn big_uint_pow_go() { + world().run("scenarios/big_uint_pow.scen.json"); +} + #[test] fn big_uint_sqrt_go() { world().run("scenarios/big_uint_sqrt.scen.json"); @@ -79,6 +84,18 @@ fn crypto_verify_bls_go() { world().run("scenarios/crypto_verify_bls.scen.json"); } +#[test] +#[ignore = "requires EI 1.4 in mx-scenario-go"] +fn crypto_verify_bls_share_go() { + world().run("scenarios/crypto_verify_bls_share.scen.json"); +} + +#[test] +#[ignore = "requires EI 1.4 in mx-scenario-go"] +fn crypto_verify_bls_aggregated_go() { + world().run("scenarios/crypto_verify_bls_aggregated_signature.scen.json"); +} + #[test] fn crypto_verify_ed_25519_go() { world().run("scenarios/crypto_verify_ed25519.scen.json"); @@ -89,6 +106,12 @@ fn crypto_verify_secp_256_k_1_go() { world().run("scenarios/crypto_verify_secp256k1.scen.json"); } +#[test] +#[ignore = "requires EI 1.4 in mx-scenario-go"] +fn crypto_verify_secp_256_r_1_go() { + world().run("scenarios/crypto_verify_secp256r1.scen.json"); +} + #[test] fn echo_array_u_8_go() { world().run("scenarios/echo_array_u8.scen.json"); @@ -194,6 +217,11 @@ fn get_caller_go() { world().run("scenarios/get_caller.scen.json"); } +#[test] +fn get_code_metadata_go() { + world().run("scenarios/get_code_metadata.scen.json"); +} + #[test] fn get_cumulated_validator_rewards_go() { world().run("scenarios/get_cumulated_validator_rewards.scen.json"); @@ -205,6 +233,11 @@ fn get_shard_of_address_go() { world().run("scenarios/get_shard_of_address.scen.json"); } +#[test] +fn is_builtin_function_go() { + world().run("scenarios/is_builtin_function.scen.json"); +} + #[test] fn managed_address_array_go() { world().run("scenarios/managed_address_array.scen.json"); @@ -236,13 +269,18 @@ fn managed_buffer_set_random_go() { } #[test] -fn managed_vec_address_push_go() { - world().run("scenarios/managed_vec_address_push.scen.json"); +fn managed_decimal_go() { + world().run("scenarios/managed_decimal.scen.json"); } #[test] -fn managed_vec_array_push_go() { - world().run("scenarios/managed_vec_array_push.scen.json"); +fn managed_decimal_logarithm_go() { + world().run("scenarios/managed_decimal_logarithm.scen.json"); +} + +#[test] +fn managed_vec_address_push_go() { + world().run("scenarios/managed_vec_address_push.scen.json"); } #[test] @@ -250,6 +288,11 @@ fn managed_vec_biguint_push_go() { world().run("scenarios/managed_vec_biguint_push.scen.json"); } +#[test] +fn new_address_go() { + world().run("scenarios/new_address.scen.json"); +} + #[test] fn only_owner_go() { world().run("scenarios/only_owner.scen.json"); @@ -280,6 +323,11 @@ fn sc_properties_go() { world().run("scenarios/sc_properties.scen.json"); } +#[test] +fn small_num_overflow_go() { + world().run("scenarios/small_num_overflow.scen.json"); +} + #[test] fn storage_big_int_go() { world().run("scenarios/storage_big_int.scen.json"); @@ -336,13 +384,24 @@ fn storage_map_3_go() { } #[test] +fn storage_mapper_address_to_id_go() { + world().run("scenarios/storage_mapper_address_to_id.scen.json"); +} + +#[test] +#[ignore = "currently not supported. TODO: investigate"] fn storage_mapper_fungible_token_go() { world().run("scenarios/storage_mapper_fungible_token.scen.json"); } #[test] -fn storage_mapper_address_to_id_go() { - world().run("scenarios/storage_mapper_address_to_id.scen.json"); +fn storage_mapper_get_at_address_go() { + world().run("scenarios/storage_mapper_get_at_address.scen.json"); +} + +#[test] +fn storage_mapper_get_at_address_extra_key_go() { + world().run("scenarios/storage_mapper_get_at_address_extra_key.scen.json"); } #[test] @@ -411,7 +470,6 @@ fn storage_raw_api_features_go() { } #[test] -#[ignore = "the error message has changed, re-enable when we move to VM 1.5"] fn storage_reserved_go() { world().run("scenarios/storage_reserved.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 e496e1be7c..2689d7f3ec 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,16 +2,19 @@ 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( - "file:output/basic-features.wasm", + "mxsc:output/basic-features.mxsc.json", basic_features::ContractBuilder, ); blockchain.register_contract( - "file:../esdt-system-sc-mock/output/esdt-system-sc-mock.wasm", + "mxsc:../esdt-system-sc-mock/output/esdt-system-sc-mock.mxsc.json", esdt_system_sc_mock::ContractBuilder, ); + blockchain.register_contract( + "mxsc:output/basic-features-crypto.mxsc.json", + basic_features::ContractBuilder, + ); blockchain } @@ -41,6 +44,11 @@ fn big_uint_from_u_64_rs() { world().run("scenarios/big_uint_from_u64.scen.json"); } +#[test] +fn big_uint_pow_rs() { + world().run("scenarios/big_uint_pow.scen.json"); +} + #[test] fn big_uint_sqrt_rs() { world().run("scenarios/big_uint_sqrt.scen.json"); @@ -94,6 +102,18 @@ fn crypto_verify_bls_rs() { world().run("scenarios/crypto_verify_bls.scen.json"); } +#[test] +#[ignore] +fn crypto_verify_bls_share_rs() { + world().run("scenarios/crypto_verify_bls_share.scen.json"); +} + +#[test] +#[ignore] +fn crypto_verify_bls_aggregated_rs() { + world().run("scenarios/crypto_verify_bls_aggregated_signature.scen.json"); +} + #[test] fn crypto_verify_ed_25519_rs() { world().run("scenarios/crypto_verify_ed25519.scen.json"); @@ -105,6 +125,12 @@ fn crypto_verify_secp_256_k_1_rs() { world().run("scenarios/crypto_verify_secp256k1.scen.json"); } +#[test] +#[ignore] +fn crypto_verify_secp_256_r_1_rs() { + world().run("scenarios/crypto_verify_secp256r1.scen.json"); +} + #[test] fn echo_array_u_8_rs() { world().run("scenarios/echo_array_u8.scen.json"); @@ -210,6 +236,11 @@ fn get_caller_rs() { world().run("scenarios/get_caller.scen.json"); } +#[test] +fn get_code_metadata_rs() { + world().run("scenarios/get_code_metadata.scen.json"); +} + #[test] fn get_cumulated_validator_rewards_rs() { world().run("scenarios/get_cumulated_validator_rewards.scen.json"); @@ -220,6 +251,11 @@ fn get_shard_of_address_rs() { world().run("scenarios/get_shard_of_address.scen.json"); } +#[test] +fn is_builtin_function_rs() { + world().run("scenarios/is_builtin_function.scen.json"); +} + #[test] fn managed_address_array_rs() { world().run("scenarios/managed_address_array.scen.json"); @@ -252,13 +288,18 @@ fn managed_buffer_set_random_rs() { } #[test] -fn managed_vec_address_push_rs() { - world().run("scenarios/managed_vec_address_push.scen.json"); +fn managed_decimal_rs() { + world().run("scenarios/managed_decimal.scen.json"); +} + +#[test] +fn managed_decimal_logarithm_rs() { + world().run("scenarios/managed_decimal_logarithm.scen.json"); } #[test] -fn managed_vec_array_push_rs() { - world().run("scenarios/managed_vec_array_push.scen.json"); +fn managed_vec_address_push_rs() { + world().run("scenarios/managed_vec_address_push.scen.json"); } #[test] @@ -266,6 +307,11 @@ fn managed_vec_biguint_push_rs() { world().run("scenarios/managed_vec_biguint_push.scen.json"); } +#[test] +fn new_address_rs() { + world().run("scenarios/new_address.scen.json"); +} + #[test] fn only_owner_rs() { world().run("scenarios/only_owner.scen.json"); @@ -298,6 +344,11 @@ fn sc_properties_rs() { world().run("scenarios/sc_properties.scen.json"); } +#[test] +fn small_num_overflow_rs() { + world().run("scenarios/small_num_overflow.scen.json"); +} + #[test] fn storage_big_int_rs() { world().run("scenarios/storage_big_int.scen.json"); @@ -353,6 +404,11 @@ fn storage_map_3_rs() { world().run("scenarios/storage_map3.scen.json"); } +#[test] +fn storage_mapper_address_to_id_rs() { + world().run("scenarios/storage_mapper_address_to_id.scen.json"); +} + #[test] #[ignore] fn storage_mapper_fungible_token_rs() { @@ -360,8 +416,13 @@ fn storage_mapper_fungible_token_rs() { } #[test] -fn storage_mapper_address_to_id_rs() { - world().run("scenarios/storage_mapper_address_to_id.scen.json"); +fn storage_mapper_get_at_address_rs() { + world().run("scenarios/storage_mapper_get_at_address.scen.json"); +} + +#[test] +fn storage_mapper_get_at_address_extra_key_rs() { + world().run("scenarios/storage_mapper_get_at_address_extra_key.scen.json"); } #[test] diff --git a/contracts/feature-tests/basic-features/tests/basic_features_storage_mapper_get_at_address_go_test.rs b/contracts/feature-tests/basic-features/tests/basic_features_storage_mapper_get_at_address_go_test.rs new file mode 100644 index 0000000000..b746a1f337 --- /dev/null +++ b/contracts/feature-tests/basic-features/tests/basic_features_storage_mapper_get_at_address_go_test.rs @@ -0,0 +1,10 @@ +use multiversx_sc_scenario::*; + +fn world() -> ScenarioWorld { + ScenarioWorld::vm_go() +} + +#[test] +fn storage_mapper_get_at_address_go() { + world().run("scenarios/storage_mapper_get_at_address.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-crypto/Cargo.lock b/contracts/feature-tests/basic-features/wasm-basic-features-crypto/Cargo.lock new file mode 100644 index 0000000000..f906bd3d13 --- /dev/null +++ b/contracts/feature-tests/basic-features/wasm-basic-features-crypto/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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "basic-features" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "multiversx-sc-modules", +] + +[[package]] +name = "basic-features-crypto-wasm" +version = "0.0.0" +dependencies = [ + "basic-features", + "multiversx-sc-wasm-adapter", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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.53.0" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-modules" +version = "0.53.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.0" +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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +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/basic-features/wasm-basic-features-crypto/Cargo.toml b/contracts/feature-tests/basic-features/wasm-basic-features-crypto/Cargo.toml new file mode 100644 index 0000000000..fcb4704fc4 --- /dev/null +++ b/contracts/feature-tests/basic-features/wasm-basic-features-crypto/Cargo.toml @@ -0,0 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "basic-features-crypto-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.basic-features] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.53.0" +path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] diff --git a/contracts/feature-tests/basic-features/wasm-basic-features-crypto/src/lib.rs b/contracts/feature-tests/basic-features/wasm-basic-features-crypto/src/lib.rs new file mode 100644 index 0000000000..134138a65f --- /dev/null +++ b/contracts/feature-tests/basic-features/wasm-basic-features-crypto/src/lib.rs @@ -0,0 +1,27 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 3 +// 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! { + basic_features + ( + init => init + verify_secp256r1_signature => verify_secp256r1_signature + verify_bls_signature_share => verify_bls_signature_share + verify_bls_aggregated_signature => verify_bls_aggregated_signature + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} 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 c5cbaa694b..552b01b6ee 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 @@ -2,29 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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" @@ -44,15 +32,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -60,15 +42,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -77,61 +50,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 c1f9e3f5a4..2f0c5e0f6b 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 @@ -1,23 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "basic-features-storage-bytes-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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.basic-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 9524057356..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 403117034b..11c5370dd3 100755 --- a/contracts/feature-tests/basic-features/wasm/Cargo.lock +++ b/contracts/feature-tests/basic-features/wasm/Cargo.lock @@ -2,29 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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" @@ -44,15 +32,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -60,15 +42,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -77,61 +50,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/basic-features/wasm/Cargo.toml b/contracts/feature-tests/basic-features/wasm/Cargo.toml index c85c863d39..22ddc8a21d 100644 --- a/contracts/feature-tests/basic-features/wasm/Cargo.toml +++ b/contracts/feature-tests/basic-features/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "basic-features-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = true + +[profile.dev] +panic = "abort" [dependencies.basic-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 f097c6893f..8658d897ed 100644 --- a/contracts/feature-tests/basic-features/wasm/src/lib.rs +++ b/contracts/feature-tests/basic-features/wasm/src/lib.rs @@ -1,20 +1,16 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 348 +// Endpoints: 409 // Async Callback: 1 -// Total number of exported functions: 350 +// Total number of exported functions: 411 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -131,6 +127,8 @@ multiversx_sc_wasm_adapter::endpoints! { get_tx_hash => get_tx_hash get_gas_left => get_gas_left get_cumulated_validator_rewards => get_cumulated_validator_rewards + get_code_metadata => get_code_metadata + is_builtin_function => is_builtin_function codec_err_finish => codec_err_finish codec_err_storage_key => codec_err_storage_key codec_err_storage_get => codec_err_storage_get @@ -171,6 +169,7 @@ multiversx_sc_wasm_adapter::endpoints! { echo_big_int => echo_big_int echo_managed_buffer => echo_managed_buffer echo_managed_address => echo_managed_address + echo_managed_option => echo_managed_option echo_big_int_managed_vec => echo_big_int_managed_vec echo_big_int_tuple => echo_big_int_tuple echo_big_int_option => echo_big_int_option @@ -218,7 +217,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 @@ -310,6 +308,11 @@ multiversx_sc_wasm_adapter::endpoints! { set_mapper_insert => set_mapper_insert set_mapper_contains => set_mapper_contains set_mapper_remove => set_mapper_remove + set_mapper_front => set_mapper_front + set_mapper_back => set_mapper_back + set_mapper_next => set_mapper_next + set_mapper_previous => set_mapper_previous + set_mapper_iter_from_and_count => set_mapper_iter_from_and_count map_my_single_value_mapper => map_my_single_value_mapper my_single_value_mapper_increment_1 => my_single_value_mapper_increment_1 my_single_value_mapper_increment_2 => my_single_value_mapper_increment_2 @@ -320,6 +323,7 @@ multiversx_sc_wasm_adapter::endpoints! { is_empty_single_value_mapper => is_empty_single_value_mapper is_empty_at_address_single_value_mapper => is_empty_at_address_single_value_mapper raw_byte_length_single_value_mapper => raw_byte_length_single_value_mapper + set_single_value_mapper_with_key => set_single_value_mapper_with_key vec_mapper => vec_mapper vec_mapper_push => vec_mapper_push vec_mapper_get => vec_mapper_get @@ -364,12 +368,65 @@ multiversx_sc_wasm_adapter::endpoints! { unique_id_mapper_swap_remove => unique_id_mapper_swap_remove unique_id_mapper_set => unique_id_mapper_set unique_id_mapper => unique_id_mapper + unordered_set_mapper => unordered_set_mapper + unordered_set_mapper_insert => unordered_set_mapper_insert + unordered_set_mapper_contains => unordered_set_mapper_contains + unordered_set_mapper_remove => unordered_set_mapper_remove managed_struct_eq => managed_struct_eq + no_overflow_usize => no_overflow_usize + no_overflow_u8 => no_overflow_u8 + no_overflow_u16 => no_overflow_u16 + no_overflow_u32 => no_overflow_u32 + no_overflow_u64 => no_overflow_u64 + overflow_usize => overflow_usize + overflow_u8 => overflow_u8 + overflow_u16 => overflow_u16 + overflow_u32 => overflow_u32 + overflow_u64 => overflow_u64 + no_overflow_isize => no_overflow_isize + no_overflow_i8 => no_overflow_i8 + no_overflow_i16 => no_overflow_i16 + no_overflow_i32 => no_overflow_i32 + no_overflow_i64 => no_overflow_i64 + overflow_isize => overflow_isize + overflow_i8 => overflow_i8 + overflow_i16 => overflow_i16 + overflow_i32 => overflow_i32 + overflow_i64 => overflow_i64 token_identifier_egld => token_identifier_egld token_identifier_is_valid_1 => token_identifier_is_valid_1 token_identifier_is_valid_2 => token_identifier_is_valid_2 non_zero_usize_iter => non_zero_usize_iter non_zero_usize_macro => non_zero_usize_macro + returns_egld_decimal => returns_egld_decimal + set_contract_address => set_contract_address + is_empty_at_address => is_empty_at_address + contains_at_address => contains_at_address + len_at_address => len_at_address + next_at_address => next_at_address + previous_at_address => previous_at_address + front_at_address => front_at_address + 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 + get_value_from_address_with_keys => get_value_from_address_with_keys + 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 + managed_decimal_ln => managed_decimal_ln + managed_decimal_log2 => managed_decimal_log2 + managed_decimal_addition_var => managed_decimal_addition_var + managed_decimal_subtraction_var => managed_decimal_subtraction_var + managed_decimal_eq_var => managed_decimal_eq_var + managed_decimal_ln_var => managed_decimal_ln_var + managed_decimal_log2_var => managed_decimal_log2_var ) } diff --git a/contracts/feature-tests/big-float-features/Cargo.toml b/contracts/feature-tests/big-float-features/Cargo.toml index a0201dfb87..ccf656cc56 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 e234ac8f02..55f63536c4 100644 --- a/contracts/feature-tests/big-float-features/meta/Cargo.toml +++ b/contracts/feature-tests/big-float-features/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.big-float-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/big_float_ln.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_ln.scen.json new file mode 100644 index 0000000000..21e7b4a3c9 --- /dev/null +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_ln.scen.json @@ -0,0 +1,59 @@ +{ + "steps": [ + { + "step": "setState", + "accounts": { + "sc:basic-features": { + "nonce": "0", + "balance": "0", + "code": "mxsc:../output/big-float-features.mxsc.json" + }, + "address:an_account": { + "nonce": "0", + "balance": "100000000000" + } + } + }, + { + "step": "scCall", + "id": "ln_big_float_precision_9(23)", + "comment": "ln(23) = 3.135514648 (9 decimals)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "ln_big_float_precision_9", + "arguments": [ + "23" + ], + "gasLimit": "2,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "+3135514648" + ] + } + }, + { + "step": "scCall", + "id": "ln_big_float_any_precision(23, 9)", + "comment": "ln(23) = 3.135514648 (9 decimals)", + "tx": { + "from": "address:an_account", + "to": "sc:basic-features", + "function": "ln_big_float_any_precision", + "arguments": [ + "23", + "9" + ], + "gasLimit": "2,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "u32:5|+3135514648|u32:9" + ] + } + } + ] +} \ No newline at end of file diff --git a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_big_int.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_big_int.scen.json index f3b288dd3b..401aeeb905 100644 --- a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_big_int.scen.json +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_big_int.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/big-float-features.wasm" + "code": "mxsc:../output/big-float-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_big_uint.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_big_uint.scen.json index 964e25c159..4203bb3df7 100644 --- a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_big_uint.scen.json +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_big_uint.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/big-float-features.wasm" + "code": "mxsc:../output/big-float-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_frac.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_frac.scen.json index 2d29c89e72..090fbbcb6a 100644 --- a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_frac.scen.json +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_frac.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/big-float-features.wasm" + "code": "mxsc:../output/big-float-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_int.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_int.scen.json index 4b15a34334..3cebf84091 100644 --- a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_int.scen.json +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_int.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/big-float-features.wasm" + "code": "mxsc:../output/big-float-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_managed_buffer.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_managed_buffer.scen.json index a3bf11ac49..1b4bc80168 100644 --- a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_managed_buffer.scen.json +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_managed_buffer.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/big-float-features.wasm" + "code": "mxsc:../output/big-float-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_parts.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_parts.scen.json index fe1de964a3..2cf7257630 100644 --- a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_parts.scen.json +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_parts.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/big-float-features.wasm" + "code": "mxsc:../output/big-float-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_sci.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_sci.scen.json index f93cd46805..46815ec795 100644 --- a/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_sci.scen.json +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_new_from_sci.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/big-float-features.wasm" + "code": "mxsc:../output/big-float-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/big-float-features/scenarios/big_float_operator_checks.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_operator_checks.scen.json index a3a9e8e51e..e421ca6d55 100644 --- a/contracts/feature-tests/big-float-features/scenarios/big_float_operator_checks.scen.json +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_operator_checks.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/big-float-features.wasm" + "code": "mxsc:../output/big-float-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/big-float-features/scenarios/big_float_operators.scen.json b/contracts/feature-tests/big-float-features/scenarios/big_float_operators.scen.json index ba3e55602f..91c3128c8f 100644 --- a/contracts/feature-tests/big-float-features/scenarios/big_float_operators.scen.json +++ b/contracts/feature-tests/big-float-features/scenarios/big_float_operators.scen.json @@ -7,7 +7,7 @@ "sc:basic-features": { "nonce": "0", "balance": "0", - "code": "file:../output/big-float-features.wasm" + "code": "mxsc:../output/big-float-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -822,4 +822,4 @@ } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/big-float-features/src/big_float_main.rs b/contracts/feature-tests/big-float-features/src/big_float_main.rs index 17b83d0e57..53d2617406 100644 --- a/contracts/feature-tests/big-float-features/src/big_float_main.rs +++ b/contracts/feature-tests/big-float-features/src/big_float_main.rs @@ -5,6 +5,7 @@ multiversx_sc::imports!(); pub mod big_float_methods; pub mod big_float_methods_wrapped; pub mod big_float_operators; +pub mod big_float_operators_ln; pub mod big_float_operators_wrapped; #[multiversx_sc::contract] @@ -12,6 +13,7 @@ pub trait BigFloatFeatures: big_float_methods::BigFloatMethods + big_float_operators::BigFloatOperators + big_float_methods_wrapped::BigFloatWrappedMethods + + big_float_operators_ln::BigFloatWrappedLn + big_float_operators_wrapped::BigFloatWrappedOperators { #[init] diff --git a/contracts/feature-tests/big-float-features/src/big_float_operators_ln.rs b/contracts/feature-tests/big-float-features/src/big_float_operators_ln.rs new file mode 100644 index 0000000000..7831724475 --- /dev/null +++ b/contracts/feature-tests/big-float-features/src/big_float_operators_ln.rs @@ -0,0 +1,29 @@ +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait BigFloatWrappedLn { + #[endpoint] + fn ln_big_float_ref(&self, a: &BigFloat) -> BigFloat { + a.ln() + .unwrap_or_else(|| sc_panic!("log argument must pe strictly positive")) + } + + #[endpoint] + fn ln_big_float_precision_9( + &self, + a: BigInt, + ) -> ManagedDecimalSigned> { + let number = self.ln_big_float_ref(&BigFloat::from(a)); + number.to_managed_decimal_signed(ConstDecimals) + } + + #[endpoint] + fn ln_big_float_any_precision( + &self, + a: BigInt, + precision: usize, + ) -> ManagedDecimalSigned { + let number = self.ln_big_float_ref(&BigFloat::from(a)); + number.to_managed_decimal_signed(precision) + } +} diff --git a/contracts/feature-tests/big-float-features/tests/big_float_scenario_go_test.rs b/contracts/feature-tests/big-float-features/tests/big_float_scenario_go_test.rs index bdfc6a1045..1cedeaa2f7 100644 --- a/contracts/feature-tests/big-float-features/tests/big_float_scenario_go_test.rs +++ b/contracts/feature-tests/big-float-features/tests/big_float_scenario_go_test.rs @@ -4,6 +4,11 @@ fn world() -> ScenarioWorld { ScenarioWorld::vm_go() } +#[test] +fn big_float_ln_go() { + world().run("scenarios/big_float_ln.scen.json"); +} + #[test] fn big_float_new_from_big_int_go() { world().run("scenarios/big_float_new_from_big_int.scen.json"); 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 5bf7e4d21f..34bed93c83 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 @@ -2,16 +2,20 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/feature-tests/big-float-features"); blockchain.register_contract( - "file:output/big-float-features.wasm", + "mxsc:output/big-float-features.mxsc.json", big_float_features::ContractBuilder, ); blockchain } +#[test] +fn big_float_ln_rs() { + world().run("scenarios/big_float_ln.scen.json"); +} + #[test] fn big_float_new_from_big_int_rs() { world().run("scenarios/big_float_new_from_big_int.scen.json"); diff --git a/contracts/feature-tests/big-float-features/wasm/Cargo.lock b/contracts/feature-tests/big-float-features/wasm/Cargo.lock index 85fbf67e45..9093b47c6d 100644 --- a/contracts/feature-tests/big-float-features/wasm/Cargo.lock +++ b/contracts/feature-tests/big-float-features/wasm/Cargo.lock @@ -2,29 +2,17 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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" @@ -43,15 +31,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 7810a2b849..cde5b3fa3d 100644 --- a/contracts/feature-tests/big-float-features/wasm/Cargo.toml +++ b/contracts/feature-tests/big-float-features/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "big-float-features-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.big-float-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 1a809830a3..de85d10ea0 100644 --- a/contracts/feature-tests/big-float-features/wasm/src/lib.rs +++ b/contracts/feature-tests/big-float-features/wasm/src/lib.rs @@ -1,20 +1,16 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 70 +// Endpoints: 73 // Async Callback (empty): 1 -// Total number of exported functions: 72 +// Total number of exported functions: 75 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -76,6 +72,9 @@ multiversx_sc_wasm_adapter::endpoints! { pow_big_float_ref_wrapped => pow_big_float_ref_wrapped big_float_zero_wrapped => big_float_zero_wrapped big_float_neg_wrapped => big_float_neg_wrapped + ln_big_float_ref => ln_big_float_ref + ln_big_float_precision_9 => ln_big_float_precision_9 + ln_big_float_any_precision => ln_big_float_any_precision add_big_float_wrapped => add_big_float_wrapped add_big_float_ref_wrapped => add_big_float_ref_wrapped sub_big_float_wrapped => sub_big_float_wrapped diff --git a/contracts/feature-tests/composability/Cargo.toml b/contracts/feature-tests/composability/Cargo.toml index 3e4c350910..8992c9bdae 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" @@ -32,6 +35,10 @@ path = "recursive-caller" [dev-dependencies.vault] path = "vault" +[dependencies.multiversx-sc] +version = "0.53.0" +path = "../../../framework/base" + [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 a05475f257..7b160a15c2 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 178d66ec84..e9c34fde3f 100644 --- a/contracts/feature-tests/composability/builtin-func-features/meta/Cargo.toml +++ b/contracts/feature-tests/composability/builtin-func-features/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.builtin-func-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 03717d93b7..77c2c0f81b 100644 --- a/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.lock @@ -2,35 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "builtin-func-features" @@ -47,27 +35,12 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "endian-type" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 ef0e8e3338..0eb652185b 100644 --- a/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/builtin-func-features/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "builtin-func-features-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.builtin-func-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 0e3168c02b..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 2b6e75313b..9fd112249e 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 3aaa278709..5aa639c1b2 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.44.0" +version = "0.53.0" path = "../../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 95824b1820..09a5973970 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,9 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 a6af7efb78..af8b4b654f 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 b1f778cc8f..fa8c753791 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 @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "first-contract-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.first-contract] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 2d8aa35543..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/esdt-contract-pair/scenarios/init.scen.json b/contracts/feature-tests/composability/esdt-contract-pair/scenarios/init.scen.json index 05573ed441..365776cb72 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/scenarios/init.scen.json +++ b/contracts/feature-tests/composability/esdt-contract-pair/scenarios/init.scen.json @@ -28,7 +28,7 @@ "id": "deploy-first-contract", "tx": { "from": "address:owner", - "contractCode": "file:../first-contract/output/first-contract.wasm", + "contractCode": "mxsc:../first-contract/output/first-contract.mxsc.json", "arguments": [ "str:cool_token", "sc:second_contract" @@ -48,7 +48,7 @@ "id": "deploy-second-contract", "tx": { "from": "address:owner", - "contractCode": "file:../second-contract/output/second-contract.wasm", + "contractCode": "mxsc:../second-contract/output/second-contract.mxsc.json", "arguments": [ "str:cool_token" ], 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 ed190c4d3c..09d9cde1a9 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.44.0" +version = "0.53.0" path = "../../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 9108cc04be..3319be901e 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,9 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 8c6e36092d..646ffc8125 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 3fc674b727..2de10d221f 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 @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "second-contract-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.second-contract] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 c558f33b56..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/esdt-contract-pair/tests/scenario_rs_test.rs b/contracts/feature-tests/composability/esdt-contract-pair/tests/scenario_rs_test.rs index 2181443dce..74d345daf7 100644 --- a/contracts/feature-tests/composability/esdt-contract-pair/tests/scenario_rs_test.rs +++ b/contracts/feature-tests/composability/esdt-contract-pair/tests/scenario_rs_test.rs @@ -3,12 +3,12 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); blockchain.register_contract( - "file:first-contract/output/first-contract.wasm", + "mxsc:first-contract/output/first-contract.mxsc.json", first_contract::ContractBuilder, ); blockchain.register_contract( - "file:second-contract/output/second-contract.wasm", + "mxsc:second-contract/output/second-contract.mxsc.json", second_contract::ContractBuilder, ); blockchain 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 67fcf6963a..99f974234e 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 e82d985363..5f3e162b21 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.44.0" +version = "0.53.0" path = "../../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 d9c2035b9d..2bf4039778 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,9 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 070aefbb43..d59caeeaec 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "child" @@ -59,15 +41,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 170ca72796..bb3671a1da 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 @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "child-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.child] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 377ba27a6a..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 c48859a4eb..4244fe6db2 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.44.0" +version = "0.53.0" path = "../../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 11033ce54b..1f6538947c 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,9 +8,10 @@ publish = false path = ".." [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../../../../framework/base" -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 fce9414aba..db4a992a35 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 @@ -2,48 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "child" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -51,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -68,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,24 +98,17 @@ 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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "parent" version = "0.0.0" dependencies = [ - "child", "multiversx-sc", ] @@ -162,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 92f3b71dbe..f6a2a723be 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 @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "parent-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.parent] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 4ac844b663..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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..03464fb77a --- /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.53.0" +path = "../../../../framework/base" + +[dev-dependencies.multiversx-sc-scenario] +version = "0.53.0" +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..203f1cf2bc --- /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.53.0" +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 97% 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..6fa20793d8 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() @@ -128,8 +128,7 @@ pub trait ForwarderEsdtModule: storage::ForwarderStorageModule { // 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_issued_token().set(token_identifier.unwrap_esdt()); self.last_error_message().clear(); }, ManagedAsyncCallResult::Err(message) => { 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 96% 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 0a8241978c..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] @@ -26,6 +28,6 @@ pub trait UpgradeContractModule { ) { self.vault_proxy(child_sc_address) .init(opt_arg) - .upgrade_from_source(&source_address, CodeMetadata::DEFAULT) + .upgrade_from_source(&source_address, CodeMetadata::UPGRADEABLE) } } 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..4ae2239ba8 --- /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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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.53.0" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.0" +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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +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..46f9f1c9b4 --- /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.53.0" +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 c207e48de5..016d08c104 100644 --- a/contracts/feature-tests/composability/forwarder-queue/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-queue/Cargo.toml @@ -8,21 +8,15 @@ publish = false [lib] path = "src/forwarder_queue.rs" -[features] -promises = ["multiversx-sc/promises"] - -[dependencies.vault] -path = "../vault" - [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/base" [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" optional = true [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 1070c562f4..f31f2d43f9 100644 --- a/contracts/feature-tests/composability/forwarder-queue/meta/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-queue/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.forwarder-queue] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 555b0da532..161c5f7ce3 100644 --- a/contracts/feature-tests/composability/forwarder-queue/sc-config.toml +++ b/contracts/feature-tests/composability/forwarder-queue/sc-config.toml @@ -7,4 +7,7 @@ name = "forwarder-queue" [contracts.promises] name = "forwarder-queue-promises" add-labels = ["promises-callback"] -features = ["promises"] +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 1ef735ad6a..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,31 +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 => { - #[cfg(feature = "promises")] 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(); }, } @@ -209,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 2dc73f90f8..86f74a34b9 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -49,7 +31,6 @@ name = "forwarder-queue" version = "0.0.0" dependencies = [ "multiversx-sc", - "vault", ] [[package]] @@ -60,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -77,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -140,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -183,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -216,34 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "vault" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "version_check" -version = "0.9.4" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 7a11a330de..43eeeee811 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 @@ -1,24 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "forwarder-queue-promises-wasm" version = "0.0.0" -authors = ["Costin Carabas "] 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-queue] path = ".." -features = ["promises"] [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 7fb7618e6f..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -12,10 +12,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 ae4536abae..c1aa312ebc 100644 --- a/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -49,7 +31,6 @@ name = "forwarder-queue" version = "0.0.0" dependencies = [ "multiversx-sc", - "vault", ] [[package]] @@ -60,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -77,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -140,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -183,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -216,34 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "vault" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "version_check" -version = "0.9.4" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 9ee761fea7..b4a60f1948 100644 --- a/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-queue/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "forwarder-queue-wasm" version = "0.0.0" -authors = ["Costin Carabas "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.forwarder-queue] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 56eb47bc23..7613a7ad95 100644 --- a/contracts/feature-tests/composability/forwarder-queue/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder-queue/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 65c818508b..3449ee0fe5 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 24d578f44c..a99e066803 100644 --- a/contracts/feature-tests/composability/forwarder-raw/meta/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-raw/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.forwarder-raw] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 df0f6628c1..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 @@ -6,16 +6,18 @@ pub trait ForwarderRawDeployUpgrade { fn deploy_contract( &self, code: ManagedBuffer, + code_metadata: CodeMetadata, args: MultiValueEncoded, ) -> MultiValue2> { - self.send_raw() - .deploy_contract( - self.blockchain().get_gas_left(), - &BigUint::zero(), - &code, - CodeMetadata::DEFAULT, - &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() } @@ -23,34 +25,34 @@ pub trait ForwarderRawDeployUpgrade { fn deploy_from_source( &self, source_contract_address: ManagedAddress, - arguments: MultiValueEncoded, + code_metadata: CodeMetadata, + args: MultiValueEncoded, ) -> ManagedAddress { - let (address, _) = self.send_raw().deploy_from_source_contract( - self.blockchain().get_gas_left(), - &BigUint::zero(), - &source_contract_address, - CodeMetadata::DEFAULT, - &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, - arguments: MultiValueEncoded, + child_sc_address: ManagedAddress, + new_code: ManagedBuffer, + code_metadata: CodeMetadata, + args: MultiValueEncoded, ) { - self.send_raw().upgrade_contract( - child_sc_address, - self.blockchain().get_gas_left(), - &BigUint::zero(), - new_code, - CodeMetadata::UPGRADEABLE, - &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] @@ -58,15 +60,16 @@ pub trait ForwarderRawDeployUpgrade { &self, sc_address: ManagedAddress, source_contract_address: ManagedAddress, - arguments: MultiValueEncoded, + code_metadata: CodeMetadata, + args: MultiValueEncoded, ) { - self.send_raw().upgrade_from_source_contract( - &sc_address, - self.blockchain().get_gas_left(), - &BigUint::zero(), - &source_contract_address, - CodeMetadata::DEFAULT, - &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..07a095ed9d 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,15 @@ 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()) + .payment(NotPayable) // `()` and `NotPayable` both work + .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 bcb0c5879f..e9934c674e 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 9849a58667..2ddba1d010 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 @@ -1,23 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "forwarder-raw-init-async-call-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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-raw] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 42d5439702..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 @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 1 +// Upgrade: 1 +// Endpoints: 0 // Async Callback: 1 // Total number of exported functions: 3 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 dfd4e61771..335c2050b1 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 89f31d4bc4..8790eaab01 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 @@ -1,23 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "forwarder-raw-init-sync-call-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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-raw] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 df428ad9c6..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 ae1f0bc48f..c48f23611c 100755 --- a/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 05dc8f3c2a..70d30a4567 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder-raw/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "forwarder-raw-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.forwarder-raw] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 5e6fd99a6e..16ff76235c 100644 --- a/contracts/feature-tests/composability/forwarder-raw/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder-raw/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 250743e851..3623f1113a 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/forwarder/meta/Cargo.toml b/contracts/feature-tests/composability/forwarder/meta/Cargo.toml index 75c8fc1966..d8c2957670 100644 --- a/contracts/feature-tests/composability/forwarder/meta/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.forwarder] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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..c6e9dcb443 100644 --- a/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs +++ b/contracts/feature-tests/composability/forwarder/src/forwarder_main.rs @@ -1,41 +1,43 @@ #![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; +pub mod vault_upgrade_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..a4dbaa28b1 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_esdt.rs @@ -0,0 +1,218 @@ +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..11ef0b1a39 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/fwd_upgrade.rs @@ -0,0 +1,38 @@ +use crate::vault_upgrade_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_upgrade_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_upgrade_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..7f653bfa45 --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/vault_proxy.rs @@ -0,0 +1,235 @@ +// 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 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< + 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/src/vault_upgrade_proxy.rs b/contracts/feature-tests/composability/forwarder/src/vault_upgrade_proxy.rs new file mode 100644 index 0000000000..ee2a10a78f --- /dev/null +++ b/contracts/feature-tests/composability/forwarder/src/vault_upgrade_proxy.rs @@ -0,0 +1,59 @@ +// 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, + 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() + } +} diff --git a/contracts/feature-tests/composability/forwarder/tests/forwarder_whitebox_test.rs b/contracts/feature-tests/composability/forwarder/tests/forwarder_whitebox_test.rs deleted file mode 100644 index 121cd9b991..0000000000 --- a/contracts/feature-tests/composability/forwarder/tests/forwarder_whitebox_test.rs +++ /dev/null @@ -1,117 +0,0 @@ -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, -}; - -const USER_ADDRESS_EXPR: &str = "address:user"; -const FORWARDER_ADDRESS_EXPR: &str = "sc:forwarder"; -const FORWARDER_PATH_EXPR: &str = "file:output/forwarder.wasm"; - -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.set_current_dir_from_workspace("contracts/composability/forwarder"); - - blockchain.register_contract(FORWARDER_PATH_EXPR, forwarder::ContractBuilder); - blockchain -} - -#[test] -fn test_nft_update_attributes_and_send() { - let mut world = world(); - - let forwarder_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_code) - .esdt_roles(NFT_TOKEN_ID_EXPR, roles), - ), - ); - - let forwarder_whitebox = WhiteboxContract::new(FORWARDER_ADDRESS_EXPR, forwarder::contract_obj); - - let original_attributes = Color { r: 0, g: 0, b: 0 }; - - world.whitebox_call( - &forwarder_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_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/wasm/Cargo.lock b/contracts/feature-tests/composability/forwarder/wasm/Cargo.lock index 332a8282e2..a4b5837af2 100755 --- a/contracts/feature-tests/composability/forwarder/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/forwarder/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -49,7 +31,6 @@ name = "forwarder" version = "0.0.0" dependencies = [ "multiversx-sc", - "vault", ] [[package]] @@ -60,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -77,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -140,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -183,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -216,34 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "vault" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "version_check" -version = "0.9.4" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/composability/forwarder/wasm/Cargo.toml b/contracts/feature-tests/composability/forwarder/wasm/Cargo.toml index 1750f8bb52..4c3ba91578 100644 --- a/contracts/feature-tests/composability/forwarder/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/forwarder/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "forwarder-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.forwarder] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 7cba7cf2d2..fd2567f244 100644 --- a/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/forwarder/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 5bdd19d794..e06ae3c915 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.44.0" -path = "../../../../contracts/modules" +[dependencies.multiversx-sc] +version = "0.53.0" +path = "../../../../framework/base" [dependencies.multiversx-sc-snippets] -version = "0.44.0" +version = "0.53.0" 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 aa3b427df1..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,13 +20,13 @@ 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( - "file:../forwarder-queue/output/forwarder-queue.wasm", + "mxsc:../forwarder-queue/output/forwarder-queue.mxsc.json", &InterpreterContext::default(), ); let vault_code = BytesValue::interpret_from( - "file:../vault/output/vault.wasm", + "mxsc:../vault/output/vault.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..7f653bfa45 --- /dev/null +++ b/contracts/feature-tests/composability/interact/src/vault_proxy.rs @@ -0,0 +1,235 @@ +// 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 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< + 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 b081c9eac9..e63c0a4c07 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 6394075a8d..dfb650dd51 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,6 +7,7 @@ publish = false [dependencies.local-esdt-and-nft] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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..0291d36131 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 @@ -280,14 +276,13 @@ pub trait LocalEsdtAndEsdtNft { // 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_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.send().direct_egld(caller, &returned_tokens); + self.tx().to(caller).egld(&returned_tokens).transfer(); } self.last_error_message().set(&message.err_msg); @@ -311,7 +306,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 7b73f9a2ae..087e6f1f6a 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "local-esdt-and-nft" @@ -82,48 +55,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 9648aff7b2..ab44b1e438 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 @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "local-esdt-and-nft-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.local-esdt-and-nft] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 ca4aca4a95..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 4a8deceba6..810d51c4d5 100644 --- a/contracts/feature-tests/composability/promises-features/Cargo.toml +++ b/contracts/feature-tests/composability/promises-features/Cargo.toml @@ -8,14 +8,7 @@ publish = false [lib] path = "src/promises_main.rs" -[dependencies.vault] -path = "../vault" - [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/base" -features = ["promises", "back-transfers"] -[dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" -path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/promises-features/meta/Cargo.toml b/contracts/feature-tests/composability/promises-features/meta/Cargo.toml index af7925b6c7..58c533722b 100644 --- a/contracts/feature-tests/composability/promises-features/meta/Cargo.toml +++ b/contracts/feature-tests/composability/promises-features/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.promises-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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_sync_bt.rs b/contracts/feature-tests/composability/promises-features/src/call_sync_bt.rs deleted file mode 100644 index 9c9b293bbc..0000000000 --- a/contracts/feature-tests/composability/promises-features/src/call_sync_bt.rs +++ /dev/null @@ -1,35 +0,0 @@ -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, - to: ManagedAddress, - token: EgldOrEsdtTokenIdentifier, - token_nonce: u64, - amount: BigUint, - ) { - let ((), back_transfers) = self - .vault_proxy() - .contract(to) - .retrieve_funds(token, token_nonce, amount) - .execute_on_dest_context_with_back_transfers::<()>(); - - self.back_transfers_event( - &back_transfers.total_egld_amount, - &back_transfers.esdt_payments.into_multi_value(), - ); - } - - #[event("back_tranfers")] - fn back_transfers_event( - &self, - #[indexed] egld_value: &BigUint, - #[indexed] multi_esdt: &MultiValueEncoded, - ); -} 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 64% 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 6b3dcaebb0..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, 1002)) + 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, 2002)) + 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(); } @@ -58,7 +55,7 @@ pub trait CallPromisesDirectModule { &self, #[call_result] result: MultiValueEncoded, arg1: usize, - arg2: usize, + arg2: BigUint, ) { self.async_call_event_callback(arg1, arg2, &result.into_vec_of_buffers()); } @@ -67,7 +64,7 @@ pub trait CallPromisesDirectModule { fn async_call_event_callback( &self, #[indexed] arg1: usize, - #[indexed] arg2: usize, + #[indexed] arg2: BigUint, arguments: &ManagedVec, ); } 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/fwd_call_sync_bt.rs b/contracts/feature-tests/composability/promises-features/src/fwd_call_sync_bt.rs new file mode 100644 index 0000000000..d31ac022dc --- /dev/null +++ b/contracts/feature-tests/composability/promises-features/src/fwd_call_sync_bt.rs @@ -0,0 +1,86 @@ +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 { + #[endpoint] + fn forward_sync_retrieve_funds_bt( + &self, + to: ManagedAddress, + token: EgldOrEsdtTokenIdentifier, + token_nonce: u64, + amount: BigUint, + ) { + let back_transfers = self + .tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .retrieve_funds(token, token_nonce, amount) + .returns(ReturnsBackTransfers) + .sync_call(); + + require!( + back_transfers.esdt_payments.len() == 1 || back_transfers.total_egld_amount != 0, + "Only one ESDT payment expected" + ); + + self.back_transfers_event( + &back_transfers.total_egld_amount, + &back_transfers.esdt_payments.into_multi_value(), + ); + } + + #[endpoint] + fn forward_sync_retrieve_funds_bt_twice( + &self, + to: ManagedAddress, + token: EgldOrEsdtTokenIdentifier, + token_nonce: u64, + amount: BigUint, + ) { + let back_transfers = self + .tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .retrieve_funds(token.clone(), token_nonce, amount.clone()) + .returns(ReturnsBackTransfers) + .sync_call(); + + require!( + back_transfers.esdt_payments.len() == 1 || back_transfers.total_egld_amount != 0, + "Only one ESDT payment expected" + ); + + self.back_transfers_event( + &back_transfers.total_egld_amount, + &back_transfers.esdt_payments.into_multi_value(), + ); + + let back_transfers = self + .tx() + .to(&to) + .typed(vault_proxy::VaultProxy) + .retrieve_funds(token, token_nonce, amount) + .returns(ReturnsBackTransfers) + .sync_call(); + + require!( + back_transfers.esdt_payments.len() == 1 || back_transfers.total_egld_amount != 0, + "Only one ESDT payment expected" + ); + + self.back_transfers_event( + &back_transfers.total_egld_amount, + &back_transfers.esdt_payments.into_multi_value(), + ); + } + + #[event("back_tranfers")] + fn back_transfers_event( + &self, + #[indexed] egld_value: &BigUint, + #[indexed] multi_esdt: &MultiValueEncoded, + ); +} 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..7f653bfa45 --- /dev/null +++ b/contracts/feature-tests/composability/promises-features/src/vault_proxy.rs @@ -0,0 +1,235 @@ +// 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 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< + 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/tests/promises_feature_blackbox_test.rs b/contracts/feature-tests/composability/promises-features/tests/promises_feature_blackbox_test.rs deleted file mode 100644 index f681c18f29..0000000000 --- a/contracts/feature-tests/composability/promises-features/tests/promises_feature_blackbox_test.rs +++ /dev/null @@ -1,101 +0,0 @@ -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 = "file:output/promises-feature.wasm"; -const VAULT_ADDRESS_EXPR: &str = "sc:vault"; -const VAULT_PATH_EXPR: &str = "file:../vault/output/vault.wasm"; - -const TOKEN_ID_EXPR: &str = "str:TOKEN-123456"; -const TOKEN_ID: &[u8] = b"TOKEN-123456"; - -type PromisesFeaturesContract = ContractInfo>; -type VaultContract = ContractInfo>; - -fn world() -> ScenarioWorld { - let mut blockchain = ScenarioWorld::new(); - blockchain.set_current_dir_from_workspace("contracts/composability/promises-feature"); - - blockchain.register_contract( - PROMISES_FEATURES_PATH_EXPR, - promises_features::ContractBuilder, - ); - blockchain.register_contract(VAULT_PATH_EXPR, 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, - } - } -} - -#[test] -#[ignore = "waiting for vm1.5"] -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 - .check_state_step(CheckStateStep::new().put_account( - state.promises_features_contract, - CheckAccount::new().esdt_balance(TOKEN_ID_EXPR, token_amount), - )); -} diff --git a/contracts/feature-tests/composability/promises-features/wasm/Cargo.lock b/contracts/feature-tests/composability/promises-features/wasm/Cargo.lock index 3a6526a6b2..7703e8cf36 100644 --- a/contracts/feature-tests/composability/promises-features/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/promises-features/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,24 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -151,7 +119,6 @@ name = "promises-features" version = "0.0.0" dependencies = [ "multiversx-sc", - "vault", ] [[package]] @@ -164,9 +131,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -183,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -216,34 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "vault" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "version_check" -version = "0.9.4" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 2a17435262..087281836e 100644 --- a/contracts/feature-tests/composability/promises-features/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/promises-features/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "promises-features-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.promises-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 73ec37b99a..1dc649df0d 100644 --- a/contracts/feature-tests/composability/promises-features/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/promises-features/wasm/src/lib.rs @@ -1,21 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 9 +// Endpoints: 10 // Async Callback (empty): 1 // Promise callbacks: 3 -// Total number of exported functions: 14 +// Total number of exported functions: 15 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -31,6 +27,7 @@ multiversx_sc_wasm_adapter::endpoints! { promise_raw_single_token => promise_raw_single_token promise_raw_multi_transfer => promise_raw_multi_transfer forward_sync_retrieve_funds_bt => forward_sync_retrieve_funds_bt + forward_sync_retrieve_funds_bt_twice => forward_sync_retrieve_funds_bt_twice forward_promise_retrieve_funds_back_transfers => forward_promise_retrieve_funds_back_transfers retrieve_funds_callback => retrieve_funds_callback the_one_callback => the_one_callback diff --git a/contracts/feature-tests/composability/proxy-test-first/Cargo.toml b/contracts/feature-tests/composability/proxy-test-first/Cargo.toml index cbd52266d6..1979d318fb 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.44.0" +version = "0.53.0" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 eb0237f2a2..9d6fa7bc28 100644 --- a/contracts/feature-tests/composability/proxy-test-first/meta/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-first/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.proxy-test-first] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 97dcf6f6f8..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::DEFAULT); + .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) - .with_egld_transfer(payment.clone_value()) - .upgrade_contract(&code, CodeMetadata::DEFAULT); + 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 c6c817c156..b6e5bb4386 100755 --- a/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,24 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -164,9 +132,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -183,26 +151,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -216,27 +173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 d02b8366db..303ee9acff 100644 --- a/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-first/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "proxy-test-first-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.proxy-test-first] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 aa2c820ac6..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 9f9c6b7c16..0e56e59713 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.44.0" +version = "0.53.0" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 d2b627b2bc..c8831c473b 100644 --- a/contracts/feature-tests/composability/proxy-test-second/meta/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-second/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.proxy-test-second] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/src/proxy-test-second.rs b/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs index 3bf0e3f089..33f199cfb5 100644 --- a/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs +++ b/contracts/feature-tests/composability/proxy-test-second/src/proxy-test-second.rs @@ -34,6 +34,12 @@ pub trait ProxyTestSecond { init_arg + 1 } + #[upgrade] + #[payable("EGLD")] + fn upgrade(&self, init_arg: i32) -> i32 { + self.init(init_arg) + } + #[payable("EGLD")] #[endpoint(payMe)] fn pay_me(&self, arg1: i64) { 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 2252a3249c..b989e3ae84 100755 --- a/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,24 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -163,9 +131,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 62b788ae38..b35f7667f0 100644 --- a/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/proxy-test-second/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "proxy-test-second-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.proxy-test-second] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 0fa4134bbf..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 @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 +// Upgrade: 1 // Endpoints: 3 // Async Callback (empty): 1 -// Total number of exported functions: 5 +// Total number of exported functions: 6 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,6 +19,7 @@ multiversx_sc_wasm_adapter::endpoints! { proxy_test_second ( init => init + upgrade => upgrade payMe => pay_me payMeWithResult => pay_me_with_result_endpoint messageMe => message_me diff --git a/contracts/feature-tests/composability/recursive-caller/Cargo.toml b/contracts/feature-tests/composability/recursive-caller/Cargo.toml index b36a402f3c..70361935fe 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 7961ea007b..cb45e19721 100644 --- a/contracts/feature-tests/composability/recursive-caller/meta/Cargo.toml +++ b/contracts/feature-tests/composability/recursive-caller/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.recursive-caller] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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..7f653bfa45 --- /dev/null +++ b/contracts/feature-tests/composability/recursive-caller/src/vault_proxy.rs @@ -0,0 +1,235 @@ +// 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 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< + 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 06a99b5731..1553be7c07 100755 --- a/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -183,26 +151,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -216,34 +173,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "vault" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - -[[package]] -name = "version_check" -version = "0.9.4" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" [[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" +name = "vault" +version = "0.0.0" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", + "multiversx-sc", ] diff --git a/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.toml b/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.toml index c7545ec11e..373cbbceab 100644 --- a/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/recursive-caller/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "recursive-caller-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.recursive-caller] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 ec9e1f9a8c..a129056010 100644 --- a/contracts/feature-tests/composability/recursive-caller/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/recursive-caller/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); diff --git a/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_egld_2.scen.json b/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_egld_2.scen.json index a3063d4fd4..cefb775799 100644 --- a/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_egld_2.scen.json +++ b/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_egld_2.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", "balance": "1000", - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } }, @@ -48,7 +48,9 @@ "str:EGLD", "1" ], - "data": "2" + "data": [ + "2" + ] }, { "address": "sc:vault", @@ -59,7 +61,7 @@ "1", "0" ], - "data": "" + "data": "*" }, { "address": "sc:recursive-caller", @@ -69,7 +71,9 @@ "str:EGLD", "1" ], - "data": "2" + "data": [ + "2" + ] }, { "address": "sc:recursive-caller", @@ -79,7 +83,9 @@ "str:EGLD", "1" ], - "data": "1" + "data": [ + "1" + ] }, { "address": "sc:vault", @@ -90,7 +96,7 @@ "1", "0" ], - "data": "" + "data": "*" }, { "address": "sc:recursive-caller", @@ -100,7 +106,9 @@ "str:EGLD", "1" ], - "data": "1" + "data": [ + "1" + ] } ], "gas": "*", @@ -122,13 +130,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "2" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", "balance": "998", "storage": {}, - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_egld_x.scen.json b/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_egld_x.scen.json index de57ad4749..457db86a61 100644 --- a/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_egld_x.scen.json +++ b/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_egld_x.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", "balance": "1000", - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } }, @@ -59,13 +59,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "5" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", "balance": "995", "storage": {}, - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_esdt_2.scen.json b/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_esdt_2.scen.json index 6fffb3d06d..ffc23e59f8 100644 --- a/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_esdt_2.scen.json +++ b/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_esdt_2.scen.json @@ -11,7 +11,7 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", @@ -19,7 +19,7 @@ "esdt": { "str:REC-TOKEN": "1000" }, - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } }, @@ -51,7 +51,9 @@ "str:REC-TOKEN", "1" ], - "data": "2" + "data": [ + "2" + ] }, { "address": "sc:vault", @@ -62,7 +64,7 @@ "1", "0" ], - "data": "" + "data": "*" }, { "address": "sc:recursive-caller", @@ -72,7 +74,9 @@ "str:REC-TOKEN", "1" ], - "data": "2" + "data": [ + "2" + ] }, { "address": "sc:recursive-caller", @@ -82,7 +86,9 @@ "str:REC-TOKEN", "1" ], - "data": "1" + "data": [ + "1" + ] }, { "address": "sc:vault", @@ -93,7 +99,7 @@ "1", "0" ], - "data": "" + "data": "*" }, { "address": "sc:recursive-caller", @@ -103,7 +109,9 @@ "str:REC-TOKEN", "1" ], - "data": "1" + "data": [ + "1" + ] } ], "gas": "*", @@ -128,7 +136,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "*" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", @@ -137,7 +145,7 @@ "str:REC-TOKEN": "999" }, "storage": {}, - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_esdt_x.scen.json b/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_esdt_x.scen.json index b87d98ba3c..c828788784 100644 --- a/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_esdt_x.scen.json +++ b/contracts/feature-tests/composability/scenarios-unsupported/recursive_caller_esdt_x.scen.json @@ -11,7 +11,7 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", @@ -19,7 +19,7 @@ "esdt": { "str:REC-TOKEN": "1000" }, - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } }, @@ -65,7 +65,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "*" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", @@ -74,7 +74,7 @@ "str:REC-TOKEN": "995" }, "storage": {}, - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/builtin_func_delete_user_name.scen.json b/contracts/feature-tests/composability/scenarios/builtin_func_delete_user_name.scen.json index 7414fa5875..e190c58b59 100644 --- a/contracts/feature-tests/composability/scenarios/builtin_func_delete_user_name.scen.json +++ b/contracts/feature-tests/composability/scenarios/builtin_func_delete_user_name.scen.json @@ -15,7 +15,7 @@ "sc:dns#00": { "nonce": "0", "balance": "0", - "code": "file:../builtin-func-features/output/builtin-func-features.wasm" + "code": "mxsc:../builtin-func-features/output/builtin-func-features.mxsc.json" } } }, @@ -33,6 +33,7 @@ "gasPrice": "0" }, "expect": { + "out": [], "status": "0" } }, @@ -51,7 +52,7 @@ "sc:dns#00": { "nonce": "0", "balance": "0", - "code": "file:../builtin-func-features/output/builtin-func-features.wasm" + "code": "mxsc:../builtin-func-features/output/builtin-func-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/builtin_func_set_user_name.scen.json b/contracts/feature-tests/composability/scenarios/builtin_func_set_user_name.scen.json index e52de6e930..ca5e99f9f9 100644 --- a/contracts/feature-tests/composability/scenarios/builtin_func_set_user_name.scen.json +++ b/contracts/feature-tests/composability/scenarios/builtin_func_set_user_name.scen.json @@ -14,7 +14,7 @@ "sc:dns#00": { "nonce": "0", "balance": "0", - "code": "file:../builtin-func-features/output/builtin-func-features.wasm" + "code": "mxsc:../builtin-func-features/output/builtin-func-features.mxsc.json" } } }, @@ -33,6 +33,7 @@ "gasPrice": "0" }, "expect": { + "out": [], "status": "0" } }, @@ -51,7 +52,7 @@ "sc:dns#00": { "nonce": "0", "balance": "0", - "code": "file:../builtin-func-features/output/builtin-func-features.wasm" + "code": "mxsc:../builtin-func-features/output/builtin-func-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_queue_async.scen.json b/contracts/feature-tests/composability/scenarios/forw_queue_async.scen.json index b3b1e29284..87a52541e8 100644 --- a/contracts/feature-tests/composability/scenarios/forw_queue_async.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_queue_async.scen.json @@ -1,5 +1,4 @@ { - "gasSchedule": "v3", "steps": [ { "step": "setState", @@ -11,12 +10,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder-queue": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-queue/output/forwarder-queue.wasm" + "code": "mxsc:../forwarder-queue/output/forwarder-queue.mxsc.json" } } }, @@ -36,6 +35,7 @@ "gasPrice": "0" }, "expect": { + "out": [], "status": "0" } }, @@ -46,10 +46,12 @@ "from": "address:a_user", "to": "sc:forwarder-queue", "function": "forward_queued_calls", + "arguments": [], "gasLimit": "50,000,000", "gasPrice": "0" }, "expect": { + "out": [], "status": "0", "logs": [ { @@ -62,17 +64,16 @@ "str:accept_funds", "1000" ], - "data": "" + "data": "*" }, { "address": "*", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder-queue", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": "*" }, { "address": "sc:vault", @@ -81,7 +82,20 @@ "str:accept_funds", "0x03e8" ], - "data": "" + "data": "*" + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:forwarder-queue" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] } ], "gas": "*", @@ -103,12 +117,12 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder-queue": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-queue/output/forwarder-queue.wasm" + "code": "mxsc:../forwarder-queue/output/forwarder-queue.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_egld.scen.json index d254e67690..bcb4567d0e 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -40,14 +40,16 @@ "status": "0", "logs": [ { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:AsyncCall", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -56,7 +58,22 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:forwarder" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] }, { "address": "sc:forwarder", @@ -64,9 +81,11 @@ "topics": [ "str:callback_raw" ], - "data": { - "0-status": "nested:0x00" - } + "data": [ + { + "0-status": "nested:0x00" + } + ] } ], "gas": "*", @@ -88,7 +107,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -99,7 +118,7 @@ "nested:0x00" ] }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_esdt.scen.json index 0b0cb4fdf8..b6d2e8cb32 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_async_accept_esdt.scen.json @@ -14,12 +14,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -52,11 +52,17 @@ "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:vault" ], - "data": "" + "data": [ + "str:AsyncCall", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -68,7 +74,22 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:forwarder" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] }, { "address": "sc:forwarder", @@ -76,9 +97,11 @@ "topics": [ "str:callback_raw" ], - "data": { - "0-status": "nested:0x00" - } + "data": [ + { + "0-status": "nested:0x00" + } + ] } ], "gas": "*", @@ -106,7 +129,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -117,7 +140,7 @@ "nested:0x00" ] }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_async_echo.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_async_echo.scen.json index 3106ae3f82..153137c062 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_async_echo.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_async_echo.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -43,19 +43,50 @@ ], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:AsyncCall", + "str:echo_arguments", + "1", + "2" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:forwarder" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00", + "1", + "2" + ] + }, { "address": "sc:forwarder", "endpoint": "str:callBack", "topics": [ "str:callback_raw" ], - "data": { - "0-status": "nested:0x00", - "1-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-status": "nested:0x00", + "1-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] } ], "gas": "*", @@ -77,7 +108,7 @@ "storage": { "str:call_counts|nested:str:echo_arguments": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -90,7 +121,7 @@ "biguint:2" ] }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_async_send_and_retrieve_multi_transfer_funds.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_async_send_and_retrieve_multi_transfer_funds.scen.json index e4851ad8cb..50768223c6 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_async_send_and_retrieve_multi_transfer_funds.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_async_send_and_retrieve_multi_transfer_funds.scen.json @@ -21,7 +21,7 @@ ] } }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -40,7 +40,7 @@ ] } }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -94,7 +94,7 @@ } }, "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -130,7 +130,7 @@ }, "str:callback_payments.len": "2" }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_builtin_nft_local_mint_via_async_call.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_builtin_nft_local_mint_via_async_call.scen.json index 9e170ecb5b..2cf72e9e6c 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_builtin_nft_local_mint_via_async_call.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_builtin_nft_local_mint_via_async_call.scen.json @@ -20,7 +20,7 @@ ] } }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -52,7 +52,20 @@ "0", "1200" ], - "data": "" + "data": [] + }, + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:forwarder" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] }, { "address": "sc:forwarder", @@ -60,7 +73,9 @@ "topics": [ "str:callback_raw" ], - "data": "nested:0x00" + "data": [ + "nested:0x00" + ] } ], "gas": "*", @@ -93,7 +108,7 @@ "str:callback_args.len": "1", "str:callback_args.item|u32:01": "nested:0x00" }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_builtin_nft_local_mint_via_sync_call.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_builtin_nft_local_mint_via_sync_call.scen.json index 6503cb4257..2cede897ee 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_builtin_nft_local_mint_via_sync_call.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_builtin_nft_local_mint_via_sync_call.scen.json @@ -20,7 +20,7 @@ ] } }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -52,7 +52,7 @@ "0", "1200" ], - "data": "" + "data": [] }, { "address": "sc:forwarder", @@ -60,7 +60,9 @@ "topics": [ "str:execute_on_dest_context_result" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -90,7 +92,7 @@ } }, "storage": {}, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_call_async_retrieve_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_call_async_retrieve_multi_transfer.scen.json index 6420fcf2a2..efd575bd41 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_call_async_retrieve_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_call_async_retrieve_multi_transfer.scen.json @@ -22,12 +22,12 @@ ] } }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -79,7 +79,7 @@ } }, "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -104,7 +104,7 @@ }, "str:callback_payments.len": "1" }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } 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 3019e05d6e..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 @@ -11,7 +11,7 @@ "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } }, "newAddresses": [ @@ -40,7 +40,8 @@ "to": "sc:forwarder", "function": "deploy_contract", "arguments": [ - "file:../vault/output/vault.wasm" + "mxsc:../vault/output/vault.mxsc.json", + "0x0100" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -63,7 +64,8 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", + "codeMetadata": "0x0100", "owner": "sc:forwarder" }, "+": "" @@ -77,7 +79,8 @@ "to": "sc:forwarder", "function": "deploy_contract", "arguments": [ - "file:../vault/output/vault.wasm", + "mxsc:../vault/output/vault.mxsc.json", + "0x0100", "str:some_argument" ], "gasLimit": "50,000,000", @@ -85,7 +88,6 @@ }, "expect": { "out": [ - "str:some_argument", "sc:child-with-arg", "nested:str:some_argument" ], @@ -102,7 +104,8 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", + "codeMetadata": "0x0100", "owner": "sc:forwarder" }, "+": "" @@ -117,6 +120,7 @@ "function": "deploy_from_source", "arguments": [ "sc:child", + "0x0100", "str:some_argument" ], "gasLimit": "50,000,000", @@ -124,7 +128,6 @@ }, "expect": { "out": [ - "str:some_argument", "sc:child-src-with-arg" ], "status": "0", @@ -140,7 +143,8 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", + "codeMetadata": "0x0100", "owner": "sc:forwarder" }, "+": "" diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_contract_upgrade.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_contract_upgrade.scen.json index 0d8672d169..99400cb23c 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_contract_upgrade.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_contract_upgrade.scen.json @@ -6,37 +6,43 @@ "accounts": { "address:a_user": {}, "sc:forwarder": { - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" + }, + "sc:reference": { + "code": "mxsc:../vault/output/vault-upgrade.mxsc.json" }, "sc:child": { - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", "owner": "sc:forwarder" } } }, { "step": "scCall", - "id": "upgrade-vault-to-forwarder", + "id": "upgrade-vault-from-source", "tx": { "from": "address:a_user", "to": "sc:forwarder", "function": "call_upgrade_from_source", "arguments": [ "sc:child", - "sc:forwarder" + "sc:reference", + "0x0102" ], "gasLimit": "500,000,000", "gasPrice": "0" }, "expect": { - "out": [] + "out": "*", + "status": "" } }, { "step": "checkState", "accounts": { "sc:child": { - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../vault/output/vault-upgrade.mxsc.json", + "codeMetadata": "0x0102" }, "+": "" } @@ -50,7 +56,8 @@ "function": "call_upgrade", "arguments": [ "sc:child", - "file:../vault/output/vault.wasm", + "mxsc:../vault/output/vault.mxsc.json", + "0x0102", "str:upgrade-init-arg" ], "gasLimit": "500,000,000", @@ -58,6 +65,7 @@ }, "expect": { "out": [ + "str:upgraded", "str:upgrade-init-arg" ] } @@ -66,7 +74,8 @@ "step": "checkState", "accounts": { "sc:child": { - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json", + "codeMetadata": "0x0102" }, "+": "" } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_contract_upgrade_self.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_contract_upgrade_self.scen.json index 027f242aa3..1b9ecffa92 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_contract_upgrade_self.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_contract_upgrade_self.scen.json @@ -6,11 +6,11 @@ "accounts": { "address:a_user": {}, "sc:forwarder": { - "code": "file:../forwarder-raw/output/forwarder-raw.wasm", + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json", "owner": "sc:forwarder" }, - "sc:vault": { - "code": "file:../vault/output/vault.wasm" + "sc:reference": { + "code": "mxsc:../vault/output/vault-upgrade.mxsc.json" } } }, @@ -23,13 +23,16 @@ "function": "call_upgrade_from_source", "arguments": [ "sc:forwarder", - "sc:vault" + "sc:reference", + "0x0102" ], "gasLimit": "500,000,000", "gasPrice": "0" }, "expect": { - "out": [] + "out": [ + "str:upgraded" + ] } }, { @@ -39,11 +42,12 @@ "nonce": "*" }, "sc:forwarder": { - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault-upgrade.mxsc.json", + "codeMetadata": "0x0102", "owner": "sc:forwarder" }, - "sc:vault": { - "code": "file:../vault/output/vault.wasm" + "sc:reference": { + "code": "mxsc:../vault/output/vault-upgrade.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_direct_egld.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_direct_egld.scen.json index ecea60c879..987ae3a743 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_direct_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_direct_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -55,13 +55,13 @@ "nonce": "0", "balance": "1000", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_direct_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_direct_esdt.scen.json index 02c5b80081..22e32a8c15 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_direct_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_direct_esdt.scen.json @@ -14,12 +14,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -51,11 +51,16 @@ "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:vault" ], - "data": "" + "data": [ + "str:DirectCall", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000" + ] } ], "gas": "*", @@ -81,13 +86,13 @@ "str:TEST-TOKENA": "1000" }, "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_direct_multi_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_direct_multi_esdt.scen.json index a2dcaa1d3b..ba3ad97b1d 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_direct_multi_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_direct_multi_esdt.scen.json @@ -19,7 +19,7 @@ "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -75,7 +75,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_init_async.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_init_async.scen.json index 0095ed9dc2..55415d5dcc 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_init_async.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_init_async.scen.json @@ -10,7 +10,7 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" } }, "newAddresses": [ @@ -26,7 +26,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../forwarder-raw/output/forwarder-raw-init-async-call.wasm", + "contractCode": "mxsc:../forwarder-raw/output/forwarder-raw-init-async-call.mxsc.json", "arguments": [ "sc:vault", "str:echo_arguments", diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_init_sync_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_init_sync_accept_egld.scen.json index 5fc148b2e4..c9cd3868aa 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_init_sync_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_init_sync_accept_egld.scen.json @@ -10,7 +10,7 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" } }, "newAddresses": [ @@ -26,8 +26,8 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../forwarder-raw/output/forwarder-raw-init-sync-call.wasm", "egldValue": "1000", + "contractCode": "mxsc:../forwarder-raw/output/forwarder-raw-init-sync-call.mxsc.json", "arguments": [ "sc:vault", "str:accept_funds" 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 ece56f50d9..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 @@ -10,7 +10,7 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" } }, "newAddresses": [ @@ -26,7 +26,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../forwarder-raw/output/forwarder-raw-init-sync-call.wasm", + "contractCode": "mxsc:../forwarder-raw/output/forwarder-raw-init-sync-call.mxsc.json", "arguments": [ "sc:vault", "str:echo_arguments", @@ -37,24 +37,37 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2" - ], + "out": [], "status": "", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_arguments", + "1", + "2" + ] + }, { "address": "sc:forwarder", "endpoint": "", "topics": [ "str:execute_on_dest_context_result" ], - "data": { - "0-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] } ], "gas": "*", 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 8c14b4df7a..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 @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -37,24 +37,37 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2" - ], + "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_arguments", + "1", + "2" + ] + }, { "address": "sc:forwarder", "endpoint": "str:call_execute_on_dest_context", "topics": [ "str:execute_on_dest_context_result" ], - "data": { - "0-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] } ], "gas": "*", @@ -78,26 +91,51 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2", - "1", - "2" - ], + "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_arguments", + "1", + "2" + ] + }, { "address": "sc:forwarder", "endpoint": "str:call_execute_on_dest_context_twice", "topics": [ "str:execute_on_dest_context_result" ], - "data": { - "0-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] + }, + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_arguments", + "1", + "2" + ] }, { "address": "sc:forwarder", @@ -105,12 +143,14 @@ "topics": [ "str:execute_on_dest_context_result" ], - "data": { - "0-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] } ], "gas": "*", 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 cfcf393b11..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 @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -35,11 +35,21 @@ "gasPrice": "0" }, "expect": { - "out": [ - "sc:forwarder" - ], + "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_caller" + ] + }, { "address": "sc:forwarder", "endpoint": "str:call_execute_on_dest_context", @@ -70,12 +80,21 @@ "gasPrice": "0" }, "expect": { - "out": [ - "sc:forwarder", - "sc:forwarder" - ], + "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_caller" + ] + }, { "address": "sc:forwarder", "endpoint": "str:call_execute_on_dest_context_twice", @@ -86,6 +105,18 @@ "nested:sc:forwarder" ] }, + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_caller" + ] + }, { "address": "sc:forwarder", "endpoint": "str:call_execute_on_dest_context_twice", diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_sync_egld.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_sync_egld.scen.json index fe6e6d878d..fea874bedc 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_sync_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_sync_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -40,14 +40,16 @@ "status": "0", "logs": [ { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -56,7 +58,9 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:forwarder", @@ -64,7 +68,9 @@ "topics": [ "str:execute_on_dest_context_result" ], - "data": {} + "data": [ + {} + ] } ], "gas": "*", @@ -91,14 +97,16 @@ "status": "0", "logs": [ { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "500" + "500", + "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -107,7 +115,9 @@ "str:accept_funds", "500" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:forwarder", @@ -115,17 +125,21 @@ "topics": [ "str:execute_on_dest_context_result" ], - "data": {} + "data": [ + {} + ] }, { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "500" + "500", + "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -134,7 +148,9 @@ "str:accept_funds", "500" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:forwarder", @@ -142,7 +158,9 @@ "topics": [ "str:execute_on_dest_context_result" ], - "data": {} + "data": [ + {} + ] } ], "gas": "*", 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 26d1bab3f0..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 @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -37,10 +37,7 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2" - ], + "out": [], "status": "", "gas": "*", "refund": "*" @@ -59,13 +56,13 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } 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 d59d7077ff..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 @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -38,24 +38,37 @@ "gasPrice": "0" }, "expect": { - "out": [ - "1", - "2" - ], + "out": [], "status": "", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:forwarder" + ], + "data": [ + "str:ExecuteOnSameContext", + "str:echo_arguments", + "1", + "2" + ] + }, { "address": "sc:forwarder", "endpoint": "str:call_execute_on_same_context", "topics": [ "str:execute_on_same_context_result" ], - "data": { - "0-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] } ], "gas": "*", @@ -75,7 +88,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -83,7 +96,7 @@ "storage": { "str:call_counts|nested:str:echo_arguments": "1" }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_sync_same_context_egld.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_sync_same_context_egld.scen.json index 7443d68fdc..1d05069f9b 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_sync_same_context_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_sync_same_context_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -56,7 +56,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -64,7 +64,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_transf_exec_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_transf_exec_accept_egld.scen.json index 1e5e457201..16d11f4bb7 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_transf_exec_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_transf_exec_accept_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -58,13 +58,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, @@ -105,13 +105,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "2" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forw_raw_transf_exec_reject_egld.scen.json b/contracts/feature-tests/composability/scenarios/forw_raw_transf_exec_reject_egld.scen.json index 9e88f15e13..18851435bf 100644 --- a/contracts/feature-tests/composability/scenarios/forw_raw_transf_exec_reject_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forw_raw_transf_exec_reject_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder-raw/output/forwarder-raw.wasm" + "code": "mxsc:../forwarder-raw/output/forwarder-raw.mxsc.json" } } }, diff --git a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_add_quantity.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_add_quantity.scen.json index 49f0ad828a..4ff37f31bb 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_add_quantity.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_add_quantity.scen.json @@ -35,7 +35,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -51,7 +51,7 @@ "lastNonce": "1" } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -82,7 +82,7 @@ "1", "1200" ], - "data": "" + "data": [] } ], "gas": "*", @@ -149,7 +149,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -165,7 +165,7 @@ "lastNonce": "1" } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_burn.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_burn.scen.json index e21cf50060..556dde1c70 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_burn.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_burn.scen.json @@ -35,7 +35,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -51,7 +51,7 @@ "lastNonce": "1" } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -82,7 +82,7 @@ "1", "1200" ], - "data": "" + "data": [] } ], "gas": "*", @@ -149,7 +149,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -166,7 +166,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_create.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_create.scen.json index 55fe0a1c20..8c922a3c10 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_create.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_create.scen.json @@ -35,7 +35,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -51,7 +51,7 @@ "lastNonce": "1" } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -90,7 +90,7 @@ "1", "*" ], - "data": "" + "data": [] }, { "address": "sc:forwarder", @@ -101,7 +101,9 @@ "2", "1" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -184,7 +186,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -200,7 +202,7 @@ "lastNonce": "1" } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_local_burn.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_local_burn.scen.json index 2ab770183b..e77d6f0ab1 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_local_burn.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_local_burn.scen.json @@ -21,7 +21,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -36,7 +36,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -66,7 +66,7 @@ "0", "2000" ], - "data": "" + "data": [] } ], "gas": "*", @@ -118,7 +118,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -133,7 +133,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_local_mint.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_local_mint.scen.json index 110df179af..30fe3af1a1 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_local_mint.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_builtin_nft_local_mint.scen.json @@ -21,7 +21,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -36,7 +36,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -66,7 +66,7 @@ "0", "1200" ], - "data": "" + "data": [] } ], "gas": "*", @@ -118,7 +118,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:forwarder2": { "nonce": "0", @@ -133,7 +133,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_egld.scen.json index 9b98f84d10..551d98b2e3 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -39,14 +39,16 @@ "status": "0", "logs": [ { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:AsyncCall", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -55,7 +57,22 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:forwarder" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] } ], "gas": "*", @@ -77,13 +94,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_esdt.scen.json index 9ff0fe9485..3420580fea 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_esdt.scen.json @@ -14,12 +14,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -51,11 +51,17 @@ "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:vault" ], - "data": "" + "data": [ + "str:AsyncCall", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -67,7 +73,22 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:forwarder" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] } ], "gas": "*", @@ -95,13 +116,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_nft.scen.json index d299df3cf8..7ed9909961 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_accept_nft.scen.json @@ -25,12 +25,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -67,7 +67,15 @@ "01", "sc:vault" ], - "data": "" + "data": [ + "str:AsyncCall", + "str:ESDTNFTTransfer", + "str:NFT-000001", + "5", + "1", + "sc:vault", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -79,7 +87,22 @@ "5", "1" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:forwarder" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] } ], "gas": "*", @@ -119,13 +142,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json index de77e0e73d..81b18ee338 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_multi_transfer.scen.json @@ -30,12 +30,12 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" } } }, @@ -85,7 +85,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -110,7 +110,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -179,7 +179,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "2" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -195,7 +195,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_egld.scen.json index ad3624c70b..f9091ab5a9 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "1000", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -40,6 +40,21 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:AsyncCall", + "str:retrieve_funds", + "str:EGLD", + "0", + "1000" + ] + }, { "address": "sc:vault", "endpoint": "str:retrieve_funds", @@ -49,17 +64,34 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] }, { - "address": "*", + "address": "sc:vault", "endpoint": "str:transferValueOnly", "topics": [ - "sc:vault", - "sc:forwarder", - "1000" + "1000", + "sc:forwarder" + ], + "data": [ + "str:BackTransfer", + "0" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "1000", + "sc:forwarder" ], - "data": "" + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] }, { "address": "sc:forwarder", @@ -70,7 +102,9 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -90,13 +124,13 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "1000", "storage": "*", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_esdt.scen.json index dcfb83a5de..caf1a68f68 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_esdt.scen.json @@ -14,12 +14,12 @@ "esdt": { "str:TEST-TOKENA": "1000" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -43,6 +43,21 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "", + "sc:vault" + ], + "data": [ + "str:AsyncCall", + "str:retrieve_funds", + "str:TEST-TOKENA", + "0", + "1000" + ] + }, { "address": "sc:vault", "endpoint": "str:retrieve_funds", @@ -52,18 +67,25 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:vault", "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:forwarder" ], - "data": "" + "data": [ + "str:BackTransfer", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000" + ] }, { "address": "sc:forwarder", @@ -74,7 +96,9 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -94,7 +118,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -103,7 +127,7 @@ "str:TEST-TOKENA": "1000" }, "storage": "*", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_nft.scen.json index de3ec7f0e8..9fee9ad370 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_async_retrieve_nft.scen.json @@ -21,12 +21,12 @@ ] } }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -50,6 +50,21 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "", + "sc:vault" + ], + "data": [ + "str:AsyncCall", + "str:retrieve_funds", + "str:NFT-000001", + "5", + "01" + ] + }, { "address": "sc:vault", "endpoint": "str:retrieve_funds", @@ -59,7 +74,9 @@ "5", "1" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:vault", @@ -70,7 +87,14 @@ "01", "sc:forwarder" ], - "data": "" + "data": [ + "str:BackTransfer", + "str:ESDTNFTTransfer", + "str:NFT-000001", + "5", + "01", + "sc:forwarder" + ] }, { "address": "sc:forwarder", @@ -81,7 +105,9 @@ "*", "*" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -101,7 +127,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -117,7 +143,7 @@ } }, "storage": "*", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_egld.scen.json index ec45c50163..25f2522e76 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -39,14 +39,16 @@ "status": "0", "logs": [ { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:accept_funds_echo_payment" + ] }, { "address": "sc:vault", @@ -55,7 +57,9 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:forwarder", @@ -64,7 +68,9 @@ "str:accept_funds_sync_result", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -86,13 +92,13 @@ "storage": { "str:call_counts|nested:str:accept_funds_echo_payment": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_esdt.scen.json index d13dfecca8..fa529ed939 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_esdt.scen.json @@ -14,12 +14,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -81,11 +81,17 @@ "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000", + "str:accept_funds_echo_payment" + ] }, { "address": "sc:vault", @@ -97,7 +103,9 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:forwarder", @@ -109,7 +117,9 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -137,13 +147,13 @@ "storage": { "str:call_counts|nested:str:accept_funds_echo_payment": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_multi_transfer.scen.json index a4ab7d4054..2801ef7051 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_multi_transfer.scen.json @@ -30,12 +30,12 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" } } }, @@ -80,53 +80,42 @@ "str:FWD-TOKEN", "0", "100", - "sc:vault" - ], - "data": "" - }, - { - "address": "sc:forwarder", - "endpoint": "str:MultiESDTNFTTransfer", - "topics": [ "str:FWD-TOKEN", "0", "200", - "sc:vault" - ], - "data": "" - }, - { - "address": "sc:forwarder", - "endpoint": "str:MultiESDTNFTTransfer", - "topics": [ "str:NFT-123456", "1", "1", - "sc:vault" - ], - "data": "" - }, - { - "address": "sc:forwarder", - "endpoint": "str:MultiESDTNFTTransfer", - "topics": [ "str:SFT-456789", "3", "3", - "sc:vault" - ], - "data": "" - }, - { - "address": "sc:forwarder", - "endpoint": "str:MultiESDTNFTTransfer", - "topics": [ "str:SFT-456789", "3", "4", "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:MultiESDTNFTTransfer", + "sc:vault", + "5", + "str:FWD-TOKEN", + "0", + "100", + "str:FWD-TOKEN", + "0", + "200", + "str:NFT-123456", + "1", + "1", + "str:SFT-456789", + "3", + "3", + "str:SFT-456789", + "3", + "4", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -150,7 +139,9 @@ "3", "4" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -191,7 +182,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -208,7 +199,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_nft.scen.json index 939e11b718..716e9540be 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_nft.scen.json @@ -25,12 +25,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -64,10 +64,18 @@ "topics": [ "str:NFT-000001", "5", - "1", + "01", "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:ESDTNFTTransfer", + "str:NFT-000001", + "5", + "1", + "sc:vault", + "str:accept_funds_echo_payment" + ] }, { "address": "sc:vault", @@ -79,7 +87,9 @@ "5", "1" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:forwarder", @@ -91,7 +101,9 @@ "5", "1" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -131,13 +143,13 @@ "storage": { "str:call_counts|nested:str:accept_funds_echo_payment": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_egld.scen.json index a3484dfb21..284d9fd86d 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -41,14 +41,16 @@ "status": "0", "logs": [ { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -57,7 +59,22 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:call_counts", + "str:accept_funds" + ] } ], "gas": "*", @@ -79,13 +96,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_esdt.scen.json index 60b14e8a0a..c5453377e4 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_esdt.scen.json @@ -14,12 +14,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -53,11 +53,17 @@ "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -69,7 +75,22 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:call_counts", + "str:accept_funds" + ] } ], "gas": "*", @@ -97,13 +118,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_nft.scen.json index 65e361bb83..dde828970f 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_accept_then_read_nft.scen.json @@ -25,12 +25,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -69,7 +69,15 @@ "01", "sc:vault" ], - "data": "" + "data": [ + "str:ExecuteOnDestContext", + "str:ESDTNFTTransfer", + "str:NFT-000001", + "5", + "1", + "sc:vault", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -81,7 +89,22 @@ "5", "1" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:call_counts", + "str:accept_funds" + ] } ], "gas": "*", @@ -121,13 +144,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_egld.scen.json index 204e9b2964..898b02e3f8 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "1000", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -40,6 +40,21 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:retrieve_funds", + "str:EGLD", + "0", + "1000" + ] + }, { "address": "sc:vault", "endpoint": "str:retrieve_funds", @@ -49,17 +64,21 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] }, { - "address": "*", + "address": "sc:vault", "endpoint": "str:transferValueOnly", "topics": [ - "sc:vault", - "sc:forwarder", - "1000" + "1000", + "sc:forwarder" ], - "data": "" + "data": [ + "str:BackTransfer", + "0" + ] } ], "gas": "*", @@ -79,13 +98,13 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "1000", "storage": "*", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/forwarder_call_sync_retrieve_egld_bt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_egld_bt.scen.json similarity index 87% rename from contracts/feature-tests/composability/scenarios-promises/forwarder_call_sync_retrieve_egld_bt.scen.json rename to contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_egld_bt.scen.json index 073adba08c..5d7d625f85 100644 --- a/contracts/feature-tests/composability/scenarios-promises/forwarder_call_sync_retrieve_egld_bt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_egld_bt.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "1000", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, @@ -26,7 +26,7 @@ "tx": { "from": "address:a_user", "to": "sc:forwarder", - "function": "forward_sync_retrieve_funds", + "function": "forward_sync_retrieve_funds_bt", "arguments": [ "sc:vault", "str:EGLD", @@ -43,7 +43,7 @@ { "address": "sc:forwarder", "endpoint": "str:transferValueOnly", - "topics": [ + "topics": [ "0", "sc:vault" ], @@ -71,7 +71,7 @@ { "address": "sc:vault", "endpoint": "str:transferValueOnly", - "topics": [ + "topics": [ "1000", "sc:forwarder" ], @@ -82,7 +82,7 @@ }, { "address": "sc:forwarder", - "endpoint": "str:forward_sync_retrieve_funds", + "endpoint": "str:forward_sync_retrieve_funds_bt", "topics": [ "str:back_tranfers", "1000" @@ -109,13 +109,13 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "1000", "storage": "*", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_esdt.scen.json index aed08a2a1e..f69c714886 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_esdt.scen.json @@ -14,12 +14,12 @@ "esdt": { "str:TEST-TOKENA": "1000" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -43,6 +43,21 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:retrieve_funds", + "str:TEST-TOKENA", + "0", + "1000" + ] + }, { "address": "sc:vault", "endpoint": "str:retrieve_funds", @@ -52,18 +67,25 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:vault", "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:forwarder" ], - "data": "" + "data": [ + "str:BackTransfer", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000" + ] } ], "gas": "*", @@ -83,7 +105,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -92,7 +114,7 @@ "str:TEST-TOKENA": "1000" }, "storage": "*", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/forwarder_call_sync_retrieve_esdt_bt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_esdt_bt.scen.json similarity index 89% rename from contracts/feature-tests/composability/scenarios-promises/forwarder_call_sync_retrieve_esdt_bt.scen.json rename to contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_esdt_bt.scen.json index fb57d6d388..cc09dab90a 100644 --- a/contracts/feature-tests/composability/scenarios-promises/forwarder_call_sync_retrieve_esdt_bt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_esdt_bt.scen.json @@ -14,12 +14,12 @@ "esdt": { "str:TEST-TOKENA": "1000" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, @@ -29,7 +29,7 @@ "tx": { "from": "address:a_user", "to": "sc:forwarder", - "function": "forward_sync_retrieve_funds", + "function": "forward_sync_retrieve_funds_bt", "arguments": [ "sc:vault", "str:TEST-TOKENA", @@ -46,7 +46,7 @@ { "address": "sc:forwarder", "endpoint": "str:transferValueOnly", - "topics": [ + "topics": [ "", "sc:vault" ], @@ -74,7 +74,7 @@ { "address": "sc:vault", "endpoint": "str:ESDTTransfer", - "topics": [ + "topics": [ "str:TEST-TOKENA", "0", "1000", @@ -89,7 +89,7 @@ }, { "address": "sc:forwarder", - "endpoint": "str:forward_sync_retrieve_funds", + "endpoint": "str:forward_sync_retrieve_funds_bt", "topics": [ "str:back_tranfers", "0", @@ -119,7 +119,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -128,7 +128,7 @@ "str:TEST-TOKENA": "1000" }, "storage": "*", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_nft.scen.json index 10fc06f83a..4b64d33e43 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_nft.scen.json @@ -21,12 +21,12 @@ ] } }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -50,6 +50,21 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:retrieve_funds", + "str:NFT-000001", + "5", + "01" + ] + }, { "address": "sc:vault", "endpoint": "str:retrieve_funds", @@ -59,7 +74,9 @@ "5", "1" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:vault", @@ -70,7 +87,14 @@ "01", "sc:forwarder" ], - "data": "" + "data": [ + "str:BackTransfer", + "str:ESDTNFTTransfer", + "str:NFT-000001", + "5", + "01", + "sc:forwarder" + ] } ], "gas": "*", @@ -90,7 +114,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -106,7 +130,7 @@ } }, "storage": "*", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/forwarder_call_sync_retrieve_nft_bt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_nft_bt.scen.json similarity index 90% rename from contracts/feature-tests/composability/scenarios-promises/forwarder_call_sync_retrieve_nft_bt.scen.json rename to contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_nft_bt.scen.json index 87a1e4e70e..cd0501af64 100644 --- a/contracts/feature-tests/composability/scenarios-promises/forwarder_call_sync_retrieve_nft_bt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_sync_retrieve_nft_bt.scen.json @@ -21,12 +21,12 @@ ] } }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, @@ -36,7 +36,7 @@ "tx": { "from": "address:a_user", "to": "sc:forwarder", - "function": "forward_sync_retrieve_funds", + "function": "forward_sync_retrieve_funds_bt", "arguments": [ "sc:vault", "str:NFT-000001", @@ -53,7 +53,7 @@ { "address": "sc:forwarder", "endpoint": "str:transferValueOnly", - "topics": [ + "topics": [ "", "sc:vault" ], @@ -81,7 +81,7 @@ { "address": "sc:vault", "endpoint": "str:ESDTNFTTransfer", - "topics": [ + "topics": [ "str:NFT-000001", "5", "01", @@ -98,7 +98,7 @@ }, { "address": "sc:forwarder", - "endpoint": "str:forward_sync_retrieve_funds", + "endpoint": "str:forward_sync_retrieve_funds_bt", "topics": [ "str:back_tranfers", "0", @@ -128,7 +128,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -144,7 +144,7 @@ } }, "storage": "*", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld.scen.json index 6bea05217e..0b635d585e 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -39,14 +39,16 @@ "status": "0", "logs": [ { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -55,7 +57,9 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -77,13 +81,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld_twice.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld_twice.scen.json index 67436ed1f6..8c93ba20d8 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld_twice.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_egld_twice.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -39,14 +39,16 @@ "status": "0", "logs": [ { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -55,17 +57,21 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] }, { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -74,7 +80,9 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -96,13 +104,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "2" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt.scen.json index edb0352d03..8ca18d2175 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt.scen.json @@ -14,12 +14,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -51,11 +51,17 @@ "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -67,7 +73,9 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -95,13 +103,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt_twice.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt_twice.scen.json index de1b57fbd0..cd975b5e41 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt_twice.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_esdt_twice.scen.json @@ -14,12 +14,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -51,11 +51,17 @@ "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -67,18 +73,26 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:forwarder", "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -90,7 +104,9 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -118,13 +134,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "2" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json index efd0428f2c..3902c8306e 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_multi_transfer.scen.json @@ -30,12 +30,12 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" } } }, @@ -63,8 +63,51 @@ "out": [], "status": "0", "message": "", - "gas": "*", - "refund": "*" + "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:MultiESDTNFTTransfer", + "topics": [ + "str:FWD-TOKEN", + "0", + "100", + "str:FWD-TOKEN", + "0", + "200", + "sc:vault" + ], + "data": [ + "str:TransferAndExecute", + "str:MultiESDTNFTTransfer", + "sc:vault", + "2", + "str:FWD-TOKEN", + "0", + "100", + "str:FWD-TOKEN", + "0", + "200", + "str:accept_funds" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:accept_funds", + "topics": [ + "str:accept_funds", + "0", + "str:FWD-TOKEN", + "0", + "100", + "str:FWD-TOKEN", + "0", + "200" + ], + "data": [ + "" + ] + } + ] } }, { @@ -85,7 +128,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -110,7 +153,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -179,7 +222,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "2" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -196,7 +239,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_nft.scen.json index f9c0cf7201..d3d22a9e91 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_nft.scen.json @@ -21,12 +21,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -63,7 +63,15 @@ "01", "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:ESDTNFTTransfer", + "str:NFT-000001", + "5", + "1", + "sc:vault", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -75,7 +83,9 @@ "5", "1" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -107,13 +117,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_return_values.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_return_values.scen.json index 6c1242ab80..c861c4c39d 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_return_values.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_return_values.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -44,14 +44,16 @@ "status": "0", "logs": [ { - "address": "*", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -60,7 +62,9 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -82,13 +86,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_sft_twice.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_sft_twice.scen.json index 7a1279f1e8..1fd4532450 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_sft_twice.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_accept_sft_twice.scen.json @@ -21,12 +21,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -63,7 +63,15 @@ "01", "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:ESDTNFTTransfer", + "str:NFT-000001", + "5", + "1", + "sc:vault", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -75,7 +83,9 @@ "5", "1" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:forwarder", @@ -86,7 +96,15 @@ "01", "sc:vault" ], - "data": "" + "data": [ + "str:TransferAndExecute", + "str:ESDTNFTTransfer", + "str:NFT-000001", + "5", + "1", + "sc:vault", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -98,7 +116,9 @@ "5", "1" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -127,13 +147,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "2" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_reject_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_reject_multi_transfer.scen.json index 4155aed706..75e226f62e 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_reject_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_reject_multi_transfer.scen.json @@ -30,12 +30,12 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" } } }, @@ -80,7 +80,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -105,7 +105,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_reject_nft.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_reject_nft.scen.json index c1c0dc7f5f..43b327c0a6 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_reject_nft.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_call_transf_exec_reject_nft.scen.json @@ -11,7 +11,7 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -26,7 +26,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, diff --git a/contracts/feature-tests/composability/scenarios/forwarder_contract_change_owner.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_contract_change_owner.scen.json index 92bfc2874b..04da8ca5e6 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_contract_change_owner.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_contract_change_owner.scen.json @@ -7,10 +7,10 @@ "address:a_user": {}, "address:new_owner": {}, "sc:forwarder": { - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "sc:child": { - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", "owner": "sc:forwarder" } } @@ -42,7 +42,7 @@ "step": "checkState", "accounts": { "sc:child": { - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", "owner": "address:new_owner" }, "+": "" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_contract_deploy.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_contract_deploy.scen.json index 4dec52453f..546edd3c23 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_contract_deploy.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_contract_deploy.scen.json @@ -11,7 +11,7 @@ "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } }, "newAddresses": [ @@ -50,7 +50,7 @@ "to": "sc:forwarder", "function": "deploy_contract", "arguments": [ - "file:../vault/output/vault.wasm" + "mxsc:../vault/output/vault.mxsc.json" ], "gasLimit": "50,000,000", "gasPrice": "0" @@ -72,7 +72,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", "owner": "sc:forwarder" }, "+": "" @@ -86,7 +86,7 @@ "to": "sc:forwarder", "function": "deploy_contract", "arguments": [ - "file:../vault/output/vault.wasm", + "mxsc:../vault/output/vault.mxsc.json", "str:some_argument" ], "gasLimit": "50,000,000", @@ -110,7 +110,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", "owner": "sc:forwarder" }, "+": "" @@ -124,7 +124,7 @@ "to": "sc:forwarder", "function": "deploy_two_contracts", "arguments": [ - "file:../vault/output/vault.wasm" + "mxsc:../vault/output/vault.mxsc.json" ], "gasLimit": "80,000,000", "gasPrice": "0" @@ -147,14 +147,14 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", "owner": "sc:forwarder" }, "sc:child3": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", "owner": "sc:forwarder" }, "+": "" @@ -192,7 +192,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", "owner": "sc:forwarder" }, "+": "" diff --git a/contracts/feature-tests/composability/scenarios/forwarder_contract_upgrade.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_contract_upgrade.scen.json index 645d99a63d..a5434efd3c 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_contract_upgrade.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_contract_upgrade.scen.json @@ -6,37 +6,42 @@ "accounts": { "address:a_user": {}, "sc:forwarder": { - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" + }, + "sc:reference": { + "code": "mxsc:../vault/output/vault-upgrade.mxsc.json" }, "sc:child": { - "code": "file:../vault/output/vault.wasm", + "code": "mxsc:../vault/output/vault.mxsc.json", "owner": "sc:forwarder" } } }, { "step": "scCall", - "id": "upgrade-vault-to-forwarder", + "id": "upgrade-vault-from-source", "tx": { "from": "address:a_user", "to": "sc:forwarder", "function": "upgrade_vault_from_source", "arguments": [ "sc:child", - "sc:forwarder" + "sc:reference" ], "gasLimit": "500,000,000", "gasPrice": "0" }, "expect": { - "out": [] + "out": "*", + "status": "" } }, { "step": "checkState", "accounts": { "sc:child": { - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../vault/output/vault-upgrade.mxsc.json", + "codeMetadata": "0x0100" }, "+": "" } @@ -51,20 +56,64 @@ "function": "upgradeVault", "arguments": [ "sc:child", - "file:../vault/output/vault.wasm" + "mxsc:../vault/output/vault.mxsc.json", + "str:arg" ], "gasLimit": "500,000,000", "gasPrice": "0" }, "expect": { - "out": [] + "out": "*", + "status": "", + "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "", + "sc:child" + ], + "data": [ + "str:UpgradeFromSource", + "str:upgradeContract", + "*", + "0x0100", + "str:arg" + ] + }, + { + "address": "sc:child", + "endpoint": "str:upgradeContract", + "topics": [ + "str:upgraded" + ], + "data": [ + "" + ] + }, + { + "address": "sc:child", + "endpoint": "str:transferValueOnly", + "topics": [ + "", + "sc:forwarder" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00", + "str:upgraded", + "str:arg" + ] + } + ] } }, { "step": "checkState", "accounts": { "sc:child": { - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "+": "" } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_get_esdt_local_roles.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_get_esdt_local_roles.scen.json index 007c8186c9..33a415bcfb 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_get_esdt_local_roles.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_get_esdt_local_roles.scen.json @@ -11,7 +11,7 @@ "esdt": { "str:ESDT-123456": "200" }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:viewer": { "nonce": "0", @@ -54,7 +54,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:viewer": { "nonce": "0", @@ -100,7 +100,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:viewer": { "nonce": "0", @@ -149,7 +149,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:viewer": { "nonce": "0", diff --git a/contracts/feature-tests/composability/scenarios/forwarder_get_esdt_token_data.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_get_esdt_token_data.scen.json index 494fcd97d1..5fc05dbe4b 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_get_esdt_token_data.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_get_esdt_token_data.scen.json @@ -36,7 +36,7 @@ "frozen": "true" } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:other": { "nonce": "0", @@ -166,6 +166,33 @@ "status": "0" } }, + { + "step": "scQuery", + "id": "missing-account", + "tx": { + "to": "sc:forwarder", + "function": "get_esdt_token_data", + "arguments": [ + "address:missing-account", + "str:FUNG-00001", + "0" + ] + }, + "expect": { + "out": [ + "0", + "0", + "false", + "", + "", + "", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "", + "" + ], + "status": "0" + } + }, { "step": "scQuery", "id": "missing-token", diff --git a/contracts/feature-tests/composability/scenarios/forwarder_nft_add_uri.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_nft_add_uri.scen.json index 4994109512..d4ba6b40c2 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_nft_add_uri.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_nft_add_uri.scen.json @@ -24,7 +24,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -56,7 +56,7 @@ "", "str:new-uri-1" ], - "data": "" + "data": [] } ], "gas": "*", @@ -91,7 +91,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -125,7 +125,7 @@ "str:new-uri-2", "str:new-uri-3" ], - "data": "" + "data": [] } ], "gas": "*", @@ -162,7 +162,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_nft_create.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_nft_create.scen.json index 0b9d9e9043..f1c91862d2 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_nft_create.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_nft_create.scen.json @@ -35,7 +35,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -74,7 +74,7 @@ "1", "*" ], - "data": "" + "data": [] }, { "address": "sc:forwarder", @@ -85,7 +85,9 @@ "2", "1" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -140,7 +142,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_nft_create_and_send.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_nft_create_and_send.scen.json index 15816150d1..047037ce69 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_nft_create_and_send.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_nft_create_and_send.scen.json @@ -35,7 +35,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -72,7 +72,7 @@ "01", "*" ], - "data": "" + "data": [] }, { "address": "sc:forwarder", @@ -83,7 +83,9 @@ "2", "1" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:forwarder", @@ -94,7 +96,14 @@ "01", "address:a_user" ], - "data": "" + "data": [ + "str:DirectCall", + "str:ESDTNFTTransfer", + "str:NFT-000001", + "2", + "01", + "address:a_user" + ] }, { "address": "sc:forwarder", @@ -106,7 +115,9 @@ "2", "1" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -161,7 +172,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_nft_current_nonce.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_nft_current_nonce.scen.json index b74629cd10..e5a2f665c3 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_nft_current_nonce.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_nft_current_nonce.scen.json @@ -33,7 +33,7 @@ "lastNonce": "1" } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, diff --git a/contracts/feature-tests/composability/scenarios/forwarder_nft_decode_complex_attributes.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_nft_decode_complex_attributes.scen.json index 100a9b6060..84fab40b1a 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_nft_decode_complex_attributes.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_nft_decode_complex_attributes.scen.json @@ -35,7 +35,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -117,7 +117,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_nft_transfer_async.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_nft_transfer_async.scen.json index 814be53981..aa18721e89 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_nft_transfer_async.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_nft_transfer_async.scen.json @@ -31,7 +31,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -91,7 +91,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_nft_transfer_exec.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_nft_transfer_exec.scen.json index c75769bc3c..884dbafadc 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_nft_transfer_exec.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_nft_transfer_exec.scen.json @@ -31,7 +31,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -92,7 +92,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_nft_update_attributes.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_nft_update_attributes.scen.json index 2dfcd41267..8db9e3250d 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_nft_update_attributes.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_nft_update_attributes.scen.json @@ -34,7 +34,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -66,7 +66,7 @@ "", "0x808080" ], - "data": "" + "data": [] } ], "gas": "*", @@ -111,7 +111,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -143,7 +143,7 @@ "", "0x909090" ], - "data": "" + "data": [] } ], "gas": "*", @@ -172,7 +172,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "+": "" } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_no_endpoint.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_no_endpoint.scen.json index 0cf6541378..85584ec665 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_no_endpoint.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_no_endpoint.scen.json @@ -6,7 +6,7 @@ "accounts": { "address:a_user": {}, "sc:forwarder": { - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, diff --git a/contracts/feature-tests/composability/scenarios/forwarder_retrieve_funds_with_accept_func.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_retrieve_funds_with_accept_func.scen.json index 76e39bf040..c37a497481 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_retrieve_funds_with_accept_func.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_retrieve_funds_with_accept_func.scen.json @@ -18,12 +18,12 @@ "esdt": { "str:THIRDTOKEN-abcdef": "5,000,000" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -77,7 +77,7 @@ "str:SECTOKEN-abcdef": "2,000,000" }, "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -88,7 +88,7 @@ "storage": { "+": "" }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_send_esdt_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_send_esdt_multi_transfer.scen.json index 88867a91b6..80d7b639e2 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_send_esdt_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_send_esdt_multi_transfer.scen.json @@ -30,7 +30,7 @@ ] } }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -97,7 +97,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -175,7 +175,7 @@ } }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, diff --git a/contracts/feature-tests/composability/scenarios/forwarder_send_twice_egld.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_send_twice_egld.scen.json deleted file mode 100644 index e554b3c4d0..0000000000 --- a/contracts/feature-tests/composability/scenarios/forwarder_send_twice_egld.scen.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "gasSchedule": "v3", - "steps": [ - { - "step": "setState", - "accounts": { - "address:a_user": { - "nonce": "0", - "balance": "0" - }, - "sc:vault": { - "nonce": "0", - "balance": "0", - "code": "file:../vault/output/vault.wasm" - }, - "sc:forwarder": { - "nonce": "0", - "balance": "1000", - "code": "file:../forwarder/output/forwarder.wasm" - } - } - }, - { - "step": "scCall", - "id": "1", - "tx": { - "from": "address:a_user", - "to": "sc:forwarder", - "function": "send_funds_twice", - "arguments": [ - "sc:vault", - "str:EGLD", - "1" - ], - "gasLimit": "100,000,000", - "gasPrice": "0" - }, - "expect": { - "out": [], - "status": "0", - "logs": [ - { - "address": "*", - "endpoint": "str:transferValueOnly", - "topics": [ - "sc:forwarder", - "sc:vault", - "1" - ], - "data": "" - }, - { - "address": "sc:vault", - "endpoint": "str:accept_funds", - "topics": [ - "str:accept_funds", - "1" - ], - "data": "" - }, - { - "address": "*", - "endpoint": "str:transferValueOnly", - "topics": [ - "sc:forwarder", - "sc:vault", - "1" - ], - "data": "" - }, - { - "address": "sc:vault", - "endpoint": "str:accept_funds", - "topics": [ - "str:accept_funds", - "1" - ], - "data": "" - } - ], - "gas": "*", - "refund": "*" - } - }, - { - "step": "checkState", - "accounts": { - "address:a_user": { - "nonce": "*", - "balance": "0", - "storage": {}, - "code": "" - }, - "sc:vault": { - "nonce": "0", - "balance": "2", - "storage": { - "str:call_counts|nested:str:accept_funds": "2" - }, - "code": "file:../vault/output/vault.wasm" - }, - "sc:forwarder": { - "nonce": "0", - "balance": "998", - "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" - } - } - } - ] -} diff --git a/contracts/feature-tests/composability/scenarios/forwarder_send_twice_esdt.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_send_twice_esdt.scen.json deleted file mode 100644 index f3a5f6f53d..0000000000 --- a/contracts/feature-tests/composability/scenarios/forwarder_send_twice_esdt.scen.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "gasSchedule": "v3", - "steps": [ - { - "step": "setState", - "accounts": { - "address:a_user": { - "nonce": "0", - "balance": "0" - }, - "sc:vault": { - "nonce": "0", - "balance": "0", - "code": "file:../vault/output/vault.wasm" - }, - "sc:forwarder": { - "nonce": "0", - "balance": "0", - "esdt": { - "str:FWD-TOKEN": "1000" - }, - "code": "file:../forwarder/output/forwarder.wasm" - } - } - }, - { - "step": "scCall", - "id": "1", - "tx": { - "from": "address:a_user", - "to": "sc:forwarder", - "function": "send_funds_twice", - "arguments": [ - "sc:vault", - "str:FWD-TOKEN", - "1" - ], - "gasLimit": "100,000,000", - "gasPrice": "0" - }, - "expect": { - "out": [], - "status": "0", - "logs": [ - { - "address": "sc:forwarder", - "endpoint": "str:ESDTTransfer", - "topics": [ - "str:FWD-TOKEN", - "", - "1", - "sc:vault" - ], - "data": "" - }, - { - "address": "sc:vault", - "endpoint": "str:accept_funds", - "topics": [ - "str:accept_funds", - "0", - "str:FWD-TOKEN", - "0", - "1" - ], - "data": "" - }, - { - "address": "sc:forwarder", - "endpoint": "str:ESDTTransfer", - "topics": [ - "str:FWD-TOKEN", - "", - "1", - "sc:vault" - ], - "data": "" - }, - { - "address": "sc:vault", - "endpoint": "str:accept_funds", - "topics": [ - "str:accept_funds", - "0", - "str:FWD-TOKEN", - "0", - "1" - ], - "data": "" - } - ], - "gas": "*", - "refund": "*" - } - }, - { - "step": "checkState", - "accounts": { - "address:a_user": { - "nonce": "*", - "balance": "0", - "storage": {}, - "code": "" - }, - "sc:vault": { - "nonce": "0", - "balance": "0", - "esdt": { - "str:FWD-TOKEN": "2" - }, - "storage": { - "str:call_counts|nested:str:accept_funds": "2" - }, - "code": "file:../vault/output/vault.wasm" - }, - "sc:forwarder": { - "nonce": "0", - "balance": "0", - "esdt": { - "str:FWD-TOKEN": "998" - }, - "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" - } - } - } - ] -} diff --git a/contracts/feature-tests/composability/scenarios/forwarder_sync_echo.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_sync_echo.scen.json index 5d92534f8f..e54b5ade94 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_sync_echo.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_sync_echo.scen.json @@ -11,12 +11,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -39,18 +39,34 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_arguments", + "1", + "2" + ] + }, { "address": "sc:forwarder", "endpoint": "str:echo_arguments_sync", "topics": [ "str:echo_arguments_sync_result" ], - "data": { - "0-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] } ], "gas": "*", @@ -76,18 +92,48 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_arguments", + "1", + "2" + ] + }, { "address": "sc:forwarder", "endpoint": "str:echo_arguments_sync_twice", "topics": [ "str:echo_arguments_sync_result" ], - "data": { - "0-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] + }, + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:ExecuteOnDestContext", + "str:echo_arguments", + "1", + "2" + ] }, { "address": "sc:forwarder", @@ -95,12 +141,14 @@ "topics": [ "str:echo_arguments_sync_result" ], - "data": { - "0-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] } ], "gas": "*", diff --git a/contracts/feature-tests/composability/scenarios/forwarder_tranfer_esdt_with_fees.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_tranfer_esdt_with_fees.scen.json index f917eb6932..dab0808f47 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_tranfer_esdt_with_fees.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_tranfer_esdt_with_fees.scen.json @@ -18,12 +18,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -80,7 +80,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -89,7 +89,7 @@ "str:FWD-TOKEN": "10" }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -151,7 +151,7 @@ "storage": { "+": "" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -160,7 +160,7 @@ "str:FWD-TOKEN": "20" }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -222,7 +222,7 @@ "storage": { "+": "" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -231,7 +231,7 @@ "str:FWD-TOKEN": "30" }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } }, @@ -293,7 +293,7 @@ "storage": { "+": "" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -302,7 +302,7 @@ "str:FWD-TOKEN": "40" }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/forwarder_validate_token_identifier.scen.json b/contracts/feature-tests/composability/scenarios/forwarder_validate_token_identifier.scen.json index d9e0db20fd..13c12bd294 100644 --- a/contracts/feature-tests/composability/scenarios/forwarder_validate_token_identifier.scen.json +++ b/contracts/feature-tests/composability/scenarios/forwarder_validate_token_identifier.scen.json @@ -11,7 +11,7 @@ "esdt": { "str:ESDT-123456": "200" }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:viewer": { "nonce": "0", diff --git a/contracts/feature-tests/composability/scenarios-promises/promises_call_async_accept_egld.scen.json b/contracts/feature-tests/composability/scenarios/promises_call_async_accept_egld.scen.json similarity index 76% rename from contracts/feature-tests/composability/scenarios-promises/promises_call_async_accept_egld.scen.json rename to contracts/feature-tests/composability/scenarios/promises_call_async_accept_egld.scen.json index e21dccb71a..6a31fc5068 100644 --- a/contracts/feature-tests/composability/scenarios-promises/promises_call_async_accept_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_call_async_accept_egld.scen.json @@ -10,18 +10,18 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, { "step": "scCall", - "txId": "1", + "id": "1", "tx": { "from": "address:a_user", "to": "sc:forwarder", @@ -38,14 +38,16 @@ "status": "0", "logs": [ { - "address": "sc:vault", + "address": "sc:forwarder", "endpoint": "str:transferValueOnly", "topics": [ - "sc:forwarder", - "sc:vault", - "1000" + "1000", + "sc:vault" ], - "data": "" + "data": [ + "str:AsyncCall", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -54,7 +56,9 @@ "str:accept_funds", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -76,13 +80,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/promises_call_async_accept_esdt.scen.json b/contracts/feature-tests/composability/scenarios/promises_call_async_accept_esdt.scen.json similarity index 80% rename from contracts/feature-tests/composability/scenarios-promises/promises_call_async_accept_esdt.scen.json rename to contracts/feature-tests/composability/scenarios/promises_call_async_accept_esdt.scen.json index 456679520e..c79d953c1d 100644 --- a/contracts/feature-tests/composability/scenarios-promises/promises_call_async_accept_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_call_async_accept_esdt.scen.json @@ -13,18 +13,18 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, { "step": "scCall", - "txId": "1", + "id": "1", "tx": { "from": "address:a_user", "to": "sc:forwarder", @@ -50,11 +50,17 @@ "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:vault" ], - "data": "" + "data": [ + "str:AsyncCall", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -66,7 +72,9 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -94,13 +102,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/promises_call_async_retrieve_egld.scen.json b/contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_egld.scen.json similarity index 61% rename from contracts/feature-tests/composability/scenarios-promises/promises_call_async_retrieve_egld.scen.json rename to contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_egld.scen.json index d5d07ca52c..bb8e199e91 100644 --- a/contracts/feature-tests/composability/scenarios-promises/promises_call_async_retrieve_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_egld.scen.json @@ -10,18 +10,18 @@ "sc:vault": { "nonce": "0", "balance": "1000", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, { "step": "scCall", - "txId": "1", + "id": "1", "tx": { "from": "address:a_user", "to": "sc:forwarder", @@ -39,6 +39,21 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:AsyncCall", + "str:retrieve_funds", + "str:EGLD", + "0", + "1000" + ] + }, { "address": "sc:vault", "endpoint": "str:retrieve_funds", @@ -48,17 +63,34 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:vault", "endpoint": "str:transferValueOnly", "topics": [ - "sc:vault", - "sc:forwarder", - "1000" + "1000", + "sc:forwarder" ], - "data": "" + "data": [ + "str:BackTransfer", + "" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "1000", + "sc:forwarder" + ], + "data": [ + "str:AsyncCallback", + "str:retrieve_funds_callback", + "0x00" + ] }, { "address": "sc:forwarder", @@ -69,7 +101,9 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -89,13 +123,13 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "1000", "storage": "*", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/promises_call_async_retrieve_esdt.scen.json b/contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_esdt.scen.json similarity index 70% rename from contracts/feature-tests/composability/scenarios-promises/promises_call_async_retrieve_esdt.scen.json rename to contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_esdt.scen.json index 6e92b55c02..4efd19b03d 100644 --- a/contracts/feature-tests/composability/scenarios-promises/promises_call_async_retrieve_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_call_async_retrieve_esdt.scen.json @@ -13,18 +13,18 @@ "esdt": { "str:TEST-TOKENA": "1000" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, { "step": "scCall", - "txId": "1", + "id": "1", "tx": { "from": "address:a_user", "to": "sc:forwarder", @@ -42,6 +42,21 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:forwarder", + "endpoint": "str:transferValueOnly", + "topics": [ + "", + "sc:vault" + ], + "data": [ + "str:AsyncCall", + "str:retrieve_funds", + "str:TEST-TOKENA", + "0", + "1000" + ] + }, { "address": "sc:vault", "endpoint": "str:retrieve_funds", @@ -51,18 +66,25 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] }, { "address": "sc:vault", "endpoint": "str:ESDTTransfer", "topics": [ "str:TEST-TOKENA", - "", + "0", "1000", "sc:forwarder" ], - "data": "" + "data": [ + "str:BackTransfer", + "str:ESDTTransfer", + "str:TEST-TOKENA", + "1000" + ] }, { "address": "sc:forwarder", @@ -73,7 +95,9 @@ "0", "1000" ], - "data": "" + "data": [ + "" + ] } ], "gas": "*", @@ -93,7 +117,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:forwarder": { "nonce": "0", @@ -102,7 +126,7 @@ "str:TEST-TOKENA": "1000" }, "storage": "*", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/promises_call_callback_directly.scen.json b/contracts/feature-tests/composability/scenarios/promises_call_callback_directly.scen.json similarity index 89% rename from contracts/feature-tests/composability/scenarios-promises/promises_call_callback_directly.scen.json rename to contracts/feature-tests/composability/scenarios/promises_call_callback_directly.scen.json index a34a78ee53..044af9bc1c 100644 --- a/contracts/feature-tests/composability/scenarios-promises/promises_call_callback_directly.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_call_callback_directly.scen.json @@ -10,13 +10,13 @@ "sc:forwarder": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, { "step": "scCall", - "txId": "1", + "id": "1", "tx": { "from": "address:a_user", "to": "sc:forwarder", diff --git a/contracts/feature-tests/composability/scenarios-promises/promises_multi_transfer.scen.json b/contracts/feature-tests/composability/scenarios/promises_multi_transfer.scen.json similarity index 52% rename from contracts/feature-tests/composability/scenarios-promises/promises_multi_transfer.scen.json rename to contracts/feature-tests/composability/scenarios/promises_multi_transfer.scen.json index 281033d98c..71eaf90e90 100644 --- a/contracts/feature-tests/composability/scenarios-promises/promises_multi_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_multi_transfer.scen.json @@ -29,12 +29,12 @@ ] } }, - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" }, "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" } } }, @@ -77,8 +77,107 @@ ], "status": "0", "message": "", - "gas": "*", - "refund": "*" + "logs": [ + { + "address": "sc:promises", + "endpoint": "str:MultiESDTNFTTransfer", + "topics": [ + "str:FWD-TOKEN", + "0", + "500", + "str:NFT-123456", + "1", + "1", + "str:SFT-456789", + "3", + "6", + "sc:vault" + ], + "data": [ + "str:AsyncCall", + "str:MultiESDTNFTTransfer", + "sc:vault", + "3", + "str:FWD-TOKEN", + "0", + "500", + "str:NFT-123456", + "1", + "1", + "str:SFT-456789", + "3", + "6", + "str:accept_funds_echo_payment" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:accept_funds_echo_payment", + "topics": [ + "str:accept_funds", + "0", + "str:FWD-TOKEN", + "0", + "500", + "str:NFT-123456", + "1", + "1", + "str:SFT-456789", + "3", + "6" + ], + "data": [ + "" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "", + "sc:promises" + ], + "data": [ + "str:AsyncCallback", + "str:the_one_callback", + "0x00", + "0", + "str:FWD-TOKEN", + "0", + "500", + "str:NFT-123456", + "1", + "1", + "str:SFT-456789", + "3", + "6" + ] + }, + { + "address": "sc:promises", + "endpoint": "str:the_one_callback", + "topics": [ + "str:async_call_event_callback", + "2001", + "2002" + ], + "data": [ + [ + "nested:0x00", + "nested:0", + "nested:str:FWD-TOKEN", + "nested:0", + "nested:500", + "nested:str:NFT-123456", + "nested:1", + "nested:1", + "nested:str:SFT-456789", + "nested:3", + "nested:6" + ] + ] + } + ] } }, { @@ -115,7 +214,7 @@ "storage": { "str:call_counts|nested:str:accept_funds_echo_payment": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:promises": { "nonce": "0", @@ -140,7 +239,7 @@ } }, "storage": {}, - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/promises_single_transfer.scen.json b/contracts/feature-tests/composability/scenarios/promises_single_transfer.scen.json similarity index 58% rename from contracts/feature-tests/composability/scenarios-promises/promises_single_transfer.scen.json rename to contracts/feature-tests/composability/scenarios/promises_single_transfer.scen.json index c437759563..d1132485c4 100644 --- a/contracts/feature-tests/composability/scenarios-promises/promises_single_transfer.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_single_transfer.scen.json @@ -10,12 +10,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:promises": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, @@ -56,12 +56,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:promises": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, @@ -75,8 +75,8 @@ "arguments": [ "sc:vault", "str:echo_arguments", - "3,000,000", - "100,000,000", + "10,000,000", + "10,000,000", "1", "2" ], @@ -90,6 +90,35 @@ ], "status": "0", "logs": [ + { + "address": "sc:promises", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:AsyncCall", + "str:echo_arguments", + "1", + "2" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:promises" + ], + "data": [ + "str:AsyncCallback", + "str:the_one_callback", + "0x00", + "1", + "2" + ] + }, { "address": "sc:promises", "endpoint": "str:the_one_callback", @@ -98,11 +127,13 @@ "1001", "1002" ], - "data": { - "0-status": "nested:0x00", - "1-arg1": "biguint:1", - "2-arg2": "biguint:2" - } + "data": [ + { + "0-status": "nested:0x00", + "1-arg1": "biguint:1", + "2-arg2": "biguint:2" + } + ] }, "+" ], @@ -120,12 +151,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:promises": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, @@ -154,6 +185,35 @@ ], "status": "0", "logs": [ + { + "address": "sc:promises", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:vault" + ], + "data": [ + "str:AsyncCall", + "str:echo_arguments", + "1", + "2" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:promises" + ], + "data": [ + "str:AsyncCallback", + "str:the_one_callback", + "0x00", + "1", + "2" + ] + }, { "address": "sc:promises", "endpoint": "str:the_one_callback", @@ -162,13 +222,15 @@ "1001", "1002" ], - "data": { - "0-status": "nested:0x00", - "1-echoed-args": [ - "biguint:1", - "biguint:2" - ] - } + "data": [ + { + "0-status": "nested:0x00", + "1-echoed-args": [ + "biguint:1", + "biguint:2" + ] + } + ] } ], "gas": "*", @@ -185,13 +247,13 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:promises": { "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/promises_single_transfer_gas1.scen.json b/contracts/feature-tests/composability/scenarios/promises_single_transfer_gas1.scen.json similarity index 83% rename from contracts/feature-tests/composability/scenarios-promises/promises_single_transfer_gas1.scen.json rename to contracts/feature-tests/composability/scenarios/promises_single_transfer_gas1.scen.json index c7f2bcf720..b58feecc8d 100644 --- a/contracts/feature-tests/composability/scenarios-promises/promises_single_transfer_gas1.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_single_transfer_gas1.scen.json @@ -10,18 +10,18 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:promises": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, { "step": "scCall", - "txId": "1", + "id": "1", "tx": { "from": "address:a_user", "to": "sc:promises", @@ -56,12 +56,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:promises": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios-promises/promises_single_transfer_gas2.scen.json b/contracts/feature-tests/composability/scenarios/promises_single_transfer_gas2.scen.json similarity index 62% rename from contracts/feature-tests/composability/scenarios-promises/promises_single_transfer_gas2.scen.json rename to contracts/feature-tests/composability/scenarios/promises_single_transfer_gas2.scen.json index 4286273b35..ec683086a7 100644 --- a/contracts/feature-tests/composability/scenarios-promises/promises_single_transfer_gas2.scen.json +++ b/contracts/feature-tests/composability/scenarios/promises_single_transfer_gas2.scen.json @@ -10,18 +10,18 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:promises": { "nonce": "0", "balance": "0", - "code": "file:../promises-features/output/promises-features.wasm" + "code": "mxsc:../promises-features/output/promises-features.mxsc.json" } } }, { "step": "scCall", - "txId": "2", + "id": "2", "tx": { "from": "address:a_user", "to": "sc:promises", @@ -41,6 +41,20 @@ "out": [], "status": "0", "logs": [ + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:promises" + ], + "data": [ + "str:AsyncCallback", + "str:the_one_callback", + "0x05", + "str:not enough gas" + ] + }, { "address": "sc:promises", "endpoint": "str:the_one_callback", @@ -49,10 +63,12 @@ "1001", "1002" ], - "data": { - "0-status": "biguint:5", - "1-message": "nested:str:not enough gas" - } + "data": [ + { + "0-status": "biguint:5", + "1-message": "nested:str:not enough gas" + } + ] }, "+" ], diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_init.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_init.scen.json index 5966acb95b..aa7d48b42b 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_init.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_init.scen.json @@ -11,7 +11,7 @@ "sc:proxy-first": { "nonce": "0", "balance": "0", - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" } }, "newAddresses": [ @@ -31,7 +31,7 @@ "egldValue": "100", "function": "deploySecondContract", "arguments": [ - "file:../proxy-test-second/output/proxy-test-second.wasm" + "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" ], "gasLimit": "1,000,000,000,000", "gasPrice": "0" @@ -61,7 +61,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", @@ -70,7 +70,7 @@ "str:init_arg": "123", "str:last_payment": "100" }, - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_message_otherShard.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_message_otherShard.scen.json index 474ca43c6f..6add2dcd48 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_message_otherShard.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_message_otherShard.scen.json @@ -15,7 +15,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" } } }, @@ -53,7 +53,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_message_otherShard_callback.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_message_otherShard_callback.scen.json index d89aba6317..ba55671d03 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_message_otherShard_callback.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_message_otherShard_callback.scen.json @@ -15,7 +15,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" } } }, @@ -53,7 +53,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_message_sameShard.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_message_sameShard.scen.json index 41c97ebf4a..be8d248968 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_message_sameShard.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_message_sameShard.scen.json @@ -15,12 +15,12 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", "balance": "0", - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } }, @@ -58,7 +58,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", @@ -69,7 +69,7 @@ "str:message_me_3": "0x030303", "str:message_me_4": "0xfefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefe" }, - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_message_sameShard_callback.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_message_sameShard_callback.scen.json index 360458083d..3a3b6df137 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_message_sameShard_callback.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_message_sameShard_callback.scen.json @@ -15,12 +15,12 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", "balance": "0", - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } }, @@ -59,7 +59,7 @@ "str:other_contract": "sc:proxy-second", "str:callback_info": "0x5555" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", @@ -70,7 +70,7 @@ "str:message_me_3": "0x030303", "str:message_me_4": "0xfefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefe" }, - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_payment_otherShard.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_payment_otherShard.scen.json index da3a5771ec..1d70c4b0a8 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_payment_otherShard.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_payment_otherShard.scen.json @@ -15,7 +15,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" } } }, @@ -54,7 +54,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_payment_otherShard_callback.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_payment_otherShard_callback.scen.json index 6aed1f8306..7dc0e1031b 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_payment_otherShard_callback.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_payment_otherShard_callback.scen.json @@ -15,7 +15,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" } } }, @@ -55,7 +55,7 @@ "str:other_contract": "sc:proxy-second", "str:CB_CLOSURE|str:1...............................": "nested:str:payCallback|nested:" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_payment_sameShard.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_payment_sameShard.scen.json index cf34f89a42..15a78e78c3 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_payment_sameShard.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_payment_sameShard.scen.json @@ -15,12 +15,12 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", "balance": "0", - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } }, @@ -59,7 +59,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", @@ -68,7 +68,7 @@ "str:pay_me_arg": "0x56", "str:last_payment": "0x123400" }, - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_payment_sameShard_callback.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_payment_sameShard_callback.scen.json index 570e3ac015..1d58a786e0 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_payment_sameShard_callback.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_payment_sameShard_callback.scen.json @@ -15,12 +15,12 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", "balance": "0", - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:other_contract": "sc:proxy-second", "str:callback_info": "0x7777" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", @@ -71,7 +71,7 @@ "str:pay_me_arg": "0x56", "str:last_payment": "0x123400" }, - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/proxy_test_upgrade.scen.json b/contracts/feature-tests/composability/scenarios/proxy_test_upgrade.scen.json index 5c694b1a78..f91f2c60d8 100644 --- a/contracts/feature-tests/composability/scenarios/proxy_test_upgrade.scen.json +++ b/contracts/feature-tests/composability/scenarios/proxy_test_upgrade.scen.json @@ -23,7 +23,7 @@ "egldValue": "200", "function": "upgradeSecondContract", "arguments": [ - "file:../proxy-test-second/output/proxy-test-second.wasm" + "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" ], "gasLimit": "1,000,000,000,000", "gasPrice": "0" @@ -53,7 +53,7 @@ "storage": { "str:other_contract": "sc:proxy-second" }, - "code": "file:../proxy-test-first/output/proxy-test-first.wasm" + "code": "mxsc:../proxy-test-first/output/proxy-test-first.mxsc.json" }, "sc:proxy-second": { "nonce": "0", @@ -62,7 +62,7 @@ "str:init_arg": "456", "str:last_payment": "200" }, - "code": "file:../proxy-test-second/output/proxy-test-second.wasm" + "code": "mxsc:../proxy-test-second/output/proxy-test-second.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/recursive_caller_egld_1.scen.json b/contracts/feature-tests/composability/scenarios/recursive_caller_egld_1.scen.json index b6c9073b40..418ee1162b 100644 --- a/contracts/feature-tests/composability/scenarios/recursive_caller_egld_1.scen.json +++ b/contracts/feature-tests/composability/scenarios/recursive_caller_egld_1.scen.json @@ -12,12 +12,12 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", "balance": "1000", - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } }, @@ -50,17 +50,21 @@ "str:EGLD", "1" ], - "data": "1" + "data": [ + "1" + ] }, { - "address": "*", + "address": "sc:recursive-caller", "endpoint": "str:transferValueOnly", "topics": [ - "sc:recursive-caller", - "sc:vault", - "1" + "1", + "sc:vault" ], - "data": "" + "data": [ + "str:AsyncCall", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -69,7 +73,22 @@ "str:accept_funds", "1" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:recursive-caller" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] }, { "address": "sc:recursive-caller", @@ -80,7 +99,9 @@ "str:EGLD", "1" ], - "data": "1" + "data": [ + "1" + ] } ], "gas": "*", @@ -102,13 +123,13 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", "balance": "999", "storage": {}, - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/recursive_caller_esdt_1.scen.json b/contracts/feature-tests/composability/scenarios/recursive_caller_esdt_1.scen.json index d23216b46e..0e4abad4a4 100644 --- a/contracts/feature-tests/composability/scenarios/recursive_caller_esdt_1.scen.json +++ b/contracts/feature-tests/composability/scenarios/recursive_caller_esdt_1.scen.json @@ -12,7 +12,7 @@ "sc:vault": { "nonce": "0", "balance": "0", - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", @@ -20,7 +20,7 @@ "esdt": { "str:REC-TOKEN": "1000" }, - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } }, @@ -53,7 +53,9 @@ "str:REC-TOKEN", "1" ], - "data": "1" + "data": [ + "1" + ] }, { "address": "sc:recursive-caller", @@ -64,7 +66,13 @@ "1", "sc:vault" ], - "data": "" + "data": [ + "str:AsyncCall", + "str:ESDTTransfer", + "str:REC-TOKEN", + "1", + "str:accept_funds" + ] }, { "address": "sc:vault", @@ -76,7 +84,22 @@ "0", "1" ], - "data": "" + "data": [ + "" + ] + }, + { + "address": "sc:vault", + "endpoint": "str:transferValueOnly", + "topics": [ + "0", + "sc:recursive-caller" + ], + "data": [ + "str:AsyncCallback", + "str:callBack", + "0x00" + ] }, { "address": "sc:recursive-caller", @@ -87,7 +110,9 @@ "str:REC-TOKEN", "1" ], - "data": "1" + "data": [ + "1" + ] } ], "gas": "*", @@ -112,7 +137,7 @@ "storage": { "str:call_counts|nested:str:accept_funds": "1" }, - "code": "file:../vault/output/vault.wasm" + "code": "mxsc:../vault/output/vault.mxsc.json" }, "sc:recursive-caller": { "nonce": "0", @@ -121,7 +146,7 @@ "str:REC-TOKEN": "999" }, "storage": {}, - "code": "file:../recursive-caller/output/recursive-caller.wasm" + "code": "mxsc:../recursive-caller/output/recursive-caller.mxsc.json" } } } diff --git a/contracts/feature-tests/composability/scenarios/send_egld.scen.json b/contracts/feature-tests/composability/scenarios/send_egld.scen.json index 1aa2ef485b..8efba53a4a 100644 --- a/contracts/feature-tests/composability/scenarios/send_egld.scen.json +++ b/contracts/feature-tests/composability/scenarios/send_egld.scen.json @@ -8,7 +8,7 @@ "sc:basic-features": { "nonce": "1000", "balance": "200", - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -64,7 +64,7 @@ "nonce": "1000", "balance": "0", "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/composability/scenarios/send_esdt.scen.json b/contracts/feature-tests/composability/scenarios/send_esdt.scen.json index 09b6573a82..df988216c0 100644 --- a/contracts/feature-tests/composability/scenarios/send_esdt.scen.json +++ b/contracts/feature-tests/composability/scenarios/send_esdt.scen.json @@ -5,13 +5,13 @@ { "step": "setState", "accounts": { - "sc:basic-features": { + "sc:forwarder": { "nonce": "1000", "balance": "0", "esdt": { "str:SENDESDT": "1,000" }, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -24,7 +24,7 @@ "id": "not-enough", "tx": { "from": "address:an_account", - "to": "sc:basic-features", + "to": "sc:forwarder", "function": "send_esdt", "arguments": [ "address:an_account", @@ -46,7 +46,7 @@ "id": "send_esdt-ok", "tx": { "from": "address:an_account", - "to": "sc:basic-features", + "to": "sc:forwarder", "function": "send_esdt", "arguments": [ "address:an_account", @@ -61,15 +61,20 @@ "status": "", "logs": [ { - "address": "sc:basic-features", + "address": "sc:forwarder", "endpoint": "str:ESDTTransfer", "topics": [ "str:SENDESDT", - "", + "0", "200", "address:an_account" ], - "data": "" + "data": [ + "str:DirectCall", + "str:ESDTTransfer", + "str:SENDESDT", + "200" + ] } ] } @@ -77,14 +82,14 @@ { "step": "checkState", "accounts": { - "sc:basic-features": { + "sc:forwarder": { "nonce": "1000", "balance": "0", "esdt": { "str:SENDESDT": "800" }, "storage": {}, - "code": "file:../forwarder/output/forwarder.wasm" + "code": "mxsc:../forwarder/output/forwarder.mxsc.json" }, "address:an_account": { "nonce": "*", diff --git a/contracts/feature-tests/composability/tests/composability_scenario_go_test.rs b/contracts/feature-tests/composability/tests/composability_scenario_go_test.rs index d6b5acbf3f..8f61befdbe 100644 --- a/contracts/feature-tests/composability/tests/composability_scenario_go_test.rs +++ b/contracts/feature-tests/composability/tests/composability_scenario_go_test.rs @@ -4,20 +4,7 @@ fn world() -> ScenarioWorld { ScenarioWorld::vm_go() } -#[ignore = "currently compatible with VM 1.5, not with VM 1.4"] #[test] -fn promises_multi_transfer_go() { - world().run("scenarios-promises/promises_multi_transfer.scen.json"); -} - -#[ignore = "currently compatible with VM 1.5, not with VM 1.4"] -#[test] -fn promises_single_transfer_go() { - world().run("scenarios-promises/promises_single_transfer.scen.json"); -} - -#[test] -#[ignore = "waiting for VM 1.5"] fn builtin_func_delete_user_name_go() { world().run("scenarios/builtin_func_delete_user_name.scen.json"); } @@ -48,7 +35,6 @@ fn forw_raw_async_echo_go() { } #[test] -#[ignore = "currently compatible with VM 1.5, not with VM 1.4"] fn forw_raw_async_send_and_retrieve_multi_transfer_funds_go() { world().run("scenarios/forw_raw_async_send_and_retrieve_multi_transfer_funds.scen.json"); } @@ -64,7 +50,6 @@ fn forw_raw_builtin_nft_local_mint_via_sync_call_go() { } #[test] -#[ignore = "currently compatible with VM 1.5, not with VM 1.4"] fn forw_raw_call_async_retrieve_multi_transfer_go() { world().run("scenarios/forw_raw_call_async_retrieve_multi_transfer.scen.json"); } @@ -100,7 +85,6 @@ fn forw_raw_direct_multi_esdt_go() { } #[test] -#[ignore = "currently compatible with VM 1.5, not with VM 1.4"] fn forw_raw_init_async_go() { world().run("scenarios/forw_raw_init_async.scen.json"); } @@ -206,7 +190,6 @@ fn forwarder_call_async_retrieve_egld_go() { } #[test] -#[ignore = "currently compatible with VM 1.5, not with VM 1.4"] fn forwarder_call_async_retrieve_esdt_go() { world().run("scenarios/forwarder_call_async_retrieve_esdt.scen.json"); } @@ -256,16 +239,31 @@ fn forwarder_call_sync_retrieve_egld_go() { world().run("scenarios/forwarder_call_sync_retrieve_egld.scen.json"); } +#[test] +fn forwarder_call_sync_retrieve_egld_bt_go() { + world().run("scenarios/forwarder_call_sync_retrieve_egld_bt.scen.json"); +} + #[test] fn forwarder_call_sync_retrieve_esdt_go() { world().run("scenarios/forwarder_call_sync_retrieve_esdt.scen.json"); } +#[test] +fn forwarder_call_sync_retrieve_esdt_bt_go() { + world().run("scenarios/forwarder_call_sync_retrieve_esdt_bt.scen.json"); +} + #[test] fn forwarder_call_sync_retrieve_nft_go() { world().run("scenarios/forwarder_call_sync_retrieve_nft.scen.json"); } +#[test] +fn forwarder_call_sync_retrieve_nft_bt_go() { + world().run("scenarios/forwarder_call_sync_retrieve_nft_bt.scen.json"); +} + #[test] fn forwarder_call_transf_exec_accept_egld_go() { world().run("scenarios/forwarder_call_transf_exec_accept_egld.scen.json"); @@ -396,16 +394,6 @@ fn forwarder_send_esdt_multi_transfer_go() { world().run("scenarios/forwarder_send_esdt_multi_transfer.scen.json"); } -#[test] -fn forwarder_send_twice_egld_go() { - world().run("scenarios/forwarder_send_twice_egld.scen.json"); -} - -#[test] -fn forwarder_send_twice_esdt_go() { - world().run("scenarios/forwarder_send_twice_esdt.scen.json"); -} - #[test] fn forwarder_sync_echo_go() { world().run("scenarios/forwarder_sync_echo.scen.json"); @@ -421,6 +409,57 @@ fn forwarder_validate_token_identifier_go() { world().run("scenarios/forwarder_validate_token_identifier.scen.json"); } +#[test] +fn promises_call_async_accept_egld_go() { + world().run("scenarios/promises_call_async_accept_egld.scen.json"); +} + +#[test] +fn promises_call_async_accept_esdt_go() { + world().run("scenarios/promises_call_async_accept_esdt.scen.json"); +} + +#[test] +#[ignore = "TODO"] +fn promises_call_async_retrieve_egld_go() { + world().run("scenarios/promises_call_async_retrieve_egld.scen.json"); +} + +#[test] +#[ignore = "TODO"] +fn promises_call_async_retrieve_esdt_go() { + world().run("scenarios/promises_call_async_retrieve_esdt.scen.json"); +} + +#[test] +#[ignore = "TODO"] +fn promises_call_callback_directly_go() { + world().run("scenarios/promises_call_callback_directly.scen.json"); +} + +#[test] +#[ignore = "TODO"] +fn promises_multi_transfer_go() { + world().run("scenarios/promises_multi_transfer.scen.json"); +} + +#[test] +fn promises_single_transfer_go() { + world().run("scenarios/promises_single_transfer.scen.json"); +} + +#[test] +#[ignore = "gas"] +fn promises_single_transfer_gas_1_go() { + world().run("scenarios/promises_single_transfer_gas1.scen.json"); +} + +#[test] +#[ignore = "gas"] +fn promises_single_transfer_gas_2_go() { + world().run("scenarios/promises_single_transfer_gas2.scen.json"); +} + #[test] fn proxy_test_init_go() { world().run("scenarios/proxy_test_init.scen.json"); 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 463f336470..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,54 +2,53 @@ 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( - "file:builtin-func-features/output/builtin-func-features.wasm", + "mxsc:builtin-func-features/output/builtin-func-features.mxsc.json", builtin_func_features::ContractBuilder, ); blockchain.register_contract( - "file:forwarder-queue/output/forwarder-queue.wasm", + "mxsc:forwarder-queue/output/forwarder-queue.mxsc.json", forwarder_queue::ContractBuilder, ); blockchain.register_contract( - "file:forwarder/output/forwarder.wasm", + "mxsc:forwarder/output/forwarder.mxsc.json", forwarder::ContractBuilder, ); blockchain.register_contract( - "file:forwarder-raw/output/forwarder-raw.wasm", + "mxsc:forwarder-raw/output/forwarder-raw.mxsc.json", forwarder_raw::ContractBuilder, ); blockchain.register_contract( - "file:promises-features/output/promises-features.wasm", + "mxsc:promises-features/output/promises-features.mxsc.json", promises_features::ContractBuilder, ); blockchain.register_contract( - "file:proxy-test-first/output/proxy-test-first.wasm", + "mxsc:proxy-test-first/output/proxy-test-first.mxsc.json", proxy_test_first::ContractBuilder, ); blockchain.register_contract( - "file:proxy-test-second/output/proxy-test-second.wasm", + "mxsc:proxy-test-second/output/proxy-test-second.mxsc.json", proxy_test_second::ContractBuilder, ); blockchain.register_contract( - "file:recursive-caller/output/recursive-caller.wasm", + "mxsc:recursive-caller/output/recursive-caller.mxsc.json", recursive_caller::ContractBuilder, ); - blockchain.register_contract("file:vault/output/vault.wasm", vault::ContractBuilder); - blockchain -} - -#[test] -#[ignore = "not yet supported"] -fn promises_multi_transfer_rs() { - world().run("scenarios-promises/promises_multi_transfer.scen.json"); -} -#[test] -#[ignore = "not yet supported"] -fn promises_single_transfer_rs() { - world().run("scenarios-promises/promises_single_transfer.scen.json"); + let vault_sc_config = + meta::multi_contract_config::(&blockchain.current_dir().join("vault")); + blockchain.register_contract_variant( + "mxsc:vault/output/vault.mxsc.json", + vault::ContractBuilder, + vault_sc_config.find_contract("vault"), + ); + blockchain.register_contract_variant( + "mxsc:vault/output/vault-upgrade.mxsc.json", + vault::ContractBuilder, + vault_sc_config.find_contract("vault-upgrade"), + ); + blockchain } #[test] @@ -293,16 +292,31 @@ fn forwarder_call_sync_retrieve_egld_rs() { world().run("scenarios/forwarder_call_sync_retrieve_egld.scen.json"); } +#[test] +fn forwarder_call_sync_retrieve_egld_bt_rs() { + world().run("scenarios/forwarder_call_sync_retrieve_egld_bt.scen.json"); +} + #[test] fn forwarder_call_sync_retrieve_esdt_rs() { world().run("scenarios/forwarder_call_sync_retrieve_esdt.scen.json"); } +#[test] +fn forwarder_call_sync_retrieve_esdt_bt_rs() { + world().run("scenarios/forwarder_call_sync_retrieve_esdt_bt.scen.json"); +} + #[test] fn forwarder_call_sync_retrieve_nft_rs() { world().run("scenarios/forwarder_call_sync_retrieve_nft.scen.json"); } +#[test] +fn forwarder_call_sync_retrieve_nft_bt_rs() { + world().run("scenarios/forwarder_call_sync_retrieve_nft_bt.scen.json"); +} + #[test] fn forwarder_call_transf_exec_accept_egld_rs() { world().run("scenarios/forwarder_call_transf_exec_accept_egld.scen.json"); @@ -433,18 +447,6 @@ fn forwarder_send_esdt_multi_transfer_rs() { world().run("scenarios/forwarder_send_esdt_multi_transfer.scen.json"); } -#[test] -#[ignore] -fn forwarder_send_twice_egld_rs() { - world().run("scenarios/forwarder_send_twice_egld.scen.json"); -} - -#[test] -#[ignore] -fn forwarder_send_twice_esdt_rs() { - world().run("scenarios/forwarder_send_twice_esdt.scen.json"); -} - #[test] fn forwarder_sync_echo_rs() { world().run("scenarios/forwarder_sync_echo.scen.json"); @@ -460,6 +462,54 @@ fn forwarder_validate_token_identifier_rs() { world().run("scenarios/forwarder_validate_token_identifier.scen.json"); } +#[test] +fn promises_call_async_accept_egld_rs() { + world().run("scenarios/promises_call_async_accept_egld.scen.json"); +} + +#[test] +fn promises_call_async_accept_esdt_rs() { + world().run("scenarios/promises_call_async_accept_esdt.scen.json"); +} + +#[test] +fn promises_call_async_retrieve_egld_rs() { + world().run("scenarios/promises_call_async_retrieve_egld.scen.json"); +} + +#[test] +fn promises_call_async_retrieve_esdt_rs() { + world().run("scenarios/promises_call_async_retrieve_esdt.scen.json"); +} + +#[test] +fn promises_call_callback_directly_rs() { + world().run("scenarios/promises_call_callback_directly.scen.json"); +} + +#[test] +fn promises_multi_transfer_rs() { + world().run("scenarios/promises_multi_transfer.scen.json"); +} + +#[test] +#[ignore = "gas"] +fn promises_single_transfer_rs() { + world().run("scenarios/promises_single_transfer.scen.json"); +} + +#[test] +#[ignore = "gas"] +fn promises_single_transfer_gas_1_rs() { + world().run("scenarios/promises_single_transfer_gas1.scen.json"); +} + +#[test] +#[ignore = "gas"] +fn promises_single_transfer_gas_2_rs() { + world().run("scenarios/promises_single_transfer_gas2.scen.json"); +} + #[test] fn proxy_test_init_rs() { world().run("scenarios/proxy_test_init.scen.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 d74be9fbb5..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 = "file:output/forwarder.wasm"; +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..424c1508a4 --- /dev/null +++ b/contracts/feature-tests/composability/tests/forwarder_whitebox_legacy_test.rs @@ -0,0 +1,79 @@ +use forwarder_legacy::fwd_nft_legacy::{Color, ForwarderNftModule}; + +use multiversx_sc_scenario::imports::*; + +const USER_ADDRESS: TestAddress = TestAddress::new("user"); +const FORWARDER_ADDRESS: TestSCAddress = TestSCAddress::new("forwarder_legacy"); +const FORWARDER_PATH: MxscPath = MxscPath::new("output/forwarder_legacy.mxsc.json"); +const NFT_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("COOL-123456"); + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(FORWARDER_PATH, forwarder_legacy::ContractBuilder); + blockchain +} + +#[test] +fn test_nft_update_attributes_and_send() { + 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); + + let original_attributes = Color { r: 0, g: 0, b: 0 }; + + world + .tx() + .from(USER_ADDRESS) + .to(FORWARDER_ADDRESS) + .whitebox(forwarder_legacy::contract_obj, |sc| { + sc.nft_create_compact( + NFT_TOKEN_ID.to_token_identifier(), + managed_biguint!(1), + original_attributes, + ); + + sc.tx() + .to(USER_ADDRESS) + .esdt((NFT_TOKEN_ID.to_token_identifier(), 1, 1u32.into())) + .transfer(); + }); + + world + .check_account(USER_ADDRESS) + .esdt_nft_balance_and_attributes(NFT_TOKEN_ID, 1, 1, original_attributes); + + let new_attributes = Color { + r: 255, + g: 255, + b: 255, + }; + + world + .tx() + .from(USER_ADDRESS) + .to(FORWARDER_ADDRESS) + .payment(TestEsdtTransfer(NFT_TOKEN_ID, 1, 1)) + .whitebox(forwarder_legacy::contract_obj, |sc| { + sc.nft_update_attributes(NFT_TOKEN_ID.to_token_identifier(), 1, new_attributes); + + sc.tx() + .to(USER_ADDRESS) + .esdt((NFT_TOKEN_ID.to_token_identifier(), 1, 1u32.into())) + .transfer(); + }); + + 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_test.rs b/contracts/feature-tests/composability/tests/forwarder_whitebox_test.rs new file mode 100644 index 0000000000..c6f2b54a78 --- /dev/null +++ b/contracts/feature-tests/composability/tests/forwarder_whitebox_test.rs @@ -0,0 +1,78 @@ +use forwarder::fwd_nft::{Color, ForwarderNftModule}; +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"); + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(FORWARDER_PATH, forwarder::ContractBuilder); + blockchain +} + +#[test] +fn test_nft_update_attributes_and_send() { + 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); + + let original_attributes = Color { r: 0, g: 0, b: 0 }; + + world + .tx() + .from(USER_ADDRESS) + .to(FORWARDER_ADDRESS) + .whitebox(forwarder::contract_obj, |sc| { + sc.nft_create_compact( + NFT_TOKEN_ID.to_token_identifier(), + managed_biguint!(1), + original_attributes, + ); + + sc.tx() + .to(USER_ADDRESS) + .esdt((NFT_TOKEN_ID.to_token_identifier(), 1, 1u32.into())) + .transfer(); + }); + + world + .check_account(USER_ADDRESS) + .esdt_nft_balance_and_attributes(NFT_TOKEN_ID, 1, 1, original_attributes); + + let new_attributes = Color { + r: 255, + g: 255, + b: 255, + }; + + world + .tx() + .from(USER_ADDRESS) + .to(FORWARDER_ADDRESS) + .payment(TestEsdtTransfer(NFT_TOKEN_ID, 1, 1)) + .whitebox(forwarder::contract_obj, |sc| { + sc.nft_update_attributes(NFT_TOKEN_ID.to_token_identifier(), 1, new_attributes); + + sc.tx() + .to(USER_ADDRESS) + .esdt((NFT_TOKEN_ID.to_token_identifier(), 1, 1u32.into())) + .transfer(); + }); + + 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/promises_feature_blackbox_test.rs b/contracts/feature-tests/composability/tests/promises_feature_blackbox_test.rs new file mode 100644 index 0000000000..2eb20508f8 --- /dev/null +++ b/contracts/feature-tests/composability/tests/promises_feature_blackbox_test.rs @@ -0,0 +1,128 @@ +use multiversx_sc::types::BigUint; +use multiversx_sc_scenario::imports::*; + +use promises_features::promises_feature_proxy; + +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.register_contract(PROMISES_FEATURES_PATH, promises_features::ContractBuilder); + blockchain.register_contract(VAULT_PATH, vault::ContractBuilder); + + blockchain +} + +struct PromisesFeaturesTestState { + world: ScenarioWorld, +} + +impl PromisesFeaturesTestState { + fn new() -> Self { + let mut world = world(); + + 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 } + } +} + +#[test] +fn test_back_transfers() { + let mut state = PromisesFeaturesTestState::new(); + let token_amount = BigUint::from(1000u64); + + 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_account(PROMISES_FEATURE_ADDRESS) + .esdt_balance(TOKEN_ID_EXPR, token_amount); +} + +#[test] +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; + + state + .world + .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); +} + +#[test] +fn test_back_transfers_logs() { + let mut state = PromisesFeaturesTestState::new(); + let token_amount = BigUint::from(1000u64); + + let logs = 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) + .returns(ReturnsLogs) + .run(); + + assert!(!logs.is_empty() && !logs[0].topics.is_empty()); + assert_eq!(logs[0].address, PROMISES_FEATURE_ADDRESS); + assert_eq!(logs[0].endpoint, "transferValueOnly"); +} + +#[test] +fn test_multi_call_back_transfers_logs() { + let mut state = PromisesFeaturesTestState::new(); + let token_amount = BigUint::from(1000u64); + let half_token_amount = token_amount.clone() / 2u64; + + let logs = state + .world + .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) + .returns(ReturnsLogs) + .run(); + + assert!(!logs.is_empty() && !logs[0].topics.is_empty()); + assert_eq!(logs[0].address, PROMISES_FEATURE_ADDRESS); + assert_eq!(logs[0].endpoint, "transferValueOnly"); +} diff --git a/contracts/feature-tests/composability/transfer-role-features/Cargo.toml b/contracts/feature-tests/composability/transfer-role-features/Cargo.toml index aae84869e0..963ee4ba0f 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dependencies.multiversx-sc-modules] -version = "0.44.0" +version = "0.53.0" path = "../../../../contracts/modules" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 44fe4262cb..21672e577a 100644 --- a/contracts/feature-tests/composability/transfer-role-features/meta/Cargo.toml +++ b/contracts/feature-tests/composability/transfer-role-features/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.transfer-role-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 89f267c287..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 = "file:output/transfer-role-features.wasm"; -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 = "file:../vault/output/vault.wasm"; - -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 3412e66b6b..5ed03c38bc 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,34 +1,23 @@ -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; +use vault::Vault; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const USER_ADDRESS_EXPR: &str = "address:user"; +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const USER_ADDRESS: TestAddress = TestAddress::new("user"); -const TRANSFER_ROLE_FEATURES_ADDRESS_EXPR: &str = "sc:transfer-role-features"; -const TRANSFER_ROLE_FEATURES_PATH_EXPR: &str = "file:output/transfer-role-features.wasm"; +const TRANSFER_ROLE_FEATURES_ADDRESS: TestSCAddress = TestSCAddress::new("transfer-role-features"); +const TRANSFER_ROLE_FEATURES_PATH_EXPR: MxscPath = + MxscPath::new("mxsc:output/transfer-role-features.mxsc.json"); -const TRANSFER_TOKEN_ID_EXPR: &str = "str:TRANSFER-123456"; -const TRANSFER_TOKEN_ID: &[u8] = b"TRANSFER-123456"; +const TRANSFER_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("TRANSFER-123456"); +const TRANSFER_TOKEN_ID_EXPR: &[u8] = b"TRANSFER-123456"; const ACCEPT_FUNDS_FUNC_NAME: &[u8] = b"accept_funds"; 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, @@ -40,175 +29,145 @@ fn world() -> ScenarioWorld { fn test_transfer_role() { 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, TRANSFER_ROLE_FEATURES_ADDRESS_EXPR) - .put_account( - USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(TRANSFER_TOKEN_ID_EXPR, 1_000u64), - ), - ); + world.account(OWNER_ADDRESS).nonce(1); + world + .account(USER_ADDRESS) + .nonce(1) + .esdt_balance(TRANSFER_TOKEN_ID, BigUint::from(1_000u64)); // vault - let vault_code = world.code_expression(VAULT_PATH_EXPR); - - const VAULT_ADDRESS_EXPR: &str = "sc:vault"; - const VAULT_PATH_EXPR: &str = "file:../vault/output/vault.wasm"; + const VAULT_ADDRESS: TestSCAddress = TestSCAddress::new("vault"); + const VAULT_PATH_EXPR: MxscPath = MxscPath::new("mxsc:../vault/output/vault.mxsc.json"); world.register_contract(VAULT_PATH_EXPR, vault::ContractBuilder); - world.set_state_step( - SetStateStep::new() - .put_account(VAULT_ADDRESS_EXPR, Account::new().nonce(1).code(vault_code)), - ); - - let transfer_role_features_whitebox = WhiteboxContract::new( - TRANSFER_ROLE_FEATURES_ADDRESS_EXPR, - transfer_role_features::contract_obj, - ); - let transfer_role_features_code = world.code_expression(TRANSFER_ROLE_FEATURES_PATH_EXPR); + world + .tx() + .from(OWNER_ADDRESS) + .raw_deploy() + .new_address(VAULT_ADDRESS) + .code(VAULT_PATH_EXPR) + .whitebox(vault::contract_obj, |sc| { + let _ = sc.init(OptionalValue::None); + }); // init - world.whitebox_deploy( - &transfer_role_features_whitebox, - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(transfer_role_features_code), - |sc| { + world + .tx() + .from(OWNER_ADDRESS) + .raw_deploy() + .new_address(TRANSFER_ROLE_FEATURES_ADDRESS) + .code(TRANSFER_ROLE_FEATURES_PATH_EXPR) + .whitebox(transfer_role_features::contract_obj, |sc| { let mut whitelist = MultiValueEncoded::new(); - whitelist.push(managed_address!(&address_expr_to_address( - OWNER_ADDRESS_EXPR - ))); - whitelist.push(managed_address!(&address_expr_to_address( - VAULT_ADDRESS_EXPR - ))); + whitelist.push(OWNER_ADDRESS.to_managed_address()); + whitelist.push(VAULT_ADDRESS.to_managed_address()); sc.init(whitelist); - }, - ); + }); // transfer to user - ok - world.whitebox_call( - &transfer_role_features_whitebox, - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .esdt_transfer(TRANSFER_TOKEN_ID, 0, "100"), - |sc| { + world + .tx() + .from(USER_ADDRESS) + .to(TRANSFER_ROLE_FEATURES_ADDRESS) + .payment(TestEsdtTransfer(TRANSFER_TOKEN_ID, 0, 100)) + .whitebox(transfer_role_features::contract_obj, |sc| { let payments = ManagedVec::from_single_item(EsdtTokenPayment::new( - managed_token_id!(TRANSFER_TOKEN_ID), + managed_token_id!(TRANSFER_TOKEN_ID_EXPR), 0, managed_biguint!(100), )); sc.transfer_to_user( - managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), - managed_address!(&address_expr_to_address(OWNER_ADDRESS_EXPR)), - payments, + USER_ADDRESS.to_managed_address(), + OWNER_ADDRESS.to_managed_address(), + &payments, managed_buffer!(b"enjoy"), ); - }, - ); + }); - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "900"), - )); - world.check_state_step(CheckStateStep::new().put_account( - OWNER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "100"), - )); + world + .check_account(USER_ADDRESS) + .esdt_balance(TRANSFER_TOKEN_ID, BigUint::from(900u64)); + world + .check_account(OWNER_ADDRESS) + .esdt_balance(TRANSFER_TOKEN_ID, BigUint::from(100u64)); // transfer to user - err, not whitelisted - world.whitebox_call_check( - &transfer_role_features_whitebox, - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .esdt_transfer(TRANSFER_TOKEN_ID, 0, "100") - .no_expect(), - |sc| { + world + .tx() + .from(USER_ADDRESS) + .to(TRANSFER_ROLE_FEATURES_ADDRESS) + .payment(TestEsdtTransfer(TRANSFER_TOKEN_ID, 0, 100)) + .returns(ExpectError(4u64, "Destination address not whitelisted")) + .whitebox(transfer_role_features::contract_obj, |sc| { let payments = ManagedVec::from_single_item(EsdtTokenPayment::new( - managed_token_id!(TRANSFER_TOKEN_ID), + managed_token_id!(TRANSFER_TOKEN_ID_EXPR), 0, managed_biguint!(100), )); sc.transfer_to_user( - managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), + USER_ADDRESS.to_managed_address(), managed_address!(&Address::zero()), - payments, + &payments, managed_buffer!(b"enjoy"), ); - }, - |r| { - r.assert_user_error("Destination address not whitelisted"); - }, - ); + }); // transfer to sc - ok - world.whitebox_call( - &transfer_role_features_whitebox, - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .esdt_transfer(TRANSFER_TOKEN_ID, 0, "100"), - |sc| { + world + .tx() + .from(USER_ADDRESS) + .to(TRANSFER_ROLE_FEATURES_ADDRESS) + .payment(TestEsdtTransfer(TRANSFER_TOKEN_ID, 0, 100)) + .whitebox(transfer_role_features::contract_obj, |sc| { let payments = ManagedVec::from_single_item(EsdtTokenPayment::new( - managed_token_id!(TRANSFER_TOKEN_ID), + managed_token_id!(TRANSFER_TOKEN_ID_EXPR), 0, managed_biguint!(100), )); sc.transfer_to_contract_raw( - managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), - managed_address!(&address_expr_to_address(VAULT_ADDRESS_EXPR)), - payments, + USER_ADDRESS.to_managed_address(), + VAULT_ADDRESS.to_managed_address(), + &payments, managed_buffer!(ACCEPT_FUNDS_FUNC_NAME), ManagedArgBuffer::new(), None, ); - }, - ); + }); - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "800"), - )); - world.check_state_step(CheckStateStep::new().put_account( - VAULT_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "100"), - )); + world + .check_account(USER_ADDRESS) + .esdt_balance(TRANSFER_TOKEN_ID, BigUint::from(800u64)); + world + .check_account(VAULT_ADDRESS) + .esdt_balance(TRANSFER_TOKEN_ID, BigUint::from(100u64)); // transfer to sc - reject - world.whitebox_call( - &transfer_role_features_whitebox, - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .esdt_transfer(TRANSFER_TOKEN_ID, 0, "100"), - |sc| { + world + .tx() + .from(USER_ADDRESS) + .to(TRANSFER_ROLE_FEATURES_ADDRESS) + .payment(TestEsdtTransfer(TRANSFER_TOKEN_ID, 0, 100)) + .whitebox(transfer_role_features::contract_obj, |sc| { let payments = ManagedVec::from_single_item(EsdtTokenPayment::new( - managed_token_id!(TRANSFER_TOKEN_ID), + managed_token_id!(TRANSFER_TOKEN_ID_EXPR), 0, managed_biguint!(100), )); sc.transfer_to_contract_raw( - managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), - managed_address!(&address_expr_to_address(VAULT_ADDRESS_EXPR)), - payments, + USER_ADDRESS.to_managed_address(), + VAULT_ADDRESS.to_managed_address(), + &payments, managed_buffer!(REJECT_FUNDS_FUNC_NAME), ManagedArgBuffer::new(), None, ); - }, - ); - - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "800"), - )); - world.check_state_step(CheckStateStep::new().put_account( - VAULT_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(TRANSFER_TOKEN_ID_EXPR, "100"), - )); -} - -fn address_expr_to_address(address_expr: &str) -> Address { - AddressValue::from(address_expr).to_address() + }); + + world + .check_account(USER_ADDRESS) + .esdt_balance(TRANSFER_TOKEN_ID, BigUint::from(800u64)); + world + .check_account(VAULT_ADDRESS) + .esdt_balance(TRANSFER_TOKEN_ID, BigUint::from(100u64)); } 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 87cd296179..cee8df1e37 100644 --- a/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,61 +34,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -174,26 +142,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 affff30336..4fc243f73c 100644 --- a/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/transfer-role-features/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "transfer-role-features-wasm" version = "0.0.0" -authors = ["Dorin Marian Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.transfer-role-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 b7f5b995f7..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 bb6b8ff9f5..ca5fda59a5 100644 --- a/contracts/feature-tests/composability/vault/Cargo.toml +++ b/contracts/feature-tests/composability/vault/Cargo.toml @@ -10,10 +10,9 @@ path = "src/vault.rs" [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/base" -features = ["promises"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/scenario" diff --git a/contracts/feature-tests/composability/vault/meta/Cargo.toml b/contracts/feature-tests/composability/vault/meta/Cargo.toml index 2eb89cd954..d74c9da9fa 100644 --- a/contracts/feature-tests/composability/vault/meta/Cargo.toml +++ b/contracts/feature-tests/composability/vault/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.vault] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 ba5b72985c..51d609dbbd 100644 --- a/contracts/feature-tests/composability/vault/sc-config.toml +++ b/contracts/feature-tests/composability/vault/sc-config.toml @@ -4,8 +4,31 @@ main = "main" [contracts.main] name = "vault" add-unlabelled = true +add-labels = ["upgrade"] [contracts.promises] name = "vault-promises" add-unlabelled = true -add-labels = ["promises-endpoint"] \ No newline at end of file +add-labels = ["promises-endpoint"] + +[contracts.upgrade] +name = "vault-upgrade" +add-unlabelled = false +add-labels = ["upgrade"] + +[[proxy]] +path = "../forwarder/src/vault_proxy.rs" + +[[proxy]] +path = "../forwarder/src/vault_upgrade_proxy.rs" +add-unlabelled = false +add-labels = ["upgrade"] + +[[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 4cebf5bc43..1fb32cccdd 100644 --- a/contracts/feature-tests/composability/vault/src/vault.rs +++ b/contracts/feature-tests/composability/vault/src/vault.rs @@ -14,6 +14,19 @@ pub trait Vault { opt_arg_to_echo } + #[upgrade] + #[label("upgrade")] + fn upgrade( + &self, + opt_arg_to_echo: OptionalValue, + ) -> MultiValue2<&'static str, OptionalValue> { + self.upgraded_event(); + ("upgraded", opt_arg_to_echo).into() + } + + #[event("upgraded")] + fn upgraded_event(&self); + #[endpoint] fn echo_arguments( &self, @@ -94,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] @@ -137,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() } } @@ -151,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(); } } @@ -172,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()); @@ -210,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 22133c868e..3e928b20c9 100644 --- a/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.lock +++ b/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -167,26 +135,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -199,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" @@ -213,29 +176,3 @@ dependencies = [ "multiversx-sc-wasm-adapter", "vault", ] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] 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 ce3f2a30b2..d85cdbe112 100644 --- a/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.toml +++ b/contracts/feature-tests/composability/vault/wasm-vault-promises/Cargo.toml @@ -1,23 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "vault-promises-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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.vault] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 87c110bc70..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -32,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 new file mode 100644 index 0000000000..2aa62e0c77 --- /dev/null +++ b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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.53.0" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.0" +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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +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", +] + +[[package]] +name = "vault-upgrade-wasm" +version = "0.0.0" +dependencies = [ + "multiversx-sc-wasm-adapter", + "vault", +] diff --git a/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.toml b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.toml new file mode 100644 index 0000000000..7dd3d6687b --- /dev/null +++ b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/Cargo.toml @@ -0,0 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "vault-upgrade-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.vault] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.53.0" +path = "../../../../../framework/wasm-adapter" + +[workspace] +members = ["."] 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 new file mode 100644 index 0000000000..15f7408f1f --- /dev/null +++ b/contracts/feature-tests/composability/vault/wasm-vault-upgrade/src/lib.rs @@ -0,0 +1,24 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Upgrade: 1 +// Endpoints: 0 +// Async Callback (empty): 1 +// Total number of exported functions: 2 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + vault + ( + upgrade => upgrade + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/contracts/feature-tests/composability/vault/wasm/Cargo.lock b/contracts/feature-tests/composability/vault/wasm/Cargo.lock index 1ac6d18dda..648da833d6 100755 --- a/contracts/feature-tests/composability/vault/wasm/Cargo.lock +++ b/contracts/feature-tests/composability/vault/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -167,26 +135,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -199,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" @@ -213,29 +176,3 @@ dependencies = [ "multiversx-sc-wasm-adapter", "vault", ] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] diff --git a/contracts/feature-tests/composability/vault/wasm/Cargo.toml b/contracts/feature-tests/composability/vault/wasm/Cargo.toml index bb620a8041..e4a6c5b05d 100644 --- a/contracts/feature-tests/composability/vault/wasm/Cargo.toml +++ b/contracts/feature-tests/composability/vault/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "vault-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.vault] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 d0e42574c2..9849ddf8ae 100644 --- a/contracts/feature-tests/composability/vault/wasm/src/lib.rs +++ b/contracts/feature-tests/composability/vault/wasm/src/lib.rs @@ -1,20 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 +// Upgrade: 1 // Endpoints: 15 // Async Callback (empty): 1 -// Total number of exported functions: 17 +// Total number of exported functions: 18 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -22,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 @@ -32,7 +30,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/erc-style-contracts/crowdfunding-erc20/Cargo.toml b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/Cargo.toml index e8ab6103e6..f9e78e05e2 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 9b4262d404..2dbb219d93 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,6 +8,7 @@ publish = false [dependencies.crowdfunding-erc20] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/deploy_erc20_and_crowdfunding.scen.json b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/deploy_erc20_and_crowdfunding.scen.json index ab45dfe82b..22ccdfecf1 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/deploy_erc20_and_crowdfunding.scen.json +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/deploy_erc20_and_crowdfunding.scen.json @@ -31,7 +31,7 @@ "id": "deploy", "tx": { "from": "address:erc20_owner", - "contractCode": "file:../../erc20/output/erc20.wasm", + "contractCode": "mxsc:../../erc20/output/erc20.mxsc.json", "arguments": [ "1,000,000,000" ], @@ -65,7 +65,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" } } }, @@ -74,7 +74,7 @@ "id": "deploy", "tx": { "from": "address:crowdfunding_owner", - "contractCode": "file:../output/crowdfunding-erc20.wasm", + "contractCode": "mxsc:../output/crowdfunding-erc20.mxsc.json", "arguments": [ "1,000,000", "123,456", @@ -110,7 +110,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "sc:crowdfunding": { "nonce": "0", @@ -120,7 +120,7 @@ "str:deadline": "123,456", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/crowdfunding-erc20.wasm" + "code": "mxsc:../output/crowdfunding-erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_with_insufficient_allowance.scen.json b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_with_insufficient_allowance.scen.json index 2ce0b7cbfb..7f5d34cb5d 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_with_insufficient_allowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_with_insufficient_allowance.scen.json @@ -85,7 +85,7 @@ "str:allowance|address:acc1|sc:crowdfunding": "400,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "sc:crowdfunding": { "nonce": "0", @@ -95,7 +95,7 @@ "str:deadline": "123,456", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/crowdfunding-erc20.wasm" + "code": "mxsc:../output/crowdfunding-erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_with_sufficient_allowance.scen.json b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_with_sufficient_allowance.scen.json index efe1fecf02..cd87006871 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_with_sufficient_allowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_with_sufficient_allowance.scen.json @@ -64,7 +64,7 @@ "str:allowance|address:acc1|sc:crowdfunding": "500,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "sc:crowdfunding": { "nonce": "0", @@ -74,7 +74,7 @@ "str:deadline": "123,456", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/crowdfunding-erc20.wasm" + "code": "mxsc:../output/crowdfunding-erc20.mxsc.json" } } }, @@ -133,7 +133,7 @@ "str:allowance|address:acc1|sc:crowdfunding": "0", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "sc:crowdfunding": { "nonce": "0", @@ -145,7 +145,7 @@ "str:deposit|address:acc1": "500,000", "str:erc20Balance": "500,000" }, - "code": "file:../output/crowdfunding-erc20.wasm" + "code": "mxsc:../output/crowdfunding-erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_without_allowance.scen.json b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_without_allowance.scen.json index 9f5d256102..313c848955 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_without_allowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/fund_without_allowance.scen.json @@ -62,7 +62,7 @@ "str:allowance|address:erc20_owner|address:acc1": "400,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "sc:crowdfunding": { "nonce": "0", @@ -72,7 +72,7 @@ "str:deadline": "123,456", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/crowdfunding-erc20.wasm" + "code": "mxsc:../output/crowdfunding-erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/set_accounts.step.json b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/set_accounts.step.json index 1e32842590..c88d05c61d 100644 --- a/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/set_accounts.step.json +++ b/contracts/feature-tests/erc-style-contracts/crowdfunding-erc20/scenarios/set_accounts.step.json @@ -29,7 +29,7 @@ "str:allowance|address:erc20_owner|address:acc1": "400,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "sc:crowdfunding": { "nonce": "0", @@ -39,7 +39,7 @@ "str:deadline": "123,456", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/crowdfunding-erc20.wasm", + "code": "mxsc:../output/crowdfunding-erc20.mxsc.json", "owner": "address:crowdfunding_owner" } } 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 998f538371..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,17 +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( - "file:output/crowdfunding-erc20.wasm", + "mxsc:output/crowdfunding-erc20.mxsc.json", crowdfunding_erc20::ContractBuilder, ); - - blockchain.register_contract("file:../erc20/output/erc20.wasm", 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 513c9cf5e9..cec66cccc8 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "crowdfunding-erc20" @@ -67,15 +49,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -84,54 +57,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 e468d01b1b..c20ff0f6e6 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 @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "crowdfunding-erc20-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.crowdfunding-erc20] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 694cb75b5f..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 8c7bd6581d..dc44473149 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.44.0" +version = "0.53.0" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 1be7cd4ddf..604e079437 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,6 +8,7 @@ publish = false [dependencies.erc1155-marketplace] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/auction_batch.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/auction_batch.scen.json index 7c9c63eebd..806eea1c0b 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/auction_batch.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/auction_batch.scen.json @@ -28,7 +28,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -85,7 +84,7 @@ "str:balanceOf|sc:marketplace_contract|str:.node_id|biguint:1": "1", "str:balanceOf|sc:marketplace_contract|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../../erc1155/output/erc1155.wasm" + "code": "mxsc:../../erc1155/output/erc1155.mxsc.json" }, "sc:marketplace_contract": { "nonce": "0", @@ -96,7 +95,7 @@ "str:auctionForToken|biguint:1|biguint:2": "u32:4|str:EGLD|biguint:100|u32:2|u16:500|u64:1000|address:creator|u32:0|u64:0|u64:0|u64:0|u64:0", "str:auctionForToken|biguint:1|biguint:3": "u32:4|str:EGLD|biguint:100|u32:2|u16:500|u64:1000|address:creator|u32:0|u64:0|u64:0|u64:0|u64:0" }, - "code": "file:../output/erc1155-marketplace.wasm" + "code": "mxsc:../output/erc1155-marketplace.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/auction_single_token_egld.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/auction_single_token_egld.scen.json index d47e7785e2..79d2048577 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/auction_single_token_egld.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/auction_single_token_egld.scen.json @@ -28,7 +28,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -85,7 +84,7 @@ "str:balanceOf|sc:marketplace_contract|str:.node_id|biguint:1": "1", "str:balanceOf|sc:marketplace_contract|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../../erc1155/output/erc1155.wasm" + "code": "mxsc:../../erc1155/output/erc1155.mxsc.json" }, "sc:marketplace_contract": { "nonce": "0", @@ -95,7 +94,7 @@ "str:percentageCut": "10", "str:auctionForToken|biguint:1|biguint:2": "u32:4|str:EGLD|biguint:100|u32:2|u16:500|u64:1000|address:creator|u32:0|u64:0|u64:0|u64:0|u64:0" }, - "code": "file:../output/erc1155-marketplace.wasm" + "code": "mxsc:../output/erc1155-marketplace.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_first_egld.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_first_egld.scen.json index d93272a63e..bb1bfacd88 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_first_egld.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_first_egld.scen.json @@ -25,7 +25,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -82,7 +81,7 @@ "str:balanceOf|sc:marketplace_contract|str:.node_id|biguint:1": "1", "str:balanceOf|sc:marketplace_contract|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../../erc1155/output/erc1155.wasm" + "code": "mxsc:../../erc1155/output/erc1155.mxsc.json" }, "sc:marketplace_contract": { "nonce": "0", @@ -92,7 +91,7 @@ "str:percentageCut": "10", "str:auctionForToken|biguint:1|biguint:2": "u32:4|str:EGLD|biguint:100|u32:2|u16:500|u64:1000|address:creator|biguint:100|address:user1" }, - "code": "file:../output/erc1155-marketplace.wasm" + "code": "mxsc:../output/erc1155-marketplace.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_second_egld.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_second_egld.scen.json index 99e91ec657..232a7b687d 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_second_egld.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_second_egld.scen.json @@ -79,7 +79,7 @@ "str:balanceOf|sc:marketplace_contract|str:.node_id|biguint:1": "1", "str:balanceOf|sc:marketplace_contract|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../../erc1155/output/erc1155.wasm" + "code": "mxsc:../../erc1155/output/erc1155.mxsc.json" }, "sc:marketplace_contract": { "nonce": "0", @@ -89,7 +89,7 @@ "str:percentageCut": "10", "str:auctionForToken|biguint:1|biguint:2": "u32:4|str:EGLD|biguint:100|u32:2|u16:500|u64:1000|address:creator|u32:2|u16:300|address:user2" }, - "code": "file:../output/erc1155-marketplace.wasm" + "code": "mxsc:../output/erc1155-marketplace.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_third_egld.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_third_egld.scen.json index eabb130f07..9df128c7f7 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_third_egld.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/bid_third_egld.scen.json @@ -79,7 +79,7 @@ "str:balanceOf|sc:marketplace_contract|str:.node_id|biguint:1": "1", "str:balanceOf|sc:marketplace_contract|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../../erc1155/output/erc1155.wasm" + "code": "mxsc:../../erc1155/output/erc1155.mxsc.json" }, "sc:marketplace_contract": { "nonce": "0", @@ -89,7 +89,7 @@ "str:percentageCut": "10", "str:auctionForToken|biguint:1|biguint:2": "u32:4|str:EGLD|biguint:100|u32:2|u16:500|u64:1000|address:creator|u32:2|u16:500|address:user1" }, - "code": "file:../output/erc1155-marketplace.wasm" + "code": "mxsc:../output/erc1155-marketplace.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/end_auction.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/end_auction.scen.json index f1c21716a5..95adcc52d5 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/end_auction.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/end_auction.scen.json @@ -83,7 +83,7 @@ "str:balanceOf|address:user1|str:.node_id|biguint:1": "1", "str:balanceOf|address:user1|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../../erc1155/output/erc1155.wasm" + "code": "mxsc:../../erc1155/output/erc1155.mxsc.json" }, "sc:marketplace_contract": { "nonce": "0", @@ -97,7 +97,7 @@ "str:claimableFunds|str:.node_id|nested:str:EGLD": "1", "str:claimableFunds|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155-marketplace.wasm" + "code": "mxsc:../output/erc1155-marketplace.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/setup_accounts.step.json b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/setup_accounts.step.json index 578efb9856..99dd4cdd35 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/setup_accounts.step.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/scenarios/setup_accounts.step.json @@ -46,7 +46,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:1": "1", "str:balanceOf|address:creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../../erc1155/output/erc1155.wasm" + "code": "mxsc:../../erc1155/output/erc1155.mxsc.json" }, "sc:marketplace_contract": { "nonce": "0", @@ -55,7 +55,7 @@ "str:tokenOwnershipContractAddress": "sc:ownership_contract", "str:percentageCut": "10" }, - "code": "file:../output/erc1155-marketplace.wasm" + "code": "mxsc:../output/erc1155-marketplace.mxsc.json" } } } 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/tests/erc1155_marketplace_scenario_rs_test.rs b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/tests/erc1155_marketplace_scenario_rs_test.rs index 5c7c6630cd..3c19930d4d 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/tests/erc1155_marketplace_scenario_rs_test.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155-marketplace/tests/erc1155_marketplace_scenario_rs_test.rs @@ -3,11 +3,11 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); blockchain.register_contract( - "file:output/erc1155-marketplace.wasm", + "mxsc:output/erc1155-marketplace.mxsc.json", erc1155_marketplace::ContractBuilder, ); blockchain.register_contract( - "file:../erc1155/output/erc1155.wasm", + "mxsc:../erc1155/output/erc1155.mxsc.json", erc1155::ContractBuilder, ); 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 d9922cba7c..6fd99d6303 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -67,15 +49,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -84,54 +57,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 405198b3da..15d1f84e6f 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 @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "erc1155-marketplace-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.erc1155-marketplace] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 86d821e06d..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 1b1b91239a..6522717a20 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 067bafd384..32cc9884ce 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,6 +8,7 @@ publish = false [dependencies.erc1155-user-mock] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 acd1cd77ac..7115285169 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 2bca4d45b7..a552d7182f 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 @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "erc1155-user-mock-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.erc1155-user-mock] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 c3e03c50ad..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 b4457a1f33..f08ff006d6 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.44.0" +version = "0.53.0" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 e0b94e8390..68f6c047bc 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.erc1155] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/batch_transfer_both_types.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_both_types.scen.json index 9307af596f..2b9cf18762 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_both_types.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_both_types.scen.json @@ -27,7 +27,7 @@ "out": [], "status": "0", "message": "", - "logs": [], + "logs": "*", "gas": "*", "refund": "*" } @@ -79,7 +79,7 @@ "str:balanceOf|address:user1|str:.node_id|biguint:2": "2", "str:balanceOf|address:user1|str:.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_both_types_to_sc.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_both_types_to_sc.scen.json index 5792a128d4..0e2bc56f66 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_both_types_to_sc.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_both_types_to_sc.scen.json @@ -12,7 +12,7 @@ "sc:user_mock": { "nonce": "0", "balance": "0", - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" } } }, @@ -37,7 +37,7 @@ "out": [], "status": "0", "message": "", - "logs": [], + "logs": "*", "gas": "*", "refund": "*" } @@ -59,7 +59,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" }, "sc:erc1155": { "nonce": "0", @@ -95,7 +95,7 @@ "str:balanceOf|sc:user_mock|str:.node_id|biguint:2": "2", "str:balanceOf|sc:user_mock|str:.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_fungible.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_fungible.scen.json index ab8b087010..027990fe2c 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_fungible.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_fungible.scen.json @@ -27,7 +27,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -75,7 +74,7 @@ "str:balanceOf|address:user1|str:.node_id|biguint:2": "2", "str:balanceOf|address:user1|str:.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_fungible_to_sc.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_fungible_to_sc.scen.json index 2f278f93ae..c06e5bd0a4 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_fungible_to_sc.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_fungible_to_sc.scen.json @@ -12,7 +12,7 @@ "sc:user_mock": { "nonce": "0", "balance": "0", - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" } } }, @@ -37,7 +37,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -59,7 +58,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" }, "sc:erc1155": { "nonce": "0", @@ -91,7 +90,7 @@ "str:balanceOf|sc:user_mock|str:.node_id|biguint:2": "2", "str:balanceOf|sc:user_mock|str:.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_non_fungible.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_non_fungible.scen.json index bb8f407742..ba16648d8f 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_non_fungible.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_non_fungible.scen.json @@ -27,7 +27,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -85,7 +84,7 @@ "str:balanceOf|address:user1|str:.node_id|biguint:2": "2", "str:balanceOf|address:user1|str:.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_non_fungible_to_sc.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_non_fungible_to_sc.scen.json index 409acb7edf..a12ccb6653 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_non_fungible_to_sc.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/batch_transfer_non_fungible_to_sc.scen.json @@ -12,7 +12,7 @@ "sc:user_mock": { "nonce": "0", "balance": "0", - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" } } }, @@ -37,7 +37,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -59,7 +58,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" }, "sc:erc1155": { "nonce": "0", @@ -101,7 +100,7 @@ "str:balanceOf|sc:user_mock|str:.node_id|biguint:2": "2", "str:balanceOf|sc:user_mock|str:.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/burn_fungible.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/burn_fungible.scen.json index c93861e869..2a2cdf9ebf 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/burn_fungible.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/burn_fungible.scen.json @@ -24,7 +24,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -56,7 +55,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:1": "1", "str:balanceOf|address:creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/burn_non_fungible.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/burn_non_fungible.scen.json index d908507973..4184594a8f 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/burn_non_fungible.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/burn_non_fungible.scen.json @@ -62,7 +62,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:1": "1", "str:balanceOf|address:creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_one_fungible_one_non_fungible.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_one_fungible_one_non_fungible.scen.json index b3f3ce5154..411b5f2446 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_one_fungible_one_non_fungible.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_one_fungible_one_non_fungible.scen.json @@ -27,7 +27,6 @@ ], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -70,7 +69,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:2": "2", "str:balanceOf|address:creator|str:.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_token_fungible.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_token_fungible.scen.json index 55713d699a..42afef0b50 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_token_fungible.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_token_fungible.scen.json @@ -36,7 +36,6 @@ ], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -68,7 +67,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:1": "1", "str:balanceOf|address:creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_token_non_fungible.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_token_non_fungible.scen.json index 7b57f4c64c..db66eccbd3 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_token_non_fungible.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_token_non_fungible.scen.json @@ -36,7 +36,6 @@ ], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -74,7 +73,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:1": "1", "str:balanceOf|address:creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_fungible_different_creator.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_fungible_different_creator.scen.json index ca1b77eb20..5e6086bad0 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_fungible_different_creator.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_fungible_different_creator.scen.json @@ -36,7 +36,6 @@ ], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -81,7 +80,7 @@ "str:balanceOf|address:second_creator|str:.node_id|biguint:2": "1", "str:balanceOf|address:second_creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_fungible_same_creator.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_fungible_same_creator.scen.json index dd353d8b0a..ce79df0337 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_fungible_same_creator.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_fungible_same_creator.scen.json @@ -27,7 +27,6 @@ ], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -66,7 +65,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:2": "2", "str:balanceOf|address:creator|str:.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_non_fungible_same_creator.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_non_fungible_same_creator.scen.json index 7c5d3c5c43..9d240f133e 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_non_fungible_same_creator.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/create_two_tokens_both_non_fungible_same_creator.scen.json @@ -27,7 +27,6 @@ ], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -76,7 +75,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:2": "2", "str:balanceOf|address:creator|str:.info": "u32:2|u32:1|u32:2|u32:2" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/deploy.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/deploy.scen.json index 8b9ac37974..6a10f01833 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/deploy.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/deploy.scen.json @@ -23,7 +23,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/erc1155.wasm", + "contractCode": "mxsc:../output/erc1155.mxsc.json", "arguments": [], "gasLimit": "0x100000", "gasPrice": "0x00" @@ -32,7 +32,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -49,7 +48,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_fungible.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_fungible.scen.json index 0435769bdf..dfb2e63be8 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_fungible.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_fungible.scen.json @@ -24,7 +24,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -56,7 +55,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:1": "1", "str:balanceOf|address:creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_non_fungible.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_non_fungible.scen.json index dc0e775d35..08d3a75c57 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_non_fungible.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_non_fungible.scen.json @@ -24,7 +24,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -65,7 +64,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:1": "1", "str:balanceOf|address:creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_not_creator.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_not_creator.scen.json index 8cbaeaedb0..78d5ef6aa1 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_not_creator.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/mint_not_creator.scen.json @@ -56,7 +56,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:1": "1", "str:balanceOf|address:creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_not_enough_balance.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_not_enough_balance.scen.json index 6fbbc3d169..252e24e2ce 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_not_enough_balance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_not_enough_balance.scen.json @@ -27,7 +27,6 @@ "out": [], "status": "4", "message": "str:Not enough balance for id", - "logs": "*", "gas": "*", "refund": "*" } @@ -59,7 +58,7 @@ "str:balanceOf|address:creator|str:.node_id|biguint:1": "1", "str:balanceOf|address:creator|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_ok.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_ok.scen.json index c28a98bd30..5507b2c18f 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_ok.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_ok.scen.json @@ -27,7 +27,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -64,7 +63,7 @@ "str:balanceOf|address:user1|str:.node_id|biguint:1": "1", "str:balanceOf|address:user1|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_ok_to_sc.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_ok_to_sc.scen.json index 84ffd8ccc2..9cf2d54aff 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_ok_to_sc.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_fungible_ok_to_sc.scen.json @@ -12,7 +12,7 @@ "sc:user_mock": { "nonce": "0", "balance": "0", - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" } } }, @@ -37,7 +37,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -59,7 +58,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" }, "sc:erc1155": { "nonce": "0", @@ -80,7 +79,7 @@ "str:balanceOf|sc:user_mock|str:.node_id|biguint:1": "1", "str:balanceOf|sc:user_mock|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_non_fungible_ok.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_non_fungible_ok.scen.json index eaba1aa2f6..e4f44827fa 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_non_fungible_ok.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_non_fungible_ok.scen.json @@ -27,7 +27,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -70,7 +69,7 @@ "str:balanceOf|address:user1|str:.node_id|biguint:1": "1", "str:balanceOf|address:user1|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_non_fungible_ok_to_sc.scen.json b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_non_fungible_ok_to_sc.scen.json index ab588567f2..665e99e8e1 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_non_fungible_ok_to_sc.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc1155/scenarios/transfer_non_fungible_ok_to_sc.scen.json @@ -12,7 +12,7 @@ "sc:user_mock": { "nonce": "0", "balance": "0", - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" } } }, @@ -37,7 +37,6 @@ "out": [], "status": "0", "message": "", - "logs": [], "gas": "*", "refund": "*" } @@ -59,7 +58,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../../erc1155-user-mock/output/erc1155-user-mock.wasm" + "code": "mxsc:../../erc1155-user-mock/output/erc1155-user-mock.mxsc.json" }, "sc:erc1155": { "nonce": "0", @@ -86,7 +85,7 @@ "str:balanceOf|sc:user_mock|str:.node_id|biguint:1": "1", "str:balanceOf|sc:user_mock|str:.info": "u32:1|u32:1|u32:1|u32:1" }, - "code": "file:../output/erc1155.wasm" + "code": "mxsc:../output/erc1155.mxsc.json" } } } 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..b4d8acc941 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155/src/erc1155.rs @@ -160,7 +160,7 @@ pub trait Erc1155 { self.token_owner(type_id, nft_id).set(to); } else { self.token_owner(type_id, nft_id) - .set(&ManagedAddress::zero()); + .set(ManagedAddress::zero()); } } @@ -320,7 +320,7 @@ pub trait Erc1155 { let amount = BigUint::from(1u32); self.decrease_balance(owner, type_id, &amount); self.token_owner(type_id, nft_id) - .set(&ManagedAddress::zero()); + .set(ManagedAddress::zero()); } /// Range is inclusive for both `start` and `end` @@ -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/tests/erc1155_scenario_rs_test.rs b/contracts/feature-tests/erc-style-contracts/erc1155/tests/erc1155_scenario_rs_test.rs index 5f751e1b6f..46d25e9447 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/tests/erc1155_scenario_rs_test.rs +++ b/contracts/feature-tests/erc-style-contracts/erc1155/tests/erc1155_scenario_rs_test.rs @@ -2,9 +2,9 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.register_contract("file:output/erc1155.wasm", erc1155::ContractBuilder); + blockchain.register_contract("mxsc:output/erc1155.mxsc.json", erc1155::ContractBuilder); blockchain.register_contract( - "file:../erc1155-user-mock/output/erc1155-user-mock.wasm", + "mxsc:../erc1155-user-mock/output/erc1155-user-mock.mxsc.json", erc1155_user_mock::ContractBuilder, ); 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 ebe32124a4..aa024d408f 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 a1969e8051..7f9da3c3f9 100644 --- a/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc1155/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "erc1155-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.erc1155] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 35b9cf3bc6..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 24683d9b10..952974dc8c 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 a3f98845b4..fe09bef84b 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc20/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.erc20] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/allowance_CallerCaller.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_CallerCaller.scen.json index 4d1bf9660a..9ba4dda1e5 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_CallerCaller.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_CallerCaller.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_CallerOther.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_CallerOther.scen.json index c0863dc955..b1bab22b4d 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_CallerOther.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_CallerOther.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherCaller.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherCaller.scen.json index 1517866069..8df986c1e7 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherCaller.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherCaller.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherEqOther.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherEqOther.scen.json index 38cb8516b4..5e1e4be875 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherEqOther.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherEqOther.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherNEqOther.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherNEqOther.scen.json index 1e46287e35..40600f4724 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherNEqOther.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/allowance_OtherNEqOther.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Caller-Positive.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Caller-Positive.scen.json index 3e5f988aa2..4e5eb8574f 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Caller-Positive.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Caller-Positive.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_1" ], - "data": "0x25" + "data": [ + "0x25" + ] } ], "gas": "*", @@ -70,7 +72,7 @@ "str:allowance|address:account_1|address:account_1": "0x25", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Caller-Zero.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Caller-Zero.scen.json index 14061d192c..3f95337d46 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Caller-Zero.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Caller-Zero.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_1" ], - "data": "0" + "data": [ + "0" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Other-Positive.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Other-Positive.scen.json index cbf0eabe8b..03b7e949c3 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Other-Positive.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Other-Positive.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_2" ], - "data": "0x2a" + "data": [ + "0x2a" + ] } ], "gas": "*", @@ -70,7 +72,7 @@ "str:allowance|address:account_1|address:account_2": "0x2a", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Other-Zero.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Other-Zero.scen.json index d3f9240b0d..c5cb63c458 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Other-Zero.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_Other-Zero.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_2" ], - "data": "0" + "data": [ + "0" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_SwitchCaller.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_SwitchCaller.scen.json index 2f319fbb2d..9925aae1ff 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_SwitchCaller.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/approve_SwitchCaller.scen.json @@ -20,7 +20,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -74,7 +74,9 @@ "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1000000000000000000000000", "address:account_1" ], - "data": "0x19" + "data": [ + "0x19" + ] } ], "gas": "*", @@ -128,7 +130,7 @@ "str:allowance|0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1000000000000000000000000|address:account_1": "0x19", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/balanceOf_Caller.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/balanceOf_Caller.scen.json index def7c4474e..4e5b368bda 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/balanceOf_Caller.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/balanceOf_Caller.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -59,7 +59,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/balanceOf_NonCaller.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/balanceOf_NonCaller.scen.json index afd628753c..5ca8fff453 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/balanceOf_NonCaller.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/balanceOf_NonCaller.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -59,7 +59,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/not_payable.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/not_payable.scen.json index c4d038992e..25eedd8c02 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/not_payable.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/not_payable.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -177,7 +177,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/not_payable_esdt.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/not_payable_esdt.scen.json index 03cbe22533..7dff3dc600 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/not_payable_esdt.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/not_payable_esdt.scen.json @@ -19,7 +19,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -213,7 +213,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/totalSupply_Positive.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/totalSupply_Positive.scen.json index 2a4570c650..d946947e50 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/totalSupply_Positive.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/totalSupply_Positive.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -57,7 +57,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/totalSupply_Zero.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/totalSupply_Zero.scen.json index 2877139c74..8dd522c405 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/totalSupply_Zero.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/totalSupply_Zero.scen.json @@ -12,7 +12,7 @@ "sc:erc20": { "nonce": "0", "balance": "0", - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -50,7 +50,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-BalanceEqAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-BalanceEqAllowance.scen.json index 43d20b4518..005f1ccab5 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-BalanceEqAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-BalanceEqAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:coin_holder_1", "address:coin_holder_2" ], - "data": "0x17" + "data": [ + "0x17" + ] } ], "gas": "*", @@ -73,7 +75,7 @@ "str:balance|address:coin_holder_2": "0x17", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-BalanceNEqAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-BalanceNEqAllowance.scen.json index 0b0d3f7151..fb8c9d3c37 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-BalanceNEqAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-BalanceNEqAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:coin_holder_1", "address:coin_holder_2" ], - "data": "0x17" + "data": [ + "0x17" + ] } ], "gas": "*", @@ -73,7 +75,7 @@ "str:balance|address:coin_holder_2": "0x17", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireAllowanceMoreThanBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireAllowanceMoreThanBalance.scen.json index 381bec1bbc..6507bc4089 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireAllowanceMoreThanBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireAllowanceMoreThanBalance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireBalanceEqAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireBalanceEqAllowance.scen.json index df774e506c..e9eb702338 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireBalanceEqAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireBalanceEqAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:coin_holder_1", "address:coin_holder_2" ], - "data": "0x2710" + "data": [ + "0x2710" + ] } ], "gas": "*", @@ -71,7 +73,7 @@ "str:balance|address:coin_holder_2": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireBalanceMoreThanAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireBalanceMoreThanAllowance.scen.json index 8f6d15eeb4..39fc9fac7e 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireBalanceMoreThanAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-EntireBalanceMoreThanAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-MoreThanAllowanceLessThanBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-MoreThanAllowanceLessThanBalance.scen.json index 24bfb5d26b..f0a53df528 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-MoreThanAllowanceLessThanBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-MoreThanAllowanceLessThanBalance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-MoreThanBalanceLessThanAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-MoreThanBalanceLessThanAllowance.scen.json index 7b09e95135..7e4e12ee4c 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-MoreThanBalanceLessThanAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-MoreThanBalanceLessThanAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-NoOverflow.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-NoOverflow.scen.json index 3cb66650ec..eba57cef83 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-NoOverflow.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-NoOverflow.scen.json @@ -18,7 +18,7 @@ "str:balance|address:account_2": "0x0a", "str:totalSupply": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -49,7 +49,9 @@ "address:coin_holder_1", "address:account_2" ], - "data": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" + "data": [ + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" + ] } ], "gas": "*", @@ -72,7 +74,7 @@ "str:balance|address:account_2": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "str:totalSupply": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-StillNoOverflow.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-StillNoOverflow.scen.json index 4760d104fa..1bb90ed14c 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-StillNoOverflow.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllDistinct-StillNoOverflow.scen.json @@ -18,7 +18,7 @@ "str:balance|address:account_2": "0x0a", "str:totalSupply": "0x010000000000000000000000000000000000000000000000000000000000000000" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -49,7 +49,9 @@ "address:coin_holder_1", "address:account_2" ], - "data": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6" + "data": [ + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6" + ] } ], "gas": "*", @@ -72,7 +74,7 @@ "str:balance|address:account_2": "0x010000000000000000000000000000000000000000000000000000000000000000", "str:totalSupply": "0x010000000000000000000000000000000000000000000000000000000000000000" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllEqual-AllowanceRelevant.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllEqual-AllowanceRelevant.scen.json index ff98e445f2..3f197e8eec 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllEqual-AllowanceRelevant.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllEqual-AllowanceRelevant.scen.json @@ -17,7 +17,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllEqual-EntireBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllEqual-EntireBalance.scen.json index da498cbcae..4155ce217e 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllEqual-EntireBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_AllEqual-EntireBalance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:account_1", "address:account_1" ], - "data": "0x2710" + "data": [ + "0x2710" + ] } ], "gas": "*", @@ -71,7 +73,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-AllowanceRelevant.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-AllowanceRelevant.scen.json index 3a2fa29249..7e92e9878b 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-AllowanceRelevant.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-AllowanceRelevant.scen.json @@ -17,7 +17,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-EntireBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-EntireBalance.scen.json index 7dd46751db..6ede55a500 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-EntireBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-EntireBalance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:account_1", "address:account_7" ], - "data": "0x2710" + "data": [ + "0x2710" + ] } ], "gas": "*", @@ -71,7 +73,7 @@ "str:balance|address:account_7": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-MoreThanBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-MoreThanBalance.scen.json index 6758bc2ea3..b03c17a89c 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-MoreThanBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqFrom-MoreThanBalance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-BalanceNEqAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-BalanceNEqAllowance.scen.json index 2230177227..0480575173 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-BalanceNEqAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-BalanceNEqAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:coin_holder_1", "address:account_1" ], - "data": "0x17" + "data": [ + "0x17" + ] } ], "gas": "*", @@ -73,7 +75,7 @@ "str:balance|address:account_1": "0x17", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-MoreThanAllowanceLessThanBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-MoreThanAllowanceLessThanBalance.scen.json index 8a2db2655c..40dabff5d4 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-MoreThanAllowanceLessThanBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-MoreThanAllowanceLessThanBalance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-MoreThanBalanceLessThanAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-MoreThanBalanceLessThanAllowance.scen.json index 63c7b9ca6f..b4015515b1 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-MoreThanBalanceLessThanAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_CallerEqTo-MoreThanBalanceLessThanAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_Exploratory-MultipleTransfersSucceed.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_Exploratory-MultipleTransfersSucceed.scen.json index a3459b5568..a046cd5b16 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_Exploratory-MultipleTransfersSucceed.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_Exploratory-MultipleTransfersSucceed.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:coin_holder_1", "address:coin_holder_2" ], - "data": "0x0a" + "data": [ + "0x0a" + ] } ], "gas": "*", @@ -82,7 +84,9 @@ "address:coin_holder_1", "address:account_6" ], - "data": "0x0a" + "data": [ + "0x0a" + ] } ], "gas": "*", @@ -116,7 +120,9 @@ "address:coin_holder_1", "address:coin_holder_1" ], - "data": "0x0a" + "data": [ + "0x0a" + ] } ], "gas": "*", @@ -150,7 +156,9 @@ "address:coin_holder_1", "address:account_1" ], - "data": "0x0a" + "data": [ + "0x0a" + ] } ], "gas": "*", @@ -176,7 +184,7 @@ "str:balance|address:account_1": "0x0a", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_Exploratory-MultipleTransfersThrow.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_Exploratory-MultipleTransfersThrow.scen.json index 4723df7702..175afd3cde 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_Exploratory-MultipleTransfersThrow.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_Exploratory-MultipleTransfersThrow.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:coin_holder_1", "address:coin_holder_2" ], - "data": "0x0a" + "data": [ + "0x0a" + ] } ], "gas": "*", @@ -82,7 +84,9 @@ "address:coin_holder_1", "address:account_6" ], - "data": "0x0a" + "data": [ + "0x0a" + ] } ], "gas": "*", @@ -116,7 +120,9 @@ "address:coin_holder_1", "address:coin_holder_1" ], - "data": "0x0a" + "data": [ + "0x0a" + ] } ], "gas": "*", @@ -166,7 +172,7 @@ "str:balance|address:account_6": "0x0a", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-BalanceEqAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-BalanceEqAllowance.scen.json index 2a18e14207..a31f4c042d 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-BalanceEqAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-BalanceEqAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:coin_holder_1", "address:coin_holder_1" ], - "data": "0x17" + "data": [ + "0x17" + ] } ], "gas": "*", @@ -72,7 +74,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-BalanceNEqAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-BalanceNEqAllowance.scen.json index 0604d015c2..b424a02811 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-BalanceNEqAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-BalanceNEqAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:coin_holder_1", "address:coin_holder_1" ], - "data": "0x17" + "data": [ + "0x17" + ] } ], "gas": "*", @@ -72,7 +74,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireAllowanceMoreThanBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireAllowanceMoreThanBalance.scen.json index a7c68f3a79..d13fcd283e 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireAllowanceMoreThanBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireAllowanceMoreThanBalance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireBalanceEqAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireBalanceEqAllowance.scen.json index 1a1e95799c..74b9bac0da 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireBalanceEqAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireBalanceEqAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -48,7 +48,9 @@ "address:coin_holder_1", "address:coin_holder_1" ], - "data": "0x2710" + "data": [ + "0x2710" + ] } ], "gas": "*", @@ -71,7 +73,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireBalanceMoreThanAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireBalanceMoreThanAllowance.scen.json index 464581b9b8..7f19c1145b 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireBalanceMoreThanAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-EntireBalanceMoreThanAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-MoreThanAllowanceLessThanBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-MoreThanAllowanceLessThanBalance.scen.json index 3b8f980186..95325597b6 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-MoreThanAllowanceLessThanBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-MoreThanAllowanceLessThanBalance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-MoreThanBalanceLessThanAllowance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-MoreThanBalanceLessThanAllowance.scen.json index e48e51e4f7..b71feb7885 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-MoreThanBalanceLessThanAllowance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-MoreThanBalanceLessThanAllowance.scen.json @@ -17,7 +17,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -62,7 +62,7 @@ "str:balance|address:coin_holder_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-NoOverflow.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-NoOverflow.scen.json index 74ef4842ad..9b45aba369 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-NoOverflow.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transferFrom_FromEqTo-NoOverflow.scen.json @@ -18,7 +18,7 @@ "str:balance|address:account_2": "0x0a", "str:totalSupply": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -49,7 +49,9 @@ "address:coin_holder_1", "address:account_2" ], - "data": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" + "data": [ + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" + ] } ], "gas": "*", @@ -72,7 +74,7 @@ "str:balance|address:account_2": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "str:totalSupply": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-AllowanceIrrelevant.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-AllowanceIrrelevant.scen.json index 2cebe6f23e..eb50667a88 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-AllowanceIrrelevant.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-AllowanceIrrelevant.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_1" ], - "data": "0x14" + "data": [ + "0x14" + ] } ], "gas": "*", @@ -79,7 +81,9 @@ "address:account_1", "address:account_1" ], - "data": "0x17" + "data": [ + "0x17" + ] } ], "gas": "*", @@ -103,7 +107,7 @@ "str:allowance|address:account_1|address:account_1": "0x14", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-EntireBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-EntireBalance.scen.json index 979c0cb95e..6bf8a8f2f7 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-EntireBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-EntireBalance.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_1" ], - "data": "0x2710" + "data": [ + "0x2710" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-MoreThanBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-MoreThanBalance.scen.json index 0b52e75810..47308147c8 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-MoreThanBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-MoreThanBalance.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -59,7 +59,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-NoOverflow.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-NoOverflow.scen.json index dae9f61eed..6f78008aaa 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-NoOverflow.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-NoOverflow.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5", "str:totalSupply": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_1" ], - "data": "0x0a" + "data": [ + "0x0a" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_1": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5", "str:totalSupply": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-Positive.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-Positive.scen.json index 519e664665..30ba7d2f61 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-Positive.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-Positive.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_1" ], - "data": "0x17" + "data": [ + "0x17" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-StillNoOverflow.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-StillNoOverflow.scen.json index d8ec5a8371..1aa0cc539d 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-StillNoOverflow.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-StillNoOverflow.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5", "str:totalSupply": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_1" ], - "data": "0x0b" + "data": [ + "0x0b" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_1": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5", "str:totalSupply": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-Zero.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-Zero.scen.json index f53b5773e6..fe52d536cf 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-Zero.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Caller-Zero.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_1" ], - "data": "0" + "data": [ + "0" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-AllowanceIrrelevant.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-AllowanceIrrelevant.scen.json index ccef21f2e7..e1d9585427 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-AllowanceIrrelevant.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-AllowanceIrrelevant.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_1" ], - "data": "0x14" + "data": [ + "0x14" + ] } ], "gas": "*", @@ -79,7 +81,9 @@ "address:account_1", "address:account_7" ], - "data": "0x17" + "data": [ + "0x17" + ] } ], "gas": "*", @@ -104,7 +108,7 @@ "str:allowance|address:account_1|address:account_1": "0x14", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-EntireBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-EntireBalance.scen.json index e60ece815d..8089d94ac6 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-EntireBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-EntireBalance.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_7" ], - "data": "0x2710" + "data": [ + "0x2710" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_7": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-MoreThanBalance.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-MoreThanBalance.scen.json index c0f6ead594..d8356178a0 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-MoreThanBalance.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-MoreThanBalance.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -59,7 +59,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-NoOverflow.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-NoOverflow.scen.json index e79a16b66d..ca508ab5c2 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-NoOverflow.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-NoOverflow.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "str:totalSupply": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_2" ], - "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "data": [ + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_2": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "str:totalSupply": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-Positive.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-Positive.scen.json index 4b35010b52..e9a895916a 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-Positive.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-Positive.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_7" ], - "data": "0x17" + "data": [ + "0x17" + ] } ], "gas": "*", @@ -70,7 +72,7 @@ "str:balance|address:account_7": "0x17", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-StillNoOverflow.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-StillNoOverflow.scen.json index c709e03502..1f534f003b 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-StillNoOverflow.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-StillNoOverflow.scen.json @@ -17,7 +17,7 @@ "str:balance|address:account_2": "0x0a", "str:totalSupply": "0x010000000000000000000000000000000000000000000000000000000000000009" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -47,7 +47,9 @@ "address:account_1", "address:account_2" ], - "data": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" + "data": [ + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5" + ] } ], "gas": "*", @@ -71,7 +73,7 @@ "str:balance|address:account_2": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "str:totalSupply": "0x010000000000000000000000000000000000000000000000000000000000000009" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-Zero.scen.json b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-Zero.scen.json index 2d703784d9..0613830a32 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-Zero.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc20/scenarios/transfer_Other-Zero.scen.json @@ -16,7 +16,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } }, @@ -46,7 +46,9 @@ "address:account_1", "address:account_7" ], - "data": "0" + "data": [ + "0" + ] } ], "gas": "*", @@ -69,7 +71,7 @@ "str:balance|address:account_1": "0x2710", "str:totalSupply": "0x2710" }, - "code": "file:../output/erc20.wasm" + "code": "mxsc:../output/erc20.mxsc.json" } } } 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 3877ef0ad6..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,9 +2,8 @@ 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("file:output/erc20.wasm", erc20::ContractBuilder); + 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 ef9978e123..ada159d488 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 45b8f256e7..1204bda01d 100644 --- a/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc20/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "erc20-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.erc20] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 44431a67da..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 946e0e057e..8de13cc846 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.44.0" +version = "0.53.0" path = "../../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 99183b8d4d..efb6d7fa17 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/meta/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc721/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.erc721] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/nft-init.scen.json b/contracts/feature-tests/erc-style-contracts/erc721/scenarios/nft-init.scen.json index ea1e311eb3..619d168ae4 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/scenarios/nft-init.scen.json +++ b/contracts/feature-tests/erc-style-contracts/erc721/scenarios/nft-init.scen.json @@ -22,7 +22,7 @@ "id": "deploy", "tx": { "from": "address:contract_owner", - "contractCode": "file:../output/erc721.wasm", + "contractCode": "mxsc:../output/erc721.mxsc.json", "arguments": [ "3" ], diff --git a/contracts/feature-tests/erc-style-contracts/erc721/tests/nft_scenario_rs_test.rs b/contracts/feature-tests/erc-style-contracts/erc721/tests/nft_scenario_rs_test.rs index 9d07877d7d..043a19ff36 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/tests/nft_scenario_rs_test.rs +++ b/contracts/feature-tests/erc-style-contracts/erc721/tests/nft_scenario_rs_test.rs @@ -2,7 +2,7 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.register_contract("file:output/erc721.wasm", erc721::ContractBuilder); + blockchain.register_contract("mxsc:output/erc721.mxsc.json", erc721::ContractBuilder); blockchain } 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 7247bce086..2ff486f4af 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.lock +++ b/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 27e84233bf..19556830d3 100644 --- a/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.toml +++ b/contracts/feature-tests/erc-style-contracts/erc721/wasm/Cargo.toml @@ -1,3 +1,9 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "erc721-wasm" version = "0.0.0" @@ -5,10 +11,7 @@ edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = ["."] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -16,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.erc721] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../../framework/wasm-adapter" + +[workspace] +members = ["."] 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 bbb38f0df1..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 5aa509c068..65d07485b1 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.44.0" +version = "0.53.0" path = "../../../../framework/base" features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 f1c08c20b0..6c8fa73739 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,6 +8,7 @@ publish = false [dependencies.lottery-erc20] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/buy-all-tickets-different-accounts.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-all-tickets-different-accounts.scen.json index 8d079bc3f3..e65250c952 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-all-tickets-different-accounts.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-all-tickets-different-accounts.scen.json @@ -166,7 +166,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc4": "1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc5": "1" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -187,7 +187,7 @@ "str:allowance|address:acc5|sc:lottery": "0", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-more-tickets-than-allowed.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-more-tickets-than-allowed.scen.json index c5adb71323..cdad8b3340 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-more-tickets-than-allowed.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-more-tickets-than-allowed.scen.json @@ -55,7 +55,7 @@ "str:ticketHolder|u32:12|str:lottery_name|0x00000000": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -70,7 +70,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-deadline.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-deadline.scen.json index 0c45bcec88..c4257d6641 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-deadline.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-deadline.scen.json @@ -61,7 +61,7 @@ "str:ticketHolder|u32:12|str:lottery_name|0x00000000": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -76,7 +76,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-determined-winner.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-determined-winner.scen.json index ad4093baf4..24fd2bd922 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-determined-winner.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-determined-winner.scen.json @@ -52,7 +52,7 @@ "storage": { "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -67,7 +67,7 @@ "str:allowance|address:acc2|sc:lottery": "0", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-sold-out.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-sold-out.scen.json index 2ba3880e43..87138b242a 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-sold-out.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-after-sold-out.scen.json @@ -57,7 +57,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc2": "1" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -72,7 +72,7 @@ "str:allowance|address:acc2|sc:lottery": "0", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-all-options.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-all-options.scen.json index aa53e3b0e1..92a3d063b6 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-all-options.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-all-options.scen.json @@ -59,7 +59,7 @@ "str:ticketHolder|u32:12|str:lottery_name|0x00000000": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -74,7 +74,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-another-account.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-another-account.scen.json index 2dc60a6728..b2a98989fd 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-another-account.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-another-account.scen.json @@ -57,7 +57,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc2": "1" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -72,7 +72,7 @@ "str:allowance|address:acc2|sc:lottery": "0", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-not-on-whitelist.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-not-on-whitelist.scen.json index 9842ac2b57..1d30a31608 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-not-on-whitelist.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-not-on-whitelist.scen.json @@ -71,7 +71,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:1|u8:100|u32:5|u64:123,456|u32:1|u32:2|u8:75|u8:25|u32:3|address:my_address|address:acc1|address:acc2|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -86,7 +86,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-same-account.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-same-account.scen.json index 6cb1dbc6bd..aae36fe803 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-same-account.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-same-account.scen.json @@ -26,7 +26,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" } } }, @@ -80,7 +80,7 @@ "str:ticketHolder|u32:12|str:lottery_name|0x00000001": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "2" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -95,7 +95,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-second-lottery.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-second-lottery.scen.json index 1bd6b68dcd..413a3aaec9 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-second-lottery.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-second-lottery.scen.json @@ -22,7 +22,7 @@ "str:allowance|address:acc2|sc:lottery": "500", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" } } }, @@ -76,7 +76,7 @@ "str:numberOfEntriesForUser|u32:12|str:lottery_$$$$|address:acc1": "1", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -91,7 +91,7 @@ "str:allowance|address:acc2|sc:lottery": "500", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-wrong-fee.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-wrong-fee.scen.json index f814172379..9b82802818 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-wrong-fee.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket-wrong-fee.scen.json @@ -57,7 +57,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:1|u8:100|u32:2|u64:123,456|0xffffffff|u32:1|u8:100|u32:0|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -72,7 +72,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket.scen.json index f325574f2b..1aba3bb501 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/buy-ticket.scen.json @@ -59,7 +59,7 @@ "str:ticketHolder|u32:12|str:lottery_name|0x00000000": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -74,7 +74,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-different-ticket-holders-winner-acc1.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-different-ticket-holders-winner-acc1.scen.json index be7b2b5154..1f88545ca3 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-different-ticket-holders-winner-acc1.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-different-ticket-holders-winner-acc1.scen.json @@ -57,7 +57,7 @@ "storage": { "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -72,7 +72,7 @@ "str:allowance|address:acc2|sc:lottery": "0", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-early.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-early.scen.json index 07ca32d472..2630144d6f 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-early.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-early.scen.json @@ -82,7 +82,7 @@ "str:ticketHolder|u32:12|str:lottery_name|0x00000000": "address:acc1", "str:numberOfEntriesForUser|u32:12|str:lottery_name|address:acc1": "1" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -97,7 +97,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-same-ticket-holder.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-same-ticket-holder.scen.json index 5df68da73f..b9ba9a97b0 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-same-ticket-holder.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-same-ticket-holder.scen.json @@ -58,7 +58,7 @@ "storage": { "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -73,7 +73,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-split-prize-pool.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-split-prize-pool.scen.json index cf11e576ad..057240aa0e 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-split-prize-pool.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/determine-winner-split-prize-pool.scen.json @@ -73,7 +73,7 @@ "storage": { "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -94,7 +94,7 @@ "str:allowance|address:acc5|sc:lottery": "0", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/lottery-init.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/lottery-init.scen.json index d70cbc7388..86755f24a5 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/lottery-init.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/lottery-init.scen.json @@ -40,7 +40,7 @@ "id": "deploy", "tx": { "from": "address:erc20_owner", - "contractCode": "file:../../erc20/output/erc20.wasm", + "contractCode": "mxsc:../../erc20/output/erc20.mxsc.json", "arguments": [ "1,000,000,000" ], @@ -84,7 +84,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" } } }, @@ -93,7 +93,7 @@ "id": "deploy", "tx": { "from": "address:my_address", - "contractCode": "file:../output/lottery-erc20.wasm", + "contractCode": "mxsc:../output/lottery-erc20.mxsc.json", "arguments": [ "sc:erc20" ], @@ -137,7 +137,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "sc:lottery": { "nonce": "0", @@ -145,7 +145,7 @@ "storage": { "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/set_accounts.step.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/set_accounts.step.json index 336e69558e..9189e68076 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/set_accounts.step.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/set_accounts.step.json @@ -17,7 +17,7 @@ "str:allowance|address:acc2|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-after-announced-winner.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-after-announced-winner.scen.json index d5099fefa9..fdb26597bc 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-after-announced-winner.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-after-announced-winner.scen.json @@ -57,7 +57,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:2|u16:1000|u32:200|u64:12345678905|0xffffffff|u32:1|u8:100|u32:0|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -72,7 +72,7 @@ "str:allowance|address:acc2|sc:lottery": "0", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-all-options-bigger-whitelist.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-all-options-bigger-whitelist.scen.json index 4a5a9a01d0..946133dd65 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-all-options-bigger-whitelist.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-all-options-bigger-whitelist.scen.json @@ -66,7 +66,7 @@ "str:allowance|address:acc5|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" } } }, @@ -115,7 +115,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:1|u8:100|u32:5|u64:123,456|u32:1|u32:2|u8:75|u8:25|u32:5|address:acc1|address:acc2|address:acc3|address:acc4|address:acc5|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -136,7 +136,7 @@ "str:allowance|address:acc5|sc:lottery": "100", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" } } } diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-alternative-function-name.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-alternative-function-name.scen.json index 99b9f6a0fa..46aec3f557 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-alternative-function-name.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-alternative-function-name.scen.json @@ -57,7 +57,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:1|u8:100|0xffffffff|u64:2592000|0xffffffff|u32:1|u8:100|u32:0|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -66,7 +66,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-fixed-deadline.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-fixed-deadline.scen.json index 5e9cfd0490..ae7c4bccbd 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-fixed-deadline.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-fixed-deadline.scen.json @@ -57,7 +57,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:1|u8:100|0xffffffff|u64:123,456|0xffffffff|u32:1|u8:100|u32:0|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -66,7 +66,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline-invalid-deadline.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline-invalid-deadline.scen.json index 0cd83bee78..92af03d64f 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline-invalid-deadline.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline-invalid-deadline.scen.json @@ -63,7 +63,7 @@ "storage": { "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -72,7 +72,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline-invalid-ticket-price-arg.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline-invalid-ticket-price-arg.scen.json index f9dd74e661..7369b6102d 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline-invalid-ticket-price-arg.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline-invalid-ticket-price-arg.scen.json @@ -57,7 +57,7 @@ "storage": { "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -66,7 +66,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline.scen.json index d43bc14b1d..1b77fb4c97 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets-and-fixed-deadline.scen.json @@ -57,7 +57,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:1|u8:100|u32:2|u64:123,456|0xffffffff|u32:1|u8:100|u32:0|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -66,7 +66,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets.scen.json index 885d9ef690..d440184874 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-limited-tickets.scen.json @@ -57,7 +57,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:1|u8:100|u32:2|u64:2592000|0xffffffff|u32:1|u8:100|u32:0|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -66,7 +66,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-second-lottery.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-second-lottery.scen.json index b466461039..791b092a91 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-second-lottery.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-second-lottery.scen.json @@ -58,7 +58,7 @@ "str:lotteryInfo|u32:12|str:lottery_$$$$": "u32:2|u16:500|u32:5|u64:234,567|0xffffffff|u32:1|u8:100|u32:0|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -67,7 +67,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-with-all-options.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-with-all-options.scen.json index 272731c298..e07c4b9e1d 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-with-all-options.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-with-all-options.scen.json @@ -57,7 +57,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:1|u8:100|u32:5|u64:123,456|u32:1|u32:2|u8:75|u8:25|u32:3|address:my_address|address:acc1|address:acc2|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -66,7 +66,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", diff --git a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-with-no-options.scen.json b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-with-no-options.scen.json index 13de631c4b..b32fbbe911 100644 --- a/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-with-no-options.scen.json +++ b/contracts/feature-tests/erc-style-contracts/lottery-erc20/scenarios/start-with-no-options.scen.json @@ -57,7 +57,7 @@ "str:lotteryInfo|u32:12|str:lottery_name": "u32:1|u8:100|0xffffffff|u64:2592000|0xffffffff|u32:1|u8:100|u32:0|u32:0|u32:0|u32:0", "str:erc20ContractAddress": "sc:erc20" }, - "code": "file:../output/lottery-erc20.wasm" + "code": "mxsc:../output/lottery-erc20.mxsc.json" }, "sc:erc20": { "nonce": "0", @@ -66,7 +66,7 @@ "str:balance|address:erc20_owner": "1,000,000,000", "str:totalSupply": "1,000,000,000" }, - "code": "file:../../erc20/output/erc20.wasm" + "code": "mxsc:../../erc20/output/erc20.mxsc.json" }, "address:erc20_owner": { "nonce": "1", 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 00b24c22d6..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,16 +2,15 @@ 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( - "file:output/lottery-erc20.wasm", + "mxsc:output/lottery-erc20.mxsc.json", lottery_erc20::ContractBuilder, ); - blockchain.register_contract("file:../erc20/output/erc20.wasm", erc20::ContractBuilder); + blockchain.register_contract( + "mxsc:../erc20/output/erc20.mxsc.json", + erc20::ContractBuilder, + ); blockchain } 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 1010aa90e6..e4d1c6b895 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -51,15 +33,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -68,9 +41,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "lottery-erc20" @@ -90,48 +63,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -147,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -190,26 +158,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -223,27 +180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 79e1e8298d..b41f8f30c4 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 @@ -1,15 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "lottery-erc20-wasm" version = "0.0.0" -authors = [ "Dorin Iancu ",] edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = ["."] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -17,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.lottery-erc20] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../../framework/wasm-adapter" + +[workspace] +members = ["."] 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 ce0717f548..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 4a5f54df23..7adf5bfa39 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 ecb602a879..b58330106d 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/meta/Cargo.toml +++ b/contracts/feature-tests/esdt-system-sc-mock/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.esdt-system-sc-mock] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/esdt_system_sc.scen.json b/contracts/feature-tests/esdt-system-sc-mock/scenarios/esdt_system_sc.scen.json index 1b2fa7de9c..b9a8fcd246 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/scenarios/esdt_system_sc.scen.json +++ b/contracts/feature-tests/esdt-system-sc-mock/scenarios/esdt_system_sc.scen.json @@ -18,7 +18,7 @@ ] } }, - "code": "file:../output/esdt-system-sc-mock.wasm" + "code": "mxsc:../output/esdt-system-sc-mock.mxsc.json" } } }, @@ -96,7 +96,7 @@ "storage": { "str:nrIssuedTokens": "1" }, - "code": "file:../output/esdt-system-sc-mock.wasm" + "code": "mxsc:../output/esdt-system-sc-mock.mxsc.json" } } }, diff --git a/contracts/feature-tests/esdt-system-sc-mock/tests/esdt_system_sc_mock_scenario_go_test.rs b/contracts/feature-tests/esdt-system-sc-mock/tests/esdt_system_sc_mock_scenario_go_test.rs index 522ae1efd4..1566e8633f 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/tests/esdt_system_sc_mock_scenario_go_test.rs +++ b/contracts/feature-tests/esdt-system-sc-mock/tests/esdt_system_sc_mock_scenario_go_test.rs @@ -5,7 +5,6 @@ fn world() -> ScenarioWorld { } #[test] -#[ignore = "builtin SC not implemented"] fn esdt_system_sc_go() { world().run("scenarios/esdt_system_sc.scen.json"); } 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 d6a56289bf..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 @@ -1,11 +1,16 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { - todo!() + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract( + "mxsc:output/esdt-system-sc-mock.mxsc.json", + esdt_system_sc_mock::ContractBuilder, + ); + blockchain } #[test] -#[ignore = "builtin SC not implemented"] fn esdt_system_sc_rs() { world().run("scenarios/esdt_system_sc.scen.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 5c396a891e..f84a770314 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.lock +++ b/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 6bcfd5b662..7bdb57da33 100644 --- a/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.toml +++ b/contracts/feature-tests/esdt-system-sc-mock/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "esdt-system-sc-mock-wasm" version = "0.0.0" -authors = ["Dorin Marian Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.esdt-system-sc-mock] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 69f9df4bf5..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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..c234568a77 --- /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.53.0" +path = "../../../framework/base" + +[dev-dependencies.multiversx-sc-scenario] +version = "0.53.0" +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..47c06b5ab9 --- /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.53.0" +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..9025402dc7 --- /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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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.53.0" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.0" +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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +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..3f446a1fce --- /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.53.0" +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 7ccfbcdbf5..c4ae7e688f 100644 --- a/contracts/feature-tests/formatted-message-features/Cargo.toml +++ b/contracts/feature-tests/formatted-message-features/Cargo.toml @@ -9,9 +9,10 @@ publish = false path = "src/formatted_message_features.rs" [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/base" +features = ["alloc"] [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 a000402366..aa270f41b2 100644 --- a/contracts/feature-tests/formatted-message-features/meta/Cargo.toml +++ b/contracts/feature-tests/formatted-message-features/meta/Cargo.toml @@ -3,13 +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.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/sc-config.toml b/contracts/feature-tests/formatted-message-features/sc-config.toml new file mode 100644 index 0000000000..2c3cbd9828 --- /dev/null +++ b/contracts/feature-tests/formatted-message-features/sc-config.toml @@ -0,0 +1,5 @@ +[settings] +main = "formatted-message-features" + +[contracts.formatted-message-features] +allocator = "static64k" diff --git a/contracts/feature-tests/formatted-message-features/scenarios/managed_error_message.scen.json b/contracts/feature-tests/formatted-message-features/scenarios/managed_error_message.scen.json index 73ea4f4993..b46ba345b5 100644 --- a/contracts/feature-tests/formatted-message-features/scenarios/managed_error_message.scen.json +++ b/contracts/feature-tests/formatted-message-features/scenarios/managed_error_message.scen.json @@ -6,7 +6,7 @@ "sc:msg-features": { "nonce": "0", "balance": "0", - "code": "file:../output/formatted-message-features.wasm" + "code": "mxsc:../output/formatted-message-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/formatted-message-features/scenarios/sc_format.scen.json b/contracts/feature-tests/formatted-message-features/scenarios/sc_format.scen.json index 61b83c5aa2..8309b3b82e 100644 --- a/contracts/feature-tests/formatted-message-features/scenarios/sc_format.scen.json +++ b/contracts/feature-tests/formatted-message-features/scenarios/sc_format.scen.json @@ -6,7 +6,7 @@ "sc:msg-features": { "nonce": "0", "balance": "0", - "code": "file:../output/formatted-message-features.wasm" + "code": "mxsc:../output/formatted-message-features.mxsc.json" }, "address:an_account": { "nonce": "0", diff --git a/contracts/feature-tests/formatted-message-features/src/formatted_message_features.rs b/contracts/feature-tests/formatted-message-features/src/formatted_message_features.rs index 9ecdf8e302..820e27d553 100644 --- a/contracts/feature-tests/formatted-message-features/src/formatted_message_features.rs +++ b/contracts/feature-tests/formatted-message-features/src/formatted_message_features.rs @@ -1,6 +1,6 @@ #![no_std] -multiversx_sc::imports!(); +use multiversx_sc::imports::*; #[multiversx_sc::contract] pub trait FormattedMessageFeatures { @@ -72,6 +72,21 @@ pub trait FormattedMessageFeatures { sc_print!("Printing x: {:c}", x); } + #[endpoint] + fn print_message_bytes(&self, x: &[u8]) { + sc_print!("Printing x: {}", x,); + } + + #[endpoint] + fn print_message_hex_bytes(&self, x: &[u8]) { + sc_print!("Printing x: {:x}", x,); + } + + #[endpoint] + fn print_message_binary_bytes(&self, x: &[u8]) { + sc_print!("Printing x: {:b}", x); + } + #[endpoint] fn format_message_one_part(&self) -> ManagedBuffer { let message = sc_format!("Test"); 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 dc366a6812..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,10 +2,9 @@ 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( - "file:output/formatted-message-features.wasm", + "mxsc:output/formatted-message-features.mxsc.json", formatted_message_features::ContractBuilder, ); diff --git a/contracts/feature-tests/formatted-message-features/tests/msg_test.rs b/contracts/feature-tests/formatted-message-features/tests/msg_test.rs index 10bb5579f7..3c1e6903db 100644 --- a/contracts/feature-tests/formatted-message-features/tests/msg_test.rs +++ b/contracts/feature-tests/formatted-message-features/tests/msg_test.rs @@ -22,6 +22,9 @@ fn test_print_ascii() { fmf.print_message(i32::MIN); check_printed_and_clear("Printing x: -2147483648"); + + fmf.print_message_bytes(b"MVX"); + check_printed_and_clear("Printing x: MVX"); } #[test] @@ -39,6 +42,9 @@ fn test_print_binary() { fmf.print_message_binary(u32::MAX); check_printed_and_clear("Printing x: 11111111111111111111111111111111"); + + fmf.print_message_binary_bytes(b"MVX"); + check_printed_and_clear("Printing x: 010011010101011001011000"); } #[test] @@ -59,6 +65,9 @@ fn test_print_hex() { fmf.print_message_hex(i32::MIN); check_printed_and_clear("Printing x: 80000000"); + + fmf.print_message_hex_bytes(b"MVX"); + check_printed_and_clear("Printing x: 4d5658"); } #[test] diff --git a/contracts/feature-tests/formatted-message-features/wasm/Cargo.lock b/contracts/feature-tests/formatted-message-features/wasm/Cargo.lock index 51c627a65e..c17f9af661 100644 --- a/contracts/feature-tests/formatted-message-features/wasm/Cargo.lock +++ b/contracts/feature-tests/formatted-message-features/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -59,15 +41,6 @@ dependencies = [ "multiversx-sc-wasm-adapter", ] -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -76,54 +49,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 7205ef8122..d053ccbdb6 100644 --- a/contracts/feature-tests/formatted-message-features/wasm/Cargo.toml +++ b/contracts/feature-tests/formatted-message-features/wasm/Cargo.toml @@ -1,17 +1,17 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "formatted-message-features-wasm" version = "0.0.0" -authors = [ "you",] edition = "2021" publish = false [lib] -crate-type = [ "cdylib",] - -[workspace] -members = [ ".",] - -[dev-dependencies] +crate-type = ["cdylib"] [profile.release] codegen-units = 1 @@ -19,10 +19,17 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.formatted-message-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" path = "../../../../framework/wasm-adapter" + +[workspace] +members = ["."] 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 9aab5c626b..c0b17c159f 100644 --- a/contracts/feature-tests/formatted-message-features/wasm/src/lib.rs +++ b/contracts/feature-tests/formatted-message-features/wasm/src/lib.rs @@ -1,21 +1,17 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 16 +// Endpoints: 19 // Async Callback (empty): 1 -// Total number of exported functions: 18 +// Total number of exported functions: 21 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - -multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::allocator!(static64k); multiversx_sc_wasm_adapter::panic_handler!(); multiversx_sc_wasm_adapter::endpoints! { @@ -32,6 +28,9 @@ multiversx_sc_wasm_adapter::endpoints! { print_message_hex => print_message_hex print_message_binary => print_message_binary print_message_codec => print_message_codec + print_message_bytes => print_message_bytes + print_message_hex_bytes => print_message_hex_bytes + print_message_binary_bytes => print_message_binary_bytes format_message_one_part => format_message_one_part format_message_multiple_parts => format_message_multiple_parts format_message_big_int => format_message_big_int diff --git a/contracts/feature-tests/managed-map-features/Cargo.toml b/contracts/feature-tests/managed-map-features/Cargo.toml index a180f8b765..1e15bebcd8 100644 --- a/contracts/feature-tests/managed-map-features/Cargo.toml +++ b/contracts/feature-tests/managed-map-features/Cargo.toml @@ -7,14 +7,13 @@ publish = false [lib] path = "src/mmap_features.rs" + [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/base" -features = ["managed-map"] - [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 0cd5d1226d..96c85128b1 100644 --- a/contracts/feature-tests/managed-map-features/meta/Cargo.toml +++ b/contracts/feature-tests/managed-map-features/meta/Cargo.toml @@ -4,9 +4,11 @@ version = "0.0.0" authors = ["Andrei Marinica "] edition = "2021" publish = false + [dependencies.managed-map-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/mmap_get.scen.json b/contracts/feature-tests/managed-map-features/scenarios/mmap_get.scen.json index bb1c10f4d2..90689c02c4 100644 --- a/contracts/feature-tests/managed-map-features/scenarios/mmap_get.scen.json +++ b/contracts/feature-tests/managed-map-features/scenarios/mmap_get.scen.json @@ -6,7 +6,6 @@ "sc:mmap-features": { "nonce": "0", "balance": "0", - "code": "file:../output/managed-map-features.wasm", "storage": { "str:num_entries": "3", "str:key|u32:0": "str:key0", @@ -15,7 +14,8 @@ "str:value|u32:1": "", "str:key|u32:2": "", "str:value|u32:2": "str:value2" - } + }, + "code": "mxsc:../output/managed-map-features.mxsc.json" }, "address:an-account": { "nonce": "0" diff --git a/contracts/feature-tests/managed-map-features/scenarios/mmap_remove.scen.json b/contracts/feature-tests/managed-map-features/scenarios/mmap_remove.scen.json index f7cab94825..213e51911e 100644 --- a/contracts/feature-tests/managed-map-features/scenarios/mmap_remove.scen.json +++ b/contracts/feature-tests/managed-map-features/scenarios/mmap_remove.scen.json @@ -6,7 +6,6 @@ "sc:mmap-features": { "nonce": "0", "balance": "0", - "code": "file:../output/managed-map-features.wasm", "storage": { "str:num_entries": "4", "str:key|u32:0": "str:key0", @@ -17,7 +16,8 @@ "str:value|u32:2": "str:value2", "str:key|u32:3": "str:key3", "str:value|u32:3": "str:value3" - } + }, + "code": "mxsc:../output/managed-map-features.mxsc.json" }, "address:an-account": { "nonce": "0" 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 89965a21e6..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,9 +2,8 @@ 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( - "file:output/managed-map-features.wasm", + "mxsc:output/managed-map-features.mxsc.json", managed_map_features::ContractBuilder, ); blockchain diff --git a/contracts/feature-tests/managed-map-features/wasm/Cargo.lock b/contracts/feature-tests/managed-map-features/wasm/Cargo.lock index a6d4a1bb1e..4e3cec3ca0 100644 --- a/contracts/feature-tests/managed-map-features/wasm/Cargo.lock +++ b/contracts/feature-tests/managed-map-features/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "managed-map-features" @@ -82,48 +55,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 e22bd1fbcf..fef494d8b5 100644 --- a/contracts/feature-tests/managed-map-features/wasm/Cargo.toml +++ b/contracts/feature-tests/managed-map-features/wasm/Cargo.toml @@ -1,23 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "managed-map-features-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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.managed-map-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 3976e5f8d1..943fc9cb9a 100644 --- a/contracts/feature-tests/managed-map-features/wasm/src/lib.rs +++ b/contracts/feature-tests/managed-map-features/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 4123c9ecf5..21163afcb8 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 dfc9d778a0..cdce31eb9a 100644 --- a/contracts/feature-tests/multi-contract-features/meta/Cargo.toml +++ b/contracts/feature-tests/multi-contract-features/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.multi-contract-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 912c030c26..92d196560c 100644 --- a/contracts/feature-tests/multi-contract-features/multicontract.toml +++ b/contracts/feature-tests/multi-contract-features/multicontract.toml @@ -7,6 +7,23 @@ main = "multi-contract-main" # main contract can have any id and any name name = "multi-contract-features" +# all default values below: +external-view = false +panic-message = false +ei = "1.3" +allocator = "fail" +stack-size = "64k" +features = [] + +[contracts.multi-contract-main.profile] +# these are just the defaults, checking that parsing works fine +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + [contracts.multi-contract-features-view] # name is optional, if missing this ^^^ id will be used external-view = true @@ -14,9 +31,20 @@ 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" +add-unlabelled = false +add-labels = ["alt-impl"] diff --git a/contracts/feature-tests/multi-contract-features/scenarios/mcf-alt-init.scen.json b/contracts/feature-tests/multi-contract-features/scenarios/mcf-alt-init.scen.json index 09737a1ffd..bddd631aeb 100644 --- a/contracts/feature-tests/multi-contract-features/scenarios/mcf-alt-init.scen.json +++ b/contracts/feature-tests/multi-contract-features/scenarios/mcf-alt-init.scen.json @@ -18,13 +18,15 @@ "id": "alt impl deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/multi-contract-alt-impl.wasm", + "contractCode": "mxsc:../output/multi-contract-alt-impl.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" }, "expect": { - "out": [ "str:alternative init" ], + "out": [ + "str:alternative init" + ], "status": "", "logs": [], "gas": "*", @@ -36,10 +38,13 @@ "id": "alt impl query", "tx": { "to": "sc:mcf-alt-impl", - "function": "sample_value" + "function": "sample_value", + "arguments": [] }, "expect": { - "out": [ "str:alternative message instead of sample value" ], + "out": [ + "str:alternative message instead of sample value" + ], "status": "", "logs": [], "gas": "*", diff --git a/contracts/feature-tests/multi-contract-features/scenarios/mcf-example-feature.scen.json b/contracts/feature-tests/multi-contract-features/scenarios/mcf-example-feature.scen.json index 614b40b11b..739a1efd29 100644 --- a/contracts/feature-tests/multi-contract-features/scenarios/mcf-example-feature.scen.json +++ b/contracts/feature-tests/multi-contract-features/scenarios/mcf-example-feature.scen.json @@ -4,10 +4,10 @@ "step": "setState", "accounts": { "sc:mcf": { - "code": "file:../output/multi-contract-features.wasm" + "code": "mxsc:../output/multi-contract-features.mxsc.json" }, "sc:mcf-example-feature": { - "code": "file:../output/multi-contract-example-feature.wasm" + "code": "mxsc:../output/multi-contract-example-feature.mxsc.json" }, "address:owner": {} } @@ -17,7 +17,8 @@ "id": "example_feature_message", "tx": { "to": "sc:mcf-example-feature", - "function": "example_feature_message" + "function": "example_feature_message", + "arguments": [] }, "expect": { "out": [ @@ -30,7 +31,8 @@ "id": "example_feature_message", "tx": { "to": "sc:mcf", - "function": "example_feature_message" + "function": "example_feature_message", + "arguments": [] }, "expect": { "out": [ diff --git a/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-get.scen.json b/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-get.scen.json index 40362f1626..4a7864aed7 100644 --- a/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-get.scen.json +++ b/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-get.scen.json @@ -23,7 +23,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/multi-contract-features.wasm", + "contractCode": "mxsc:../output/multi-contract-features.mxsc.json", "arguments": [ "123" ], @@ -43,7 +43,7 @@ "id": "deploy", "tx": { "from": "address:owner", - "contractCode": "file:../output/multi-contract-features-view.wasm", + "contractCode": "mxsc:../output/multi-contract-features-view.mxsc.json", "arguments": [ "sc:mcf" ], @@ -67,7 +67,7 @@ "storage": { "str:sample-value": "123" }, - "code": "file:../output/multi-contract-features.wasm" + "code": "mxsc:../output/multi-contract-features.mxsc.json" }, "sc:mcf-view": { "nonce": "0", @@ -75,7 +75,7 @@ "storage": { "str:external-view-target-address": "sc:mcf" }, - "code": "file:../output/multi-contract-features-view.wasm" + "code": "mxsc:../output/multi-contract-features-view.mxsc.json" }, "address:owner": { "nonce": "*" @@ -108,7 +108,7 @@ "storage": { "str:sample-value": "123" }, - "code": "file:../output/multi-contract-features.wasm" + "code": "mxsc:../output/multi-contract-features.mxsc.json" }, "sc:mcf-view": { "nonce": "0", @@ -117,7 +117,7 @@ "str:sample-value": "567", "str:external-view-target-address": "sc:mcf" }, - "code": "file:../output/multi-contract-features-view.wasm" + "code": "mxsc:../output/multi-contract-features-view.mxsc.json" }, "address:owner": { "nonce": "*" diff --git a/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-pure.scen.json b/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-pure.scen.json index ec9b98dbd6..a83f1d0150 100644 --- a/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-pure.scen.json +++ b/contracts/feature-tests/multi-contract-features/scenarios/mcf-external-pure.scen.json @@ -6,12 +6,12 @@ "sc:mcf": { "nonce": "0", "balance": "0", - "code": "file:../output/multi-contract-features.wasm" + "code": "mxsc:../output/multi-contract-features.mxsc.json" }, "sc:mcf-view": { "nonce": "0", "balance": "0", - "code": "file:../output/multi-contract-features-view.wasm" + "code": "mxsc:../output/multi-contract-features-view.mxsc.json" }, "address:an-account": { "nonce": "0", 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/src/multi_contract_features.rs b/contracts/feature-tests/multi-contract-features/src/multi_contract_features.rs index 86b34b270a..d337169f9e 100644 --- a/contracts/feature-tests/multi-contract-features/src/multi_contract_features.rs +++ b/contracts/feature-tests/multi-contract-features/src/multi_contract_features.rs @@ -1,5 +1,4 @@ #![no_std] - multiversx_sc::imports!(); #[multiversx_sc::contract] 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 0b086419f7..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,20 +2,19 @@ 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::( - "file:output/multi-contract-features.wasm", + "mxsc:output/multi-contract-features.mxsc.json", multi_contract_features::ContractBuilder, "multi-contract-features", ); blockchain.register_partial_contract::( - "file:output/multi-contract-features-view.wasm", + "mxsc:output/multi-contract-features-view.mxsc.json", multi_contract_features::ContractBuilder, "multi-contract-features-view", ); blockchain.register_partial_contract::( - "file:output/multi-contract-alt-impl.wasm", + "mxsc:output/multi-contract-alt-impl.mxsc.json", multi_contract_features::ContractBuilder, "multi-contract-alt-impl", ); 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 0257408683..407c038093 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multi-contract-alt-impl-wasm" @@ -82,48 +55,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 1a9ac0c4c7..2c8cdbdfa2 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 @@ -1,23 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "multi-contract-alt-impl-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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.multi-contract-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 2c0918a028..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 bcf8fae85b..d83c8f81ea 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multi-contract-example-feature-wasm" @@ -82,48 +55,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 5c84a04128..669e7e5fad 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 @@ -1,24 +1,35 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "multi-contract-example-feature-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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.multi-contract-features] path = ".." features = ["example_feature"] [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 8cfb37b1bf..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 68f03600b5..30b5bd5bce 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multi-contract-features" @@ -82,48 +55,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 59c81ee75f..5aa3aacb18 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 @@ -1,23 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "multi-contract-features-view-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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.multi-contract-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 3fe1350380..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 10cb55cb86..315f2e6c65 100755 --- a/contracts/feature-tests/multi-contract-features/wasm/Cargo.lock +++ b/contracts/feature-tests/multi-contract-features/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,9 +34,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multi-contract-features" @@ -73,7 +46,7 @@ dependencies = [ ] [[package]] -name = "multi-contract-features-custom-cargo-toml-name" +name = "multi-contract-features-wasm" version = "0.0.0" dependencies = [ "multi-contract-features", @@ -82,48 +55,49 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -139,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 b942596c00..97aa191f1c 100644 --- a/contracts/feature-tests/multi-contract-features/wasm/Cargo.toml +++ b/contracts/feature-tests/multi-contract-features/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] -name = "multi-contract-features-custom-cargo-toml-name" +name = "multi-contract-features-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.multi-contract-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 8cfb37b1bf..9602c289bf 100644 --- a/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs +++ b/contracts/feature-tests/multi-contract-features/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 741e4099d3..ecbad46188 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 8cd54e1b05..7641f3072e 100644 --- a/contracts/feature-tests/panic-message-features/meta/Cargo.toml +++ b/contracts/feature-tests/panic-message-features/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.panic-message-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 66803229e3..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 @@ -8,7 +8,7 @@ "sc:panic_features": { "nonce": "0", "balance": "0", - "code": "file:../output/panic-message-features.wasm" + "code": "mxsc:../output/panic-message-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -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", @@ -53,7 +53,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/panic-message-features.wasm" + "code": "mxsc:../output/panic-message-features.mxsc.json" }, "address:an_account": { "nonce": "1", 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 321cae054a..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 @@ -8,7 +8,7 @@ "sc:panic_features": { "nonce": "0", "balance": "0", - "code": "file:../output/panic-message-features.wasm" + "code": "mxsc:../output/panic-message-features.mxsc.json" }, "address:an_account": { "nonce": "0", @@ -32,7 +32,7 @@ "expect": { "out": [], "status": "0x04", - "message": "str:panic occurred: example panic message 123", + "message": "file:error-message.txt", "logs": "*", "gas": "*", "refund": "*" @@ -45,7 +45,7 @@ "nonce": "0", "balance": "0", "storage": {}, - "code": "file:../output/panic-message-features.wasm" + "code": "mxsc:../output/panic-message-features.mxsc.json" }, "address:an_account": { "nonce": "1", 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 35d2d98dc4..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,10 +2,9 @@ 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::( - "file:output/panic-message-features.wasm", + "mxsc:output/panic-message-features.mxsc.json", panic_message_features::ContractBuilder, "panic-message-features", ); @@ -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 e55c203e13..6f74adc48f 100755 --- a/contracts/feature-tests/panic-message-features/wasm/Cargo.lock +++ b/contracts/feature-tests/panic-message-features/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,19 +98,13 @@ 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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "panic-message-features" version = "0.0.0" @@ -154,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 491944c165..a980084e13 100644 --- a/contracts/feature-tests/panic-message-features/wasm/Cargo.toml +++ b/contracts/feature-tests/panic-message-features/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "panic-message-features-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.panic-message-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 5a06957099..b42857cfc0 100644 --- a/contracts/feature-tests/panic-message-features/wasm/src/lib.rs +++ b/contracts/feature-tests/panic-message-features/wasm/src/lib.rs @@ -1,20 +1,16 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 2 +// Endpoints: 3 // Async Callback (empty): 1 -// Total number of exported functions: 4 +// Total number of exported functions: 5 #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![feature(lang_items)] - multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler_with_message!(); @@ -24,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 86f1f74cc0..e5ec427dc5 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" diff --git a/contracts/feature-tests/payable-features/meta/Cargo.toml b/contracts/feature-tests/payable-features/meta/Cargo.toml index 1ac4eb4ea0..8504a5caa9 100644 --- a/contracts/feature-tests/payable-features/meta/Cargo.toml +++ b/contracts/feature-tests/payable-features/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.payable-features] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/scenarios/call-value-check.scen.json b/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json index 3a5f7518dc..23da3773d6 100644 --- a/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/call-value-check.scen.json @@ -6,7 +6,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_any_1.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_any_1.scen.json index 0e4a1a3cc3..615636c669 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_any_1.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_any_1.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_any_2.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_any_2.scen.json index b950201519..8715e5b59a 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_any_2.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_any_2.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_any_3.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_any_3.scen.json index 9992d701a3..8891796a1a 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_any_3.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_any_3.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_any_4.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_any_4.scen.json index 4f4135cb72..2379e769ba 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_any_4.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_any_4.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_egld_1.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_egld_1.scen.json index 86a5aa7511..daa18ca3b0 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_egld_1.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_egld_1.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_egld_2.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_egld_2.scen.json index c56e700ff6..6936d54810 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_egld_2.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_egld_2.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_egld_3.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_egld_3.scen.json index d51b99d4a3..bc72384a81 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_egld_3.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_egld_3.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_egld_4.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_egld_4.scen.json index 36e980274d..da92bf5a59 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_egld_4.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_egld_4.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json index ed0cc1e64f..b05028dfae 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multi_array.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json index 1aa2f812d1..45d92e9fa7 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_multiple.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_token_1.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_token_1.scen.json index bf1d803680..5142e256f3 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_token_1.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_token_1.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_token_2.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_token_2.scen.json index ba1a78358a..2445d41984 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_token_2.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_token_2.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_token_3.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_token_3.scen.json index c6f52443a0..440a6587c9 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_token_3.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_token_3.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", diff --git a/contracts/feature-tests/payable-features/scenarios/payable_token_4.scen.json b/contracts/feature-tests/payable-features/scenarios/payable_token_4.scen.json index d8ef04d237..0397ec9c70 100644 --- a/contracts/feature-tests/payable-features/scenarios/payable_token_4.scen.json +++ b/contracts/feature-tests/payable-features/scenarios/payable_token_4.scen.json @@ -8,7 +8,7 @@ "sc:payable-features": { "nonce": "0", "balance": "0", - "code": "file:../output/payable-features.wasm" + "code": "mxsc:../output/payable-features.mxsc.json" }, "address:an-account": { "nonce": "0", 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 ce8ec7ea25..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 = "file:output/payable-features.wasm"; +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 975f72c72c..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,9 +2,8 @@ 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( - "file:output/payable-features.wasm", + "mxsc:output/payable-features.mxsc.json", payable_features::ContractBuilder, ); blockchain diff --git a/contracts/feature-tests/payable-features/wasm/Cargo.lock b/contracts/feature-tests/payable-features/wasm/Cargo.lock index 1fd95978e7..12cb395c24 100755 --- a/contracts/feature-tests/payable-features/wasm/Cargo.lock +++ b/contracts/feature-tests/payable-features/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,19 +98,13 @@ 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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "payable-features" version = "0.0.0" @@ -154,18 +122,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/feature-tests/payable-features/wasm/Cargo.toml b/contracts/feature-tests/payable-features/wasm/Cargo.toml index 52aa8d09bb..3edbcf28de 100644 --- a/contracts/feature-tests/payable-features/wasm/Cargo.toml +++ b/contracts/feature-tests/payable-features/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "payable-features-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.payable-features] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 702bb4a549..41f085e638 100644 --- a/contracts/feature-tests/payable-features/wasm/src/lib.rs +++ b/contracts/feature-tests/payable-features/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 b1074829f7..c0378047ba 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.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" 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 10b1ae0e46..c5b78a0b39 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.44.0" +version = "0.53.0" 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 0f3958a635..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; @@ -74,7 +61,7 @@ impl State { "bech32:".to_string() + SC_ADDRESS }; let contract_code = BytesValue::interpret_from( - "file:../output/rust-snippets-generator-test.wasm", + "mxsc:../output/rust-snippets-generator-test.mxsc.json", &InterpreterContext::default(), ); let contract = ContractType::new(sc_addr_expr); 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 29bd3df007..c7c55e7ae9 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/meta/Cargo.toml +++ b/contracts/feature-tests/rust-snippets-generator-test/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.rust-snippets-generator-test] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 cbc434df28..6319847030 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/src/lib.rs +++ b/contracts/feature-tests/rust-snippets-generator-test/src/lib.rs @@ -11,9 +11,9 @@ multiversx_sc::derive_imports!(); // cargo run snippets // Add --overwrite if you want to overwrite existing snippets -// Additionally, we also have to update the interact-rs snippets manually to add relative paths: +// Additionally, we also have to update the interactor snippets manually to add relative paths: // [dependencies.multiversx-sc-snippets] -// version = "0.44.0" +// version = "0.53.0" // 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 72302d7658..64372db698 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.lock +++ b/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 f9f4e9e3b1..923f470fe5 100644 --- a/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.toml +++ b/contracts/feature-tests/rust-snippets-generator-test/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "rust-snippets-generator-test-wasm" version = "0.0.0" -authors = ["Dorin Marian Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.rust-snippets-generator-test] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 31443ac81e..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 7e7020f78a..a2d8bbd831 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.44.0" +version = "0.53.0" path = "../../../framework/base" features = [ "alloc" ] @@ -17,11 +17,11 @@ path = "../../examples/adder" path = "../../feature-tests/basic-features" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" [dev-dependencies] -num-bigint = "0.4.2" +num-bigint = "0.4" num-traits = "0.2" hex = "0.4" 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 cbcd320fe2..be2765e077 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/meta/Cargo.toml +++ b/contracts/feature-tests/rust-testing-framework-tester/meta/Cargo.toml @@ -7,6 +7,7 @@ publish = false [dependencies.rust-testing-framework-tester] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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/sc-config.toml b/contracts/feature-tests/rust-testing-framework-tester/sc-config.toml index 330cdda658..b8c5b739dc 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/sc-config.toml +++ b/contracts/feature-tests/rust-testing-framework-tester/sc-config.toml @@ -4,3 +4,8 @@ main = "rust-testing-framework-tester" # the only purpose of this config is to specify the allocator [contracts.rust-testing-framework-tester] allocator = "static64k" + +[[proxy]] +path = "src/rust_testing_framework_tester_proxy.rs" +add-unlabelled = false +add-endpoints = ["init"] diff --git a/contracts/feature-tests/rust-testing-framework-tester/scenarios/test.scen.json b/contracts/feature-tests/rust-testing-framework-tester/scenarios/test.scen.json index 571cfc7225..d92783c9a0 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/scenarios/test.scen.json +++ b/contracts/feature-tests/rust-testing-framework-tester/scenarios/test.scen.json @@ -27,6 +27,7 @@ "str:totalValue": "0x01" }, "code": "file:../output/rust-testing-framework-tester.wasm", + "codeMetadata": "0x0506", "developerRewards": "0" } } @@ -57,8 +58,7 @@ "arguments": [ "0x32" ], - "gasLimit": "100000000", - "gasPrice": "0" + "gasLimit": "100000000" }, "expect": { "out": [], diff --git a/contracts/feature-tests/rust-testing-framework-tester/scenarios/test_esdt_generation.scen.json b/contracts/feature-tests/rust-testing-framework-tester/scenarios/test_esdt_generation.scen.json index 293b6b9c74..d211c85067 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/scenarios/test_esdt_generation.scen.json +++ b/contracts/feature-tests/rust-testing-framework-tester/scenarios/test_esdt_generation.scen.json @@ -13,7 +13,7 @@ "step": "setState", "accounts": { "0x00000000000000006c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925": { - "nonce": "0", + "nonce": "1", "balance": "0", "esdt": { "str:COOL-123456": { @@ -28,6 +28,7 @@ } }, "code": "file:../output/rust-testing-framework-tester.wasm", + "codeMetadata": "0x0506", "developerRewards": "0" } } diff --git a/contracts/feature-tests/rust-testing-framework-tester/src/dummy_module.rs b/contracts/feature-tests/rust-testing-framework-tester/src/dummy_module.rs index 76721a8fc4..7db5c9379d 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/src/dummy_module.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/src/dummy_module.rs @@ -1,5 +1,3 @@ -multiversx_sc::imports!(); - #[multiversx_sc::module] pub trait DummyModule { fn some_function(&self) -> BigUint { 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..ffc411dad0 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/src/lib.rs @@ -1,11 +1,12 @@ #![no_std] -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use multiversx_sc::proxy_imports::*; pub mod dummy_module; +pub mod rust_testing_framework_tester_proxy; -#[derive(TopEncode, TopDecode, TypeAbi, Clone, Debug, PartialEq, Eq)] +#[type_abi] +#[derive(TopEncode, TopDecode, Clone, Debug, PartialEq, Eq)] pub struct NftDummyAttributes { pub creation_epoch: u64, pub cool_factor: u8, @@ -20,7 +21,7 @@ pub struct StructWithManagedTypes { pub trait RustTestingFrameworkTester: dummy_module::DummyModule { #[init] fn init(&self) -> ManagedBuffer { - self.total_value().set(&BigUint::from(1u32)); + self.total_value().set(BigUint::from(1u32)); b"constructor-result".into() } @@ -62,14 +63,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 +83,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 +107,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 +171,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 +188,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 +207,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/src/rust_testing_framework_tester_proxy.rs b/contracts/feature-tests/rust-testing-framework-tester/src/rust_testing_framework_tester_proxy.rs new file mode 100644 index 0000000000..6a42d7e5b3 --- /dev/null +++ b/contracts/feature-tests/rust-testing-framework-tester/src/rust_testing_framework_tester_proxy.rs @@ -0,0 +1,61 @@ +// 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 RustTestingFrameworkTesterProxy; + +impl TxProxyTrait for RustTestingFrameworkTesterProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = RustTestingFrameworkTesterProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + RustTestingFrameworkTesterProxyMethods { wrapped_tx: tx } + } +} + +pub struct RustTestingFrameworkTesterProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl RustTestingFrameworkTesterProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy> { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode, Clone, Debug, PartialEq, Eq)] +pub struct NftDummyAttributes { + pub creation_epoch: u64, + pub cool_factor: u8, +} diff --git a/contracts/feature-tests/rust-testing-framework-tester/tests/rust_testing_framework_tester_scenario_go_test.rs b/contracts/feature-tests/rust-testing-framework-tester/tests/rust_testing_framework_tester_scenario_go_test.rs index 76adbba8ce..ec1d6b3799 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/tests/rust_testing_framework_tester_scenario_go_test.rs +++ b/contracts/feature-tests/rust-testing-framework-tester/tests/rust_testing_framework_tester_scenario_go_test.rs @@ -5,16 +5,19 @@ fn world() -> ScenarioWorld { } #[test] +#[ignore] fn test_go() { world().run("scenarios/test.scen.json"); } #[test] +#[ignore] fn test_esdt_generation_go() { world().run("scenarios/test_esdt_generation.scen.json"); } #[test] +#[ignore] fn test_multiple_sc_go() { world().run("scenarios/test_multiple_sc.scen.json"); } 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..e5bfcc2def 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, @@ -13,16 +10,19 @@ fn world() -> ScenarioWorld { } #[test] +#[ignore] fn test_rs() { world().run("scenarios/test.scen.json"); } #[test] +#[ignore] fn test_esdt_generation_rs() { world().run("scenarios/test_esdt_generation.scen.json"); } #[test] +#[ignore] fn test_multiple_sc_rs() { world().run("scenarios/test_multiple_sc.scen.json"); } 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 a53f1aa83b..a426721718 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,78 +1,50 @@ -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 = "file:output/rust-testing-framework-tester.wasm"; +const CODE_PATH: MxscPath = MxscPath::new("output/rust-testing-framework-tester.mxsc.json"); +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const RUST_TESTING_FRAMEWORK_TESTER_ADDRESS: TestSCAddress = + TestSCAddress::new("rust-testing-framework-tester"); fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain - .set_current_dir_from_workspace("contracts/feature_tests/rust-testing-framework-tester"); + blockchain.register_contract(CODE_PATH, rust_testing_framework_tester::ContractBuilder); - blockchain.register_contract( - WASM_PATH_EXPR, - rust_testing_framework_tester::ContractBuilder, - ); blockchain } #[test] fn tester_deploy_test() { let mut world = world(); - let code = world.code_expression(WASM_PATH_EXPR); - let owner_address = "address:owner"; - let mut adder_contract = - ContractInfo::>::new("sc:contract"); + world.start_trace(); + + world.account(OWNER_ADDRESS).new_address( + OWNER_ADDRESS, + 0, + RUST_TESTING_FRAMEWORK_TESTER_ADDRESS, + ); - world - .start_trace() - .set_state_step( - SetStateStep::new() - .put_account(owner_address, Account::new()) - .new_address(owner_address, 0, &adder_contract), - ) - .sc_deploy_use_result( - ScDeployStep::new() - .from(owner_address) - .code(code) - .call(adder_contract.init()), - |address, tr: TypedResponse| { - assert_eq!(address, adder_contract.to_address()); - assert_eq!(tr.result.unwrap(), "constructor-result"); - }, - ) - .write_scenario_trace("scenarios/trace-deploy.scen.json"); + let (returned_value, contract_address) = world + .tx() + .from(OWNER_ADDRESS) + .typed(rust_testing_framework_tester_proxy::RustTestingFrameworkTesterProxy) + .init() + .code(CODE_PATH) + .returns(ReturnsResult) + .new_address(RUST_TESTING_FRAMEWORK_TESTER_ADDRESS) + .returns(ReturnsNewAddress) + .run(); + + assert_eq!(returned_value.to_string(), "constructor-result"); + assert_eq!(contract_address, RUST_TESTING_FRAMEWORK_TESTER_ADDRESS); + + world.write_scenario_trace("scenarios/trace-deploy.scen.json"); } #[test] fn tester_deploy_test_spawned_thread() { - let handler = std::thread::spawn(|| { - let mut world = world(); - let code = world.code_expression(WASM_PATH_EXPR); - - let owner_address = "address:owner"; - let mut adder_contract = - ContractInfo::>::new("sc:contract"); - - world - .start_trace() - .set_state_step( - SetStateStep::new() - .put_account(owner_address, Account::new()) - .new_address(owner_address, 0, &adder_contract), - ) - .sc_deploy_use_result( - ScDeployStep::new() - .from(owner_address) - .code(code) - .call(adder_contract.init()), - |address, tr: TypedResponse| { - assert_eq!(address, adder_contract.to_address()); - assert_eq!(tr.result.unwrap(), "constructor-result"); - }, - ) - .write_scenario_trace("scenarios/trace-deploy.scen.json"); - }); + let handler = std::thread::spawn(tester_deploy_test); handler.join().unwrap(); } 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..a502523505 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"; @@ -305,6 +294,7 @@ fn test_esdt_balance() { }) .assert_ok(); + wrapper.add_mandos_set_account(sc_wrapper.address_ref()); wrapper.add_mandos_check_account(sc_wrapper.address_ref()); wrapper.write_mandos_output(TEST_ESDT_OUTPUT_PATH); } 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 0679ad2e0d..e4fe0b45f2 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.lock +++ b/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,54 +34,55 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -124,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -182,26 +150,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -215,27 +172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" +name = "unwrap-infallible" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] +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 60c36b69ba..111c090390 100644 --- a/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.toml +++ b/contracts/feature-tests/rust-testing-framework-tester/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "rust-testing-framework-tester-wasm" version = "0.0.0" -authors = ["Dorin Iancu "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.rust-testing-framework-tester] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 2e106ce4a3..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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..58f97682f3 --- /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.53.0" +path = "../../../framework/base" + +[dev-dependencies.multiversx-sc-scenario] +version = "0.53.0" +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..2c850459ec --- /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.53.0" +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 73% 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 1e3301f335..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 = "file:output/adder.wasm"; +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("file:output/adder.wasm", 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_deprecated_test.rs b/contracts/feature-tests/scenario-tester/tests/st_whitebox_deprecated_test.rs new file mode 100644 index 0000000000..e67fd8cacf --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_whitebox_deprecated_test.rs @@ -0,0 +1,54 @@ +#![allow(deprecated)] + +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/tests/st_whitebox_test.rs b/contracts/feature-tests/scenario-tester/tests/st_whitebox_test.rs new file mode 100644 index 0000000000..61dd6cdc2d --- /dev/null +++ b/contracts/feature-tests/scenario-tester/tests/st_whitebox_test.rs @@ -0,0 +1,54 @@ +use multiversx_sc_scenario::imports::*; +use scenario_tester::*; + +const ST_PATH_EXPR: MxscPath = MxscPath::new("mxsc:output/scenario-tester.mxsc.json"); +const OWNER: TestAddress = TestAddress::new("owner"); +const SCENARIO_TESTER: TestSCAddress = TestSCAddress::new("scenario-tester"); + +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(); + + world.account(OWNER).nonce(1); + + let new_address = world + .tx() + .from(OWNER) + .raw_deploy() + .code(ST_PATH_EXPR) + .new_address(SCENARIO_TESTER) + .returns(ReturnsNewBech32Address) + .whitebox(scenario_tester::contract_obj, |sc| { + sc.init(BigUint::from(5u64)); + }); + + assert_eq!(new_address.to_address(), SCENARIO_TESTER.to_address()); + + world + .query() + .to(SCENARIO_TESTER) + .whitebox(scenario_tester::contract_obj, |sc| { + let sum_value = sc.sum(); + assert_eq!(sum_value.get(), BigUint::from(5u32)); + }); + + world + .tx() + .from(OWNER) + .to(SCENARIO_TESTER) + .whitebox(scenario_tester::contract_obj, |sc| sc.add(3u32.into())); + + world + .check_account(SCENARIO_TESTER) + .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..cb15a21d75 --- /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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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.53.0" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.0" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.0" +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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +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..c6f1c3743c --- /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.53.0" +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 bfbcc29793..d32b9b8140 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.44.0" +version = "0.53.0" path = "../../../contracts/modules" [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/base" [dev-dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "0.53.0" path = "../../../framework/scenario" -[dev-dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../framework/meta" +[dev-dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 a3296948b4..627498902b 100644 --- a/contracts/feature-tests/use-module/meta/Cargo.toml +++ b/contracts/feature-tests/use-module/meta/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies.use-module] path = ".." -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "0.53.0" +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 bfe4d784c4..0000000000 --- a/contracts/feature-tests/use-module/meta/abi/Cargo.toml +++ /dev/null @@ -1,17 +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.44.0" -path = "../../../../framework/base" - -[dependencies.multiversx-sc-meta] -version = "0.44.0" -path = "../../../../framework/meta" 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_claim_developer_rewards.scen.json b/contracts/feature-tests/use-module/scenarios/use_module_claim_developer_rewards.scen.json index 0d816749fa..ab080331e2 100644 --- a/contracts/feature-tests/use-module/scenarios/use_module_claim_developer_rewards.scen.json +++ b/contracts/feature-tests/use-module/scenarios/use_module_claim_developer_rewards.scen.json @@ -26,7 +26,7 @@ "id": "1", "tx": { "from": "address:owner", - "contractCode": "file:../output/use-module.wasm", + "contractCode": "mxsc:../output/use-module.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" @@ -44,14 +44,14 @@ "accounts": { "sc:child": { "balance": "500", + "code": "mxsc:../../composability/vault/output/vault.mxsc.json", "owner": "sc:use_module", - "code": "file:../../composability/vault/output/vault.wasm", "developerRewards": "100" }, "sc:not_child": { "balance": "500", - "owner": "sc:not_owner", - "code": "file:../../composability/vault/output/vault.wasm" + "code": "mxsc:../../composability/vault/output/vault.mxsc.json", + "owner": "sc:not_owner" } } }, @@ -102,7 +102,7 @@ "accounts": { "sc:use_module": { "balance": "100", - "code": "file:../output/use-module.wasm", + "code": "mxsc:../output/use-module.mxsc.json", "owner": "address:owner" }, "address:not_owner": { @@ -115,14 +115,14 @@ }, "sc:child": { "balance": "500", + "code": "mxsc:../../composability/vault/output/vault.mxsc.json", "owner": "sc:use_module", - "code": "file:../../composability/vault/output/vault.wasm", "developerRewards": "0" }, "sc:not_child": { "balance": "500", - "owner": "sc:not_owner", - "code": "file:../../composability/vault/output/vault.wasm" + "code": "mxsc:../../composability/vault/output/vault.mxsc.json", + "owner": "sc:not_owner" } } } diff --git a/contracts/feature-tests/use-module/scenarios/use_module_dns_register.scen.json b/contracts/feature-tests/use-module/scenarios/use_module_dns_register.scen.json index 34c9f18414..2a5698fe03 100644 --- a/contracts/feature-tests/use-module/scenarios/use_module_dns_register.scen.json +++ b/contracts/feature-tests/use-module/scenarios/use_module_dns_register.scen.json @@ -11,7 +11,7 @@ "sc:use_module": { "nonce": "0", "balance": "0", - "code": "file:../output/use-module.wasm", + "code": "mxsc:../output/use-module.mxsc.json", "owner": "address:a_user" }, "sc:dns#87": { @@ -20,7 +20,7 @@ "storage": { "str:registration_cost": "1000" }, - "code": "file:../test-wasm/elrond-wasm-sc-dns.wasm" + "code": "mxsc:../test-wasm/elrond-wasm-sc-dns.mxsc.json" } } }, @@ -55,7 +55,7 @@ "balance": "*", "username": "str:coolname0001.elrond", "storage": {}, - "code": "file:../output/use-module.wasm" + "code": "mxsc:../output/use-module.mxsc.json" }, "+": "" } diff --git a/contracts/feature-tests/use-module/scenarios/use_module_features.scen.json b/contracts/feature-tests/use-module/scenarios/use_module_features.scen.json index e18549ea0e..e58c23eb2c 100644 --- a/contracts/feature-tests/use-module/scenarios/use_module_features.scen.json +++ b/contracts/feature-tests/use-module/scenarios/use_module_features.scen.json @@ -22,7 +22,7 @@ "id": "1", "tx": { "from": "address:owner", - "contractCode": "file:../output/use-module.wasm", + "contractCode": "mxsc:../output/use-module.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/feature-tests/use-module/scenarios/use_module_internal.scen.json b/contracts/feature-tests/use-module/scenarios/use_module_internal.scen.json index 29ce30882c..b61c3d72dc 100644 --- a/contracts/feature-tests/use-module/scenarios/use_module_internal.scen.json +++ b/contracts/feature-tests/use-module/scenarios/use_module_internal.scen.json @@ -22,7 +22,7 @@ "id": "1", "tx": { "from": "address:owner", - "contractCode": "file:../output/use-module.wasm", + "contractCode": "mxsc:../output/use-module.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/feature-tests/use-module/scenarios/use_module_no_endpoint.scen.json b/contracts/feature-tests/use-module/scenarios/use_module_no_endpoint.scen.json index 2e87aed861..f23f88dad2 100644 --- a/contracts/feature-tests/use-module/scenarios/use_module_no_endpoint.scen.json +++ b/contracts/feature-tests/use-module/scenarios/use_module_no_endpoint.scen.json @@ -5,7 +5,7 @@ "accounts": { "address:a_user": {}, "sc:forwarder": { - "code": "file:../output/use-module.wasm" + "code": "mxsc:../output/use-module.mxsc.json" } } }, 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 081b761a5d..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 @@ -5,7 +5,7 @@ "accounts": { "address:a_user": {}, "sc:use_module": { - "code": "file:../output/use-module.wasm" + "code": "mxsc:../output/use-module.mxsc.json" } } }, @@ -39,7 +39,7 @@ "storage": { "str:ongoing_operation:currentOngoingOperation": "" }, - "code": "file:../output/use-module.wasm" + "code": "mxsc:../output/use-module.mxsc.json" }, "+": "" } @@ -52,7 +52,7 @@ "to": "sc:use_module", "function": "countTo100", "arguments": [], - "gasLimit": "5,350,000", + "gasLimit": "4,700,000", "gasPrice": "0" }, "expect": { @@ -74,7 +74,7 @@ "storage": { "str:ongoing_operation:currentOngoingOperation": "1" }, - "code": "file:../output/use-module.wasm" + "code": "mxsc:../output/use-module.mxsc.json" }, "+": "" } @@ -109,7 +109,7 @@ "storage": { "str:ongoing_operation:currentOngoingOperation": "" }, - "code": "file:../output/use-module.wasm" + "code": "mxsc:../output/use-module.mxsc.json" }, "+": "" } diff --git a/contracts/feature-tests/use-module/scenarios/use_module_only_admin.scen.json b/contracts/feature-tests/use-module/scenarios/use_module_only_admin.scen.json index a731da0444..afa152fcb2 100644 --- a/contracts/feature-tests/use-module/scenarios/use_module_only_admin.scen.json +++ b/contracts/feature-tests/use-module/scenarios/use_module_only_admin.scen.json @@ -30,7 +30,7 @@ "id": "1", "tx": { "from": "address:owner", - "contractCode": "file:../output/use-module.wasm", + "contractCode": "mxsc:../output/use-module.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/feature-tests/use-module/scenarios/use_module_only_owner.scen.json b/contracts/feature-tests/use-module/scenarios/use_module_only_owner.scen.json index 602a6db542..0f9c586a30 100644 --- a/contracts/feature-tests/use-module/scenarios/use_module_only_owner.scen.json +++ b/contracts/feature-tests/use-module/scenarios/use_module_only_owner.scen.json @@ -26,7 +26,7 @@ "id": "1", "tx": { "from": "address:owner", - "contractCode": "file:../output/use-module.wasm", + "contractCode": "mxsc:../output/use-module.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" diff --git a/contracts/feature-tests/use-module/scenarios/use_module_pause.scen.json b/contracts/feature-tests/use-module/scenarios/use_module_pause.scen.json index 12db43f84c..bd8a21bc44 100644 --- a/contracts/feature-tests/use-module/scenarios/use_module_pause.scen.json +++ b/contracts/feature-tests/use-module/scenarios/use_module_pause.scen.json @@ -22,7 +22,7 @@ "id": "1", "tx": { "from": "address:owner", - "contractCode": "file:../output/use-module.wasm", + "contractCode": "mxsc:../output/use-module.mxsc.json", "arguments": [], "gasLimit": "20,000,000", "gasPrice": "0" @@ -70,7 +70,7 @@ "expect": { "out": [], "status": "", - "logs": [], + "logs": "*", "gas": "*", "refund": "*" } @@ -110,7 +110,7 @@ "expect": { "out": [], "status": "", - "logs": [], + "logs": "*", "gas": "*", "refund": "*" } @@ -137,4 +137,4 @@ } } ] -} +} \ No newline at end of file diff --git a/contracts/feature-tests/use-module/src/use_module.rs b/contracts/feature-tests/use-module/src/use_module.rs index 7cd54c9ec3..64d2e32c16 100644 --- a/contracts/feature-tests/use-module/src/use_module.rs +++ b/contracts/feature-tests/use-module/src/use_module.rs @@ -63,7 +63,7 @@ pub trait UseModule: } #[endpoint(checkPause)] - fn check_pause(&self) -> SCResult { - Ok(self.is_paused()) + fn check_pause(&self) -> bool { + self.is_paused() } } 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 23c7eb8dec..800797024b 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,18 +1,10 @@ -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"; +const GOV_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("GOV-123456"); const QUORUM: u64 = 1_500; const MIN_BALANCE_PROPOSAL: u64 = 500; const VOTING_DELAY_BLOCKS: u64 = 10; @@ -22,13 +14,13 @@ const LOCKING_PERIOD_BLOCKS: u64 = 30; const INITIAL_GOV_TOKEN_BALANCE: u64 = 1_000; const GAS_LIMIT: u64 = 1_000_000; -const USE_MODULE_ADDRESS_EXPR: &str = "sc:use-module"; -const USE_MODULE_PATH_EXPR: &str = "file:output/use-module.wasm"; +const USE_MODULE_ADDRESS: TestSCAddress = TestSCAddress::new("use-module"); +const USE_MODULE_PATH_EXPR: MxscPath = MxscPath::new("mxsc:output/use-module.mxsc.json"); -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const FIRST_USER_ADDRESS_EXPR: &str = "address:first-user"; -const SECOND_USER_ADDRESS_EXPR: &str = "address:second-user"; -const THIRD_USER_ADDRESS_EXPR: &str = "address:third-user"; +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const FIRST_USER_ADDRESS: TestAddress = TestAddress::new("first-user"); +const SECOND_USER_ADDRESS: TestAddress = TestAddress::new("second-user"); +const THIRD_USER_ADDRESS: TestAddress = TestAddress::new("third-user"); pub struct Payment { pub token: Vec, @@ -38,7 +30,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 @@ -47,58 +38,45 @@ fn world() -> ScenarioWorld { fn setup() -> ScenarioWorld { let mut world = world(); - world.set_state_step( - SetStateStep::new() - .put_account( - OWNER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(GOV_TOKEN_ID_EXPR, INITIAL_GOV_TOKEN_BALANCE), - ) - .new_address(OWNER_ADDRESS_EXPR, 1, USE_MODULE_ADDRESS_EXPR) - .put_account( - FIRST_USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(GOV_TOKEN_ID_EXPR, INITIAL_GOV_TOKEN_BALANCE), - ) - .put_account( - SECOND_USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(GOV_TOKEN_ID_EXPR, INITIAL_GOV_TOKEN_BALANCE), - ) - .put_account( - THIRD_USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(GOV_TOKEN_ID_EXPR, INITIAL_GOV_TOKEN_BALANCE), - ), - ); + world + .account(OWNER_ADDRESS) + .nonce(1) + .esdt_balance(GOV_TOKEN_ID, INITIAL_GOV_TOKEN_BALANCE); + world + .account(FIRST_USER_ADDRESS) + .nonce(1) + .esdt_balance(GOV_TOKEN_ID, INITIAL_GOV_TOKEN_BALANCE); + world + .account(SECOND_USER_ADDRESS) + .nonce(1) + .esdt_balance(GOV_TOKEN_ID, INITIAL_GOV_TOKEN_BALANCE); + world + .account(THIRD_USER_ADDRESS) + .nonce(1) + .esdt_balance(GOV_TOKEN_ID, INITIAL_GOV_TOKEN_BALANCE); // init - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); - let use_module_code = world.code_expression(USE_MODULE_PATH_EXPR); - - world.whitebox_deploy( - &use_module_whitebox, - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(use_module_code), - |sc| { + let new_address = world + .tx() + .from(OWNER_ADDRESS) + .raw_deploy() + .code(USE_MODULE_PATH_EXPR) + .new_address(USE_MODULE_ADDRESS) + .returns(ReturnsNewBech32Address) + .whitebox(use_module::contract_obj, |sc| { sc.init_governance_module( - managed_token_id!(GOV_TOKEN_ID), - managed_biguint!(QUORUM), - managed_biguint!(MIN_BALANCE_PROPOSAL), + TokenIdentifier::from(GOV_TOKEN_ID), + BigUint::from(QUORUM), + BigUint::from(MIN_BALANCE_PROPOSAL), VOTING_DELAY_BLOCKS, VOTING_PERIOD_BLOCKS, LOCKING_PERIOD_BLOCKS, ); - }, - ); + }); - world.set_state_step(SetStateStep::new().block_nonce(10)); + assert_eq!(new_address.to_address(), USE_MODULE_ADDRESS.to_address()); + + world.current_block().block_nonce(10); world } @@ -111,17 +89,14 @@ pub fn propose( endpoint_name: &[u8], args: Vec>, ) -> usize { - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); - let mut proposal_id = 0; - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(proposer) - .esdt_transfer(GOV_TOKEN_ID, 0, gov_token_amount), - |sc| { + world + .tx() + .from(proposer) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, gov_token_amount)) + .whitebox(use_module::contract_obj, |sc| { let mut args_managed = ManagedVec::new(); for arg in args { args_managed.push(managed_buffer!(&arg)); @@ -139,8 +114,7 @@ pub fn propose( ); proposal_id = sc.propose(managed_buffer!(b"change quorum"), actions); - }, - ); + }); proposal_id } @@ -153,16 +127,14 @@ fn test_init() { #[test] fn test_change_gov_config() { let mut world = setup(); - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); let mut current_block_nonce = 10; let proposal_id = propose( &mut world, - &address_expr_to_address(FIRST_USER_ADDRESS_EXPR), + &FIRST_USER_ADDRESS.to_address(), 500, - &address_expr_to_address(USE_MODULE_ADDRESS_EXPR), + &USE_MODULE_ADDRESS.to_address(), b"changeQuorum", vec![1_000u64.to_be_bytes().to_vec()], ); @@ -170,209 +142,188 @@ fn test_change_gov_config() { assert_eq!(proposal_id, 1); // vote too early - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new() - .from(SECOND_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "999") - .no_expect(), - |sc| { + world + .tx() + .from(SECOND_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 999)) + .returns(ExpectError(4u64, "Proposal is not active")) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::UpVote); - }, - |r| { - r.assert_user_error("Proposal is not active"); - }, - ); + }); current_block_nonce += VOTING_DELAY_BLOCKS; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(SECOND_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "999"), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(SECOND_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 999)) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::UpVote); - }, - ); + }); // try execute before queue - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Can only execute queued proposals")) + .whitebox(use_module::contract_obj, |sc| { sc.execute(proposal_id); - }, - |r| { - r.assert_user_error("Can only execute queued proposals"); - }, - ); + }); // try queue before voting ends - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Can only queue succeeded proposals")) + .whitebox(use_module::contract_obj, |sc| { sc.queue(proposal_id); - }, - |r| { - r.assert_user_error("Can only queue succeeded proposals"); - }, - ); + }); current_block_nonce += VOTING_PERIOD_BLOCKS; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); + world.current_block().block_nonce(current_block_nonce); // try queue not enough votes - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Can only queue succeeded proposals")) + .whitebox(use_module::contract_obj, |sc| { sc.queue(proposal_id); - }, - |r| { - r.assert_user_error("Can only queue succeeded proposals"); - }, - ); + }); // user 1 vote again current_block_nonce = 20; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(FIRST_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "200"), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 200)) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::UpVote); - }, - ); + }); // owner downvote - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(OWNER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "200"), - |sc| { + world + .tx() + .from(OWNER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 200)) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::DownVote); - }, - ); + }); // try queue too many downvotes current_block_nonce = 45; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Can only queue succeeded proposals")) + .whitebox(use_module::contract_obj, |sc| { sc.queue(proposal_id); - }, - |r| { - r.assert_user_error("Can only queue succeeded proposals"); - }, - ); + }); // user 1 vote again current_block_nonce = 20; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new() - .from(FIRST_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "200") - .no_expect(), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 200)) + .returns(ExpectError(4u64, "Already voted for this proposal")) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::UpVote); - }, - |r| { - r.assert_user_error("Already voted for this proposal"); - }, - ); + }); // user 3 vote again - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(THIRD_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "200"), - |sc| { + world + .tx() + .from(THIRD_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 200)) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::UpVote); - }, - ); + }); // queue ok current_block_nonce = 45; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { sc.queue(proposal_id); - }, - ); + }); // try execute too early - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { - sc.execute(proposal_id); - }, - |r| { - r.assert_user_error("Proposal is in timelock status. Try again later"); - }, - ); + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError( + 4u64, + "Proposal is in timelock status. Try again later", + )) + .whitebox(use_module::contract_obj, |sc| sc.execute(proposal_id)); // execute ok current_block_nonce += LOCKING_PERIOD_BLOCKS; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { - sc.execute(proposal_id); - }, - ); + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| sc.execute(proposal_id)); // after execution, quorum changed from 1_500 to the proposed 1_000 - world.whitebox_query(&use_module_whitebox, |sc| { - assert_eq!(sc.quorum().get(), managed_biguint!(1_000)); - assert!(sc.proposals().item_is_empty(1)); - }); - - world.check_state_step(CheckStateStep::new().put_account( - FIRST_USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "300"), - )); - world.check_state_step(CheckStateStep::new().put_account( - SECOND_USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "1"), - )); - world.check_state_step(CheckStateStep::new().put_account( - THIRD_USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "800"), - )); - world.check_state_step(CheckStateStep::new().put_account( - OWNER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "800"), - )); + world + .query() + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + assert_eq!(sc.quorum().get(), managed_biguint!(1_000)); + assert!(sc.proposals().item_is_empty(1)); + }); + + world + .check_account(FIRST_USER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::from(300u64)); + world + .check_account(SECOND_USER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::from(1u64)); + world + .check_account(THIRD_USER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::from(800u64)); + world + .check_account(OWNER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::from(800u64)); } #[test] fn test_down_veto_gov_config() { let mut world = setup(); - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); let mut current_block_nonce = 10; let proposal_id = propose( &mut world, - &address_expr_to_address(FIRST_USER_ADDRESS_EXPR), + &FIRST_USER_ADDRESS.to_address(), 500, - &address_expr_to_address(USE_MODULE_ADDRESS_EXPR), + &USE_MODULE_ADDRESS.to_address(), b"changeQuorum", vec![1_000u64.to_be_bytes().to_vec()], ); @@ -380,81 +331,75 @@ fn test_down_veto_gov_config() { assert_eq!(proposal_id, 1); current_block_nonce += VOTING_DELAY_BLOCKS; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(FIRST_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "300"), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 300)) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::UpVote); - }, - ); + }); current_block_nonce = 20; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(SECOND_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "200"), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(SECOND_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 200)) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::UpVote); - }, - ); + }); - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(THIRD_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "200"), - |sc| { - sc.vote(proposal_id, VoteType::DownVetoVote); - }, - ); + world + .tx() + .from(THIRD_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 200)) + .whitebox(use_module::contract_obj, |sc| { + sc.vote(proposal_id, VoteType::DownVetoVote) + }); // Vote didn't succeed; current_block_nonce = 45; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { + world.current_block().block_epoch(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Can only queue succeeded proposals")) + .whitebox(use_module::contract_obj, |sc| { sc.queue(proposal_id); - }, - |r| { - r.assert_user_error("Can only queue succeeded proposals"); - }, - ); + }); + + world + .check_account(FIRST_USER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::from(200u64)); - world.check_state_step(CheckStateStep::new().put_account( - FIRST_USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "200"), - )); - world.check_state_step(CheckStateStep::new().put_account( - SECOND_USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "800"), - )); - world.check_state_step(CheckStateStep::new().put_account( - THIRD_USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "800"), - )); + world + .check_account(SECOND_USER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::from(800u64)); + + world + .check_account(THIRD_USER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::from(800u64)); } #[test] fn test_abstain_vote_gov_config() { let mut world = setup(); - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); let mut current_block_nonce = 10; let proposal_id = propose( &mut world, - &address_expr_to_address(FIRST_USER_ADDRESS_EXPR), + &FIRST_USER_ADDRESS.to_address(), 500, - &address_expr_to_address(USE_MODULE_ADDRESS_EXPR), + &USE_MODULE_ADDRESS.to_address(), b"changeQuorum", vec![1_000u64.to_be_bytes().to_vec()], ); @@ -462,95 +407,93 @@ fn test_abstain_vote_gov_config() { assert_eq!(proposal_id, 1); current_block_nonce += VOTING_DELAY_BLOCKS; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(FIRST_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "500"), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 500)) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::UpVote); - }, - ); + }); current_block_nonce = 20; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(SECOND_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "400"), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(SECOND_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 400)) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::DownVote); - }, - ); + }); - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(THIRD_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "600"), - |sc| { + world + .tx() + .from(THIRD_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 600)) + .whitebox(use_module::contract_obj, |sc| { sc.vote(proposal_id, VoteType::AbstainVote); - }, - ); + }); // Vote didn't succeed; current_block_nonce = 45; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { sc.queue(proposal_id); - }, - ); + }); // execute ok current_block_nonce += LOCKING_PERIOD_BLOCKS; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(FIRST_USER_ADDRESS_EXPR).no_expect(), - |sc| { + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(FIRST_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { sc.execute(proposal_id); - }, - ); + }); // after execution, quorum changed from 1_500 to the proposed 1_000 - world.whitebox_query(&use_module_whitebox, |sc| { - assert_eq!(sc.quorum().get(), managed_biguint!(1_000)); - assert!(sc.proposals().item_is_empty(1)); - }); - - world.check_state_step(CheckStateStep::new().put_account( - FIRST_USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "0"), - )); - world.check_state_step(CheckStateStep::new().put_account( - SECOND_USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "600"), - )); - world.check_state_step(CheckStateStep::new().put_account( - THIRD_USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(GOV_TOKEN_ID_EXPR, "400"), - )); + world + .query() + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + assert_eq!(sc.quorum().get(), managed_biguint!(1_000)); + assert!(sc.proposals().item_is_empty(1)); + }); + + world + .check_account(FIRST_USER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::zero()); + world + .check_account(SECOND_USER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::from(600u64)); + world + .check_account(THIRD_USER_ADDRESS) + .esdt_balance(GOV_TOKEN_ID, BigUint::from(400u64)); } #[test] fn test_gov_cancel_defeated_proposal() { let mut world = setup(); - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); let mut current_block_nonce = 10; let proposal_id = propose( &mut world, - &address_expr_to_address(FIRST_USER_ADDRESS_EXPR), + &FIRST_USER_ADDRESS.to_address(), 500, - &address_expr_to_address(USE_MODULE_ADDRESS_EXPR), + &USE_MODULE_ADDRESS.to_address(), b"changeQuorum", vec![1_000u64.to_be_bytes().to_vec()], ); @@ -558,42 +501,33 @@ fn test_gov_cancel_defeated_proposal() { assert_eq!(proposal_id, 1); current_block_nonce += VOTING_DELAY_BLOCKS; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(SECOND_USER_ADDRESS_EXPR) - .esdt_transfer(GOV_TOKEN_ID, 0, "999"), - |sc| { - sc.vote(proposal_id, VoteType::DownVote); - }, - ); + world.current_block().block_nonce(current_block_nonce); + + world + .tx() + .from(SECOND_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(GOV_TOKEN_ID, 0, 999)) + .whitebox(use_module::contract_obj, |sc| { + sc.vote(proposal_id, VoteType::DownVote) + }); // try cancel too early - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(SECOND_USER_ADDRESS_EXPR).no_expect(), - |sc| { + world + .tx() + .from(SECOND_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Action may not be cancelled")) + .whitebox(use_module::contract_obj, |sc| { sc.cancel(proposal_id); - }, - |r| { - r.assert_user_error("Action may not be cancelled"); - }, - ); + }); current_block_nonce += VOTING_PERIOD_BLOCKS; - world.set_state_step(SetStateStep::new().block_nonce(current_block_nonce)); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(SECOND_USER_ADDRESS_EXPR).no_expect(), - |sc| { - sc.cancel(proposal_id); - }, - ); -} + world.current_block().block_nonce(current_block_nonce); -fn address_expr_to_address(address_expr: &str) -> Address { - AddressValue::from(address_expr).to_address() + world + .tx() + .from(SECOND_USER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| sc.cancel(proposal_id)); } 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 14ee01cc0f..643387b634 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,34 +1,25 @@ -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, -}; - -const STAKING_TOKEN_ID_EXPR: &str = "str:STAKE-123456"; -const STAKING_TOKEN_ID: &[u8] = b"STAKE-123456"; +use multiversx_sc_scenario::imports::*; + +const STAKING_TOKEN_ID: TestTokenIdentifier = TestTokenIdentifier::new("STAKE-123456"); const INITIAL_BALANCE: u64 = 2_000_000; const REQUIRED_STAKE_AMOUNT: u64 = 1_000_000; const SLASH_AMOUNT: u64 = 600_000; const QUORUM: usize = 3; -const OWNER_ADDRESS_EXPR: &str = "address:owner"; -const ALICE_ADDRESS_EXPR: &str = "address:alice"; -const BOB_ADDRESS_EXPR: &str = "address:bob"; -const CAROL_ADDRESS_EXPR: &str = "address:carol"; -const EVE_ADDRESS_EXPR: &str = "address:eve"; -const PAUL_ADDRESS_EXPR: &str = "address:paul"; -const SALLY_ADDRESS_EXPR: &str = "address:sally"; +const OWNER_ADDRESS: TestAddress = TestAddress::new("owner"); +const ALICE_ADDRESS: TestAddress = TestAddress::new("alice"); +const BOB_ADDRESS: TestAddress = TestAddress::new("bob"); +const CAROL_ADDRESS: TestAddress = TestAddress::new("carol"); +const EVE_ADDRESS: TestAddress = TestAddress::new("eve"); +const PAUL_ADDRESS: TestAddress = TestAddress::new("paul"); +const SALLY_ADDRESS: TestAddress = TestAddress::new("sally"); -const USE_MODULE_ADDRESS_EXPR: &str = "sc:use-module"; -const USE_MODULE_PATH_EXPR: &str = "file:output/use-module.wasm"; +const USE_MODULE_ADDRESS: TestSCAddress = TestSCAddress::new("use-module"); +const USE_MODULE_PATH_EXPR: MxscPath = MxscPath::new("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 @@ -38,447 +29,339 @@ fn world() -> ScenarioWorld { fn test_staking_module() { 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, USE_MODULE_ADDRESS_EXPR) - .put_account( - ALICE_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(STAKING_TOKEN_ID_EXPR, INITIAL_BALANCE), - ) - .put_account( - BOB_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(STAKING_TOKEN_ID_EXPR, INITIAL_BALANCE), - ) - .put_account( - CAROL_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(STAKING_TOKEN_ID_EXPR, INITIAL_BALANCE), - ) - .put_account( - EVE_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(STAKING_TOKEN_ID_EXPR, INITIAL_BALANCE), - ) - .put_account( - PAUL_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(STAKING_TOKEN_ID_EXPR, INITIAL_BALANCE), - ) - .put_account( - SALLY_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(STAKING_TOKEN_ID_EXPR, INITIAL_BALANCE), - ), - ); + world.account(OWNER_ADDRESS).nonce(1); + world + .account(ALICE_ADDRESS) + .nonce(1) + .esdt_balance(STAKING_TOKEN_ID, INITIAL_BALANCE); + world + .account(BOB_ADDRESS) + .nonce(1) + .esdt_balance(STAKING_TOKEN_ID, INITIAL_BALANCE); + world + .account(CAROL_ADDRESS) + .nonce(1) + .esdt_balance(STAKING_TOKEN_ID, INITIAL_BALANCE); + world + .account(EVE_ADDRESS) + .nonce(1) + .esdt_balance(STAKING_TOKEN_ID, INITIAL_BALANCE); + world + .account(PAUL_ADDRESS) + .nonce(1) + .esdt_balance(STAKING_TOKEN_ID, INITIAL_BALANCE); + world + .account(SALLY_ADDRESS) + .nonce(1) + .esdt_balance(STAKING_TOKEN_ID, INITIAL_BALANCE); // init - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); - let use_module_code = world.code_expression(USE_MODULE_PATH_EXPR); - - world.whitebox_deploy( - &use_module_whitebox, - ScDeployStep::new() - .from(OWNER_ADDRESS_EXPR) - .code(use_module_code), - |sc| { + let new_address = world + .tx() + .from(OWNER_ADDRESS) + .raw_deploy() + .code(USE_MODULE_PATH_EXPR) + .new_address(USE_MODULE_ADDRESS) + .returns(ReturnsNewBech32Address) + .whitebox(use_module::contract_obj, |sc| { let mut whitelist = ManagedVec::new(); - whitelist.push(managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))); - whitelist.push(managed_address!(&address_expr_to_address(BOB_ADDRESS_EXPR))); - whitelist.push(managed_address!(&address_expr_to_address( - CAROL_ADDRESS_EXPR - ))); - whitelist.push(managed_address!(&address_expr_to_address( - PAUL_ADDRESS_EXPR - ))); - whitelist.push(managed_address!(&address_expr_to_address( - SALLY_ADDRESS_EXPR - ))); + whitelist.push(ALICE_ADDRESS.to_managed_address()); + whitelist.push(BOB_ADDRESS.to_managed_address()); + whitelist.push(CAROL_ADDRESS.to_managed_address()); + whitelist.push(PAUL_ADDRESS.to_managed_address()); + whitelist.push(SALLY_ADDRESS.to_managed_address()); sc.init_staking_module( - &EgldOrEsdtTokenIdentifier::esdt(managed_token_id!(STAKING_TOKEN_ID)), - &managed_biguint!(REQUIRED_STAKE_AMOUNT), - &managed_biguint!(SLASH_AMOUNT), + &EgldOrEsdtTokenIdentifier::esdt(STAKING_TOKEN_ID.to_token_identifier()), + &BigUint::from(REQUIRED_STAKE_AMOUNT), + &BigUint::from(SLASH_AMOUNT), QUORUM, &whitelist, ); - }, - ); + }); + + assert_eq!(new_address.to_address(), USE_MODULE_ADDRESS.to_address()); // try stake - not a board member - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new() - .from(EVE_ADDRESS_EXPR) - .esdt_transfer(STAKING_TOKEN_ID, 0, REQUIRED_STAKE_AMOUNT) - .no_expect(), - |sc| sc.stake(), - |r| { - r.assert_user_error("Only whitelisted members can stake"); - }, - ); + world + .tx() + .from(EVE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(STAKING_TOKEN_ID, 0, REQUIRED_STAKE_AMOUNT)) + .returns(ExpectError(4u64, "Only whitelisted members can stake")) + .whitebox(use_module::contract_obj, |sc| { + sc.stake(); + }); // stake half and try unstake - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR).esdt_transfer( + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer( STAKING_TOKEN_ID, 0, REQUIRED_STAKE_AMOUNT / 2, - ), - |sc| sc.stake(), - ); - - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR).no_expect(), - |sc| sc.unstake(managed_biguint!(REQUIRED_STAKE_AMOUNT / 4)), - |r| { - r.assert_user_error("Not enough stake"); - }, - ); + )) + .whitebox(use_module::contract_obj, |sc| { + sc.stake(); + }); + + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Not enough stake")) + .whitebox(use_module::contract_obj, |sc| { + sc.unstake(BigUint::from(REQUIRED_STAKE_AMOUNT / 4)); + }); // bob and carol stake - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(BOB_ADDRESS_EXPR).esdt_transfer( - STAKING_TOKEN_ID, - 0, - REQUIRED_STAKE_AMOUNT, - ), - |sc| sc.stake(), - ); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(CAROL_ADDRESS_EXPR).esdt_transfer( - STAKING_TOKEN_ID, - 0, - REQUIRED_STAKE_AMOUNT, - ), - |sc| sc.stake(), - ); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(PAUL_ADDRESS_EXPR).esdt_transfer( - STAKING_TOKEN_ID, - 0, - REQUIRED_STAKE_AMOUNT, - ), - |sc| sc.stake(), - ); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(SALLY_ADDRESS_EXPR).esdt_transfer( - STAKING_TOKEN_ID, - 0, - REQUIRED_STAKE_AMOUNT, - ), - |sc| sc.stake(), - ); + world + .tx() + .from(BOB_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(STAKING_TOKEN_ID, 0, REQUIRED_STAKE_AMOUNT)) + .whitebox(use_module::contract_obj, |sc| { + sc.stake(); + }); + + world + .tx() + .from(CAROL_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(STAKING_TOKEN_ID, 0, REQUIRED_STAKE_AMOUNT)) + .whitebox(use_module::contract_obj, |sc| { + sc.stake(); + }); + + world + .tx() + .from(PAUL_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(STAKING_TOKEN_ID, 0, REQUIRED_STAKE_AMOUNT)) + .whitebox(use_module::contract_obj, |sc| { + sc.stake(); + }); + + world + .tx() + .from(SALLY_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(STAKING_TOKEN_ID, 0, REQUIRED_STAKE_AMOUNT)) + .whitebox(use_module::contract_obj, |sc| { + sc.stake(); + }); // try vote slash, not enough stake - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR).no_expect(), - |sc| sc.vote_slash_member(managed_address!(&address_expr_to_address(BOB_ADDRESS_EXPR))), - |r| { - r.assert_user_error("Not enough stake"); - }, - ); + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Not enough stake")) + .whitebox(use_module::contract_obj, |sc| { + sc.vote_slash_member(BOB_ADDRESS.to_managed_address()); + }); // try vote slash, slashed address not a board member - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR).no_expect(), - |sc| sc.vote_slash_member(managed_address!(&address_expr_to_address(EVE_ADDRESS_EXPR))), - |r| { - r.assert_user_error("Voted user is not a staked board member"); - }, - ); + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Voted user is not a staked board member")) + .whitebox(use_module::contract_obj, |sc| { + sc.vote_slash_member(EVE_ADDRESS.to_managed_address()); + }); // alice stake over max amount and withdraw surplus - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR).esdt_transfer( - STAKING_TOKEN_ID, - 0, - REQUIRED_STAKE_AMOUNT, - ), - |sc| { + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .payment(TestEsdtTransfer(STAKING_TOKEN_ID, 0, REQUIRED_STAKE_AMOUNT)) + .whitebox(use_module::contract_obj, |sc| { sc.stake(); - let alice_staked_amount = sc - .staked_amount(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))) - .get(); - assert_eq!(alice_staked_amount, managed_biguint!(1_500_000)); - }, - ); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR), - |sc| { - sc.unstake(managed_biguint!(500_000)); - - let alice_staked_amount = sc - .staked_amount(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))) - .get(); - assert_eq!(alice_staked_amount, managed_biguint!(1_000_000)); - }, - ); - - world.check_state_step(CheckStateStep::new().put_account( - ALICE_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(STAKING_TOKEN_ID_EXPR, "1_000_000"), - )); + let alice_staked_amount = sc.staked_amount(&ALICE_ADDRESS.to_managed_address()).get(); + assert_eq!(alice_staked_amount, BigUint::from(1_500_000u64)); + }); + + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + sc.unstake(BigUint::from(500_000u64)); + let alice_staked_amount = sc.staked_amount(&ALICE_ADDRESS.to_managed_address()).get(); + assert_eq!(alice_staked_amount, BigUint::from(1_000_000u64)); + }); + + world + .check_account(ALICE_ADDRESS) + .esdt_balance(STAKING_TOKEN_ID, BigUint::from(1_000_000u64)); // alice vote to slash bob - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR), - |sc| { - sc.vote_slash_member(managed_address!(&address_expr_to_address(BOB_ADDRESS_EXPR))); + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + sc.vote_slash_member(BOB_ADDRESS.to_managed_address()); assert_eq!( - sc.slashing_proposal_voters(&managed_address!(&address_expr_to_address( - BOB_ADDRESS_EXPR - ))) - .len(), + sc.slashing_proposal_voters(&BOB_ADDRESS.to_managed_address()) + .len(), 1 ); assert!(sc - .slashing_proposal_voters(&managed_address!(&address_expr_to_address( - BOB_ADDRESS_EXPR - ))) - .contains(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - )))); - }, - ); + .slashing_proposal_voters(&BOB_ADDRESS.to_managed_address()) + .contains(&ALICE_ADDRESS.to_managed_address())); + }); // bob vote to slash alice - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(BOB_ADDRESS_EXPR), - |sc| { - sc.vote_slash_member(managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))); - }, - ); + world + .tx() + .from(BOB_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + sc.vote_slash_member(ALICE_ADDRESS.to_managed_address()); + }); // try slash before quorum reached - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(BOB_ADDRESS_EXPR).no_expect(), - |sc| { - sc.slash_member(managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))); - }, - |r| { - r.assert_user_error("Quorum not reached"); - }, - ); + world + .tx() + .from(BOB_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Quorum not reached")) + .whitebox(use_module::contract_obj, |sc| { + sc.slash_member(ALICE_ADDRESS.to_managed_address()); + }); // paul vote to slash alice - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(PAUL_ADDRESS_EXPR), - |sc| { - sc.vote_slash_member(managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))); - }, - ); + world + .tx() + .from(PAUL_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + sc.vote_slash_member(ALICE_ADDRESS.to_managed_address()); + }); // sally vote to slash alice - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(SALLY_ADDRESS_EXPR), - |sc| { - sc.vote_slash_member(managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))); - }, - ); + world + .tx() + .from(SALLY_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + sc.vote_slash_member(ALICE_ADDRESS.to_managed_address()); + }); // sally cancels vote to slash alice - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(SALLY_ADDRESS_EXPR), - |sc| { - sc.cancel_vote_slash_member(managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))); - }, - ); + world + .tx() + .from(SALLY_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + sc.cancel_vote_slash_member(ALICE_ADDRESS.to_managed_address()); + }); // carol vote - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(CAROL_ADDRESS_EXPR), - |sc| { - sc.vote_slash_member(managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))); + world + .tx() + .from(CAROL_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + sc.vote_slash_member(ALICE_ADDRESS.to_managed_address()); assert_eq!( - sc.slashing_proposal_voters(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))) - .len(), + sc.slashing_proposal_voters(&ALICE_ADDRESS.to_managed_address()) + .len(), 3 ); assert!(sc - .slashing_proposal_voters(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))) - .contains(&managed_address!(&address_expr_to_address( - BOB_ADDRESS_EXPR - )))); + .slashing_proposal_voters(&ALICE_ADDRESS.to_managed_address()) + .contains(&BOB_ADDRESS.to_managed_address())); assert!(sc - .slashing_proposal_voters(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))) - .contains(&managed_address!(&address_expr_to_address( - CAROL_ADDRESS_EXPR - )))); + .slashing_proposal_voters(&ALICE_ADDRESS.to_managed_address()) + .contains(&CAROL_ADDRESS.to_managed_address())); assert!(sc - .slashing_proposal_voters(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))) - .contains(&managed_address!(&address_expr_to_address( - PAUL_ADDRESS_EXPR - )))); + .slashing_proposal_voters(&ALICE_ADDRESS.to_managed_address()) + .contains(&PAUL_ADDRESS.to_managed_address())); assert!(!sc - .slashing_proposal_voters(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))) - .contains(&managed_address!(&address_expr_to_address( - SALLY_ADDRESS_EXPR - )))); - }, - ); + .slashing_proposal_voters(&ALICE_ADDRESS.to_managed_address()) + .contains(&SALLY_ADDRESS.to_managed_address())); + }); // slash alice - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(BOB_ADDRESS_EXPR), - |sc| { - sc.slash_member(managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))); + world + .tx() + .from(BOB_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + sc.slash_member(ALICE_ADDRESS.to_managed_address()); assert_eq!( - sc.staked_amount(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))) - .get(), - managed_biguint!(REQUIRED_STAKE_AMOUNT - SLASH_AMOUNT) - ); - assert_eq!( - sc.total_slashed_amount().get(), - managed_biguint!(SLASH_AMOUNT) + sc.staked_amount(&ALICE_ADDRESS.to_managed_address()).get(), + BigUint::from(REQUIRED_STAKE_AMOUNT - SLASH_AMOUNT) ); + assert_eq!(sc.total_slashed_amount().get(), BigUint::from(SLASH_AMOUNT)); assert!(sc - .slashing_proposal_voters(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))) + .slashing_proposal_voters(&ALICE_ADDRESS.to_managed_address()) .is_empty()); - }, - ); + }); // alice try vote after slash - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR).no_expect(), - |sc| { - sc.vote_slash_member(managed_address!(&address_expr_to_address(BOB_ADDRESS_EXPR))); - }, - |r| { - r.assert_user_error("Not enough stake"); - }, - ); + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Not enough stake")) + .whitebox(use_module::contract_obj, |sc| { + sc.vote_slash_member(BOB_ADDRESS.to_managed_address()); + }); // alice try unstake the remaining tokens - world.whitebox_call_check( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR).no_expect(), - |sc| { - sc.unstake(managed_biguint!(400_000)); - }, - |r| { - r.assert_user_error("Not enough stake"); - }, - ); + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .returns(ExpectError(4u64, "Not enough stake")) + .whitebox(use_module::contract_obj, |sc| { + sc.unstake(BigUint::from(400_000u64)); + }); // alice remove from board members - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| { + world + .tx() + .from(OWNER_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { // check alice's votes before slash assert!(sc - .slashing_proposal_voters(&managed_address!(&address_expr_to_address( - BOB_ADDRESS_EXPR - ))) - .contains(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - )))); + .slashing_proposal_voters(&BOB_ADDRESS.to_managed_address()) + .contains(&ALICE_ADDRESS.to_managed_address())); - sc.remove_board_member(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - ))); + sc.remove_board_member(&ALICE_ADDRESS.to_managed_address()); assert_eq!(sc.user_whitelist().len(), 4); assert!(!sc .user_whitelist() - .contains(&managed_address!(&address_expr_to_address( - ALICE_ADDRESS_EXPR - )))); + .contains(&ALICE_ADDRESS.to_managed_address())); // alice's vote gets removed assert!(sc - .slashing_proposal_voters(&managed_address!(&address_expr_to_address( - BOB_ADDRESS_EXPR - ))) + .slashing_proposal_voters(&BOB_ADDRESS.to_managed_address()) .is_empty()); - }, - ); + }); // alice unstake ok - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(ALICE_ADDRESS_EXPR), - |sc| { - sc.unstake(managed_biguint!(400_000)); - }, - ); - - world.check_state_step(CheckStateStep::new().put_account( - ALICE_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(STAKING_TOKEN_ID_EXPR, INITIAL_BALANCE - SLASH_AMOUNT), - )); -} - -fn address_expr_to_address(address_expr: &str) -> Address { - AddressValue::from(address_expr).to_address() + world + .tx() + .from(ALICE_ADDRESS) + .to(USE_MODULE_ADDRESS) + .whitebox(use_module::contract_obj, |sc| { + sc.unstake(BigUint::from(400_000u64)); + }); + + world + .check_account(ALICE_ADDRESS) + .esdt_balance(STAKING_TOKEN_ID, INITIAL_BALANCE - SLASH_AMOUNT); } 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 7831b75732..4b40f656c9 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,34 +1,19 @@ -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"; -const USER_ADDRESS_EXPR: &str = "address:user"; +const OWNER_ADDRESS_EXPR: TestAddress = TestAddress::new("owner"); +const USER_ADDRESS_EXPR: TestAddress = TestAddress::new("user"); -const USE_MODULE_ADDRESS_EXPR: &str = "sc:use-module"; -const USE_MODULE_PATH_EXPR: &str = "file:output/use-module.wasm"; +const USE_MODULE_ADDRESS_EXPR: TestSCAddress = TestSCAddress::new("use-module"); +const USE_MODULE_PATH_EXPR: MxscPath = MxscPath::new("mxsc:output/use-module.mxsc.json"); -const MERGED_TOKEN_ID_EXPR: &str = "str:MERGED-123456"; -const MERGED_TOKEN_ID: &[u8] = b"MERGED-123456"; -const NFT_TOKEN_ID_EXPR: &str = "str:NFT-123456"; -const NFT_TOKEN_ID: &[u8] = b"NFT-123456"; -const FUNGIBLE_TOKEN_ID_EXPR: &str = "str:FUN-123456"; -const FUNGIBLE_TOKEN_ID: &[u8] = b"FUN-123456"; +const MERGED_TOKEN_ID_EXPR: TestTokenIdentifier = TestTokenIdentifier::new("MERGED-123456"); +const NFT_TOKEN_ID_EXPR: TestTokenIdentifier = TestTokenIdentifier::new("NFT-123456"); +const FUNGIBLE_TOKEN_ID_EXPR: TestTokenIdentifier = TestTokenIdentifier::new("FUN-123456"); const NFT_AMOUNT: u64 = 1; const FUNGIBLE_AMOUNT: u64 = 100; @@ -45,8 +30,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 } @@ -55,561 +38,465 @@ fn world() -> ScenarioWorld { fn test_token_merge() { let mut world = world(); - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); - let use_module_code = world.code_expression(USE_MODULE_PATH_EXPR); - let roles = vec![ "ESDTRoleNFTCreate".to_string(), "ESDTRoleNFTBurn".to_string(), ]; - - world.set_state_step( - SetStateStep::new() - .put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .put_account( - USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(FUNGIBLE_TOKEN_ID_EXPR, FUNGIBLE_AMOUNT) - .esdt_nft_all_properties( - NFT_TOKEN_ID_EXPR, - FIRST_NFT_NONCE, - NFT_AMOUNT, - Some(FIRST_ATTRIBUTES), - FIRST_ROYALTIES, - None, - None, - Vec::from(FIRST_URIS), - ) - .esdt_nft_all_properties( - NFT_TOKEN_ID_EXPR, - SECOND_NFT_NONCE, - NFT_AMOUNT, - Some(SECOND_ATTRIBUTES), - SECOND_ROYALTIES, - None, - None, - Vec::from(SECOND_URIS), - ), - ) - .put_account( - USE_MODULE_ADDRESS_EXPR, - Account::new() - .nonce(1) - .code(use_module_code) - .owner(OWNER_ADDRESS_EXPR) - .esdt_roles(MERGED_TOKEN_ID_EXPR, roles), - ), - ); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| { + let first_uris = FIRST_URIS + .iter() + .map(|first_uri| managed_buffer!(first_uri)) + .collect(); + let second_uris = SECOND_URIS + .iter() + .map(|second_uri| managed_buffer!(second_uri)) + .collect(); + + world.account(OWNER_ADDRESS_EXPR).nonce(1); + world + .account(USER_ADDRESS_EXPR) + .nonce(1) + .esdt_balance(FUNGIBLE_TOKEN_ID_EXPR, FUNGIBLE_AMOUNT) + .esdt_nft_all_properties( + NFT_TOKEN_ID_EXPR, + FIRST_NFT_NONCE, + NFT_AMOUNT, + managed_buffer!(FIRST_ATTRIBUTES), + FIRST_ROYALTIES, + None::
, + (), + first_uris, + ) + .esdt_nft_all_properties( + NFT_TOKEN_ID_EXPR, + SECOND_NFT_NONCE, + NFT_AMOUNT, + managed_buffer!(SECOND_ATTRIBUTES), + SECOND_ROYALTIES, + None::
, + (), + second_uris, + ); + + world + .account(USE_MODULE_ADDRESS_EXPR) + .nonce(1) + .code(USE_MODULE_PATH_EXPR) + .owner(OWNER_ADDRESS_EXPR) + .esdt_roles(MERGED_TOKEN_ID_EXPR, roles); + + world + .tx() + .from(OWNER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .whitebox(use_module::contract_obj, |sc| { sc.merged_token() - .set_token_id(managed_token_id!(MERGED_TOKEN_ID)); + .set_token_id(MERGED_TOKEN_ID_EXPR.to_token_identifier()); let _ = sc .mergeable_tokens_whitelist() - .insert(managed_token_id!(NFT_TOKEN_ID)); + .insert(NFT_TOKEN_ID_EXPR.to_token_identifier()); let _ = sc .mergeable_tokens_whitelist() - .insert(managed_token_id!(FUNGIBLE_TOKEN_ID)); - }, - ); + .insert(FUNGIBLE_TOKEN_ID_EXPR.to_token_identifier()); + }); // merge two NFTs let nft_transfers = vec![ - TxESDT { - esdt_token_identifier: NFT_TOKEN_ID.into(), - nonce: FIRST_NFT_NONCE.into(), - esdt_value: NFT_AMOUNT.into(), - }, - TxESDT { - esdt_token_identifier: NFT_TOKEN_ID.into(), - nonce: SECOND_NFT_NONCE.into(), - esdt_value: NFT_AMOUNT.into(), - }, + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT), + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT), ]; - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .multi_esdt_transfer(nft_transfers), - |sc| { + world + .tx() + .from(USER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .multi_esdt(nft_transfers) + .whitebox(use_module::contract_obj, |sc| { let merged_token = sc.merge_tokens_endpoint(); assert_eq!( merged_token.token_identifier, - managed_token_id!(MERGED_TOKEN_ID) + MERGED_TOKEN_ID_EXPR.to_token_identifier() ); assert_eq!(merged_token.token_nonce, 1); assert_eq!(merged_token.amount, managed_biguint!(NFT_AMOUNT)); let merged_token_data = sc.blockchain().get_esdt_token_data( - &managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), - &managed_token_id!(MERGED_TOKEN_ID), + &USER_ADDRESS_EXPR.to_managed_address(), + &MERGED_TOKEN_ID_EXPR.to_token_identifier(), 1, ); - let mut expected_uri = ArrayVec::new(); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - FIRST_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - SECOND_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); + let expected_uri = ArrayVec::from([ + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + FIRST_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + SECOND_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + ]); let actual_uri = MergedTokenInstances::decode_from_first_uri(&merged_token_data.uris); - assert_eq!(expected_uri, actual_uri.into_instances()); + assert_eq!(expected_uri, *actual_uri.into_instances()); assert_eq!( merged_token_data.royalties, managed_biguint!(SECOND_ROYALTIES) ); - }, - ); - - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( - MERGED_TOKEN_ID_EXPR, - 1, - NFT_AMOUNT, - Option::<&Empty>::None, - ), - )); + }); + + world + .check_account(USER_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes(MERGED_TOKEN_ID_EXPR, 1, NFT_AMOUNT, &Empty); - world.check_state_step(CheckStateStep::new().put_account( - USE_MODULE_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( + world + .check_account(USE_MODULE_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes( NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT, - Some(FIRST_ATTRIBUTES), - ), - )); + FIRST_ATTRIBUTES, + ); - world.check_state_step(CheckStateStep::new().put_account( - USE_MODULE_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( + world + .check_account(USE_MODULE_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes( NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT, - Some(SECOND_ATTRIBUTES), - ), - )); + SECOND_ATTRIBUTES, + ); // split nfts - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(USER_ADDRESS_EXPR).esdt_transfer( - MERGED_TOKEN_ID_EXPR, - 1, - NFT_AMOUNT, - ), - |sc| { + world + .tx() + .from(USER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .payment(TestEsdtTransfer(MERGED_TOKEN_ID_EXPR, 1, NFT_AMOUNT)) + .whitebox(use_module::contract_obj, |sc| { let output_tokens = sc.split_tokens_endpoint(); - let mut expected_output_tokens = ManagedVec::new(); - expected_output_tokens.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - FIRST_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - expected_output_tokens.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - SECOND_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - assert_eq!(output_tokens, expected_output_tokens); - }, - ); - - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( + let expected_output_tokens = vec![ + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT), + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT), + ]; + assert_eq!(output_tokens, expected_output_tokens.into()); + }); + + world + .check_account(USER_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes( NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT, - Some(FIRST_ATTRIBUTES), - ), - )); + FIRST_ATTRIBUTES, + ); - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( + world + .check_account(USER_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes( NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT, - Some(SECOND_ATTRIBUTES), - ), - )); + SECOND_ATTRIBUTES, + ); // merge the NFT with fungible let esdt_transfers = vec![ - TxESDT { - esdt_token_identifier: NFT_TOKEN_ID.into(), - nonce: FIRST_NFT_NONCE.into(), - esdt_value: NFT_AMOUNT.into(), - }, - TxESDT { - esdt_token_identifier: FUNGIBLE_TOKEN_ID.into(), - nonce: 0u64.into(), - esdt_value: FUNGIBLE_AMOUNT.into(), - }, + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT), + TestEsdtTransfer(FUNGIBLE_TOKEN_ID_EXPR, 0u64, FUNGIBLE_AMOUNT), ]; - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .multi_esdt_transfer(esdt_transfers), - |sc| { + world + .tx() + .from(USER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .multi_esdt(esdt_transfers) + .whitebox(use_module::contract_obj, |sc| { let merged_token = sc.merge_tokens_endpoint(); assert_eq!( merged_token.token_identifier, - managed_token_id!(MERGED_TOKEN_ID) + MERGED_TOKEN_ID_EXPR.to_token_identifier() ); assert_eq!(merged_token.token_nonce, 2); assert_eq!(merged_token.amount, managed_biguint!(NFT_AMOUNT)); let merged_token_data = sc.blockchain().get_esdt_token_data( - &managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), - &managed_token_id!(MERGED_TOKEN_ID), + &USER_ADDRESS_EXPR.to_managed_address(), + &MERGED_TOKEN_ID_EXPR.to_token_identifier(), 2, ); - let mut expected_uri = ArrayVec::new(); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - FIRST_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(FUNGIBLE_TOKEN_ID), - 0, - managed_biguint!(FUNGIBLE_AMOUNT), - )); + let expected_uri = ArrayVec::from([ + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + FIRST_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + EsdtTokenPayment::new( + FUNGIBLE_TOKEN_ID_EXPR.to_token_identifier(), + 0, + managed_biguint!(FUNGIBLE_AMOUNT), + ), + ]); let actual_uri = MergedTokenInstances::decode_from_first_uri(&merged_token_data.uris); - assert_eq!(expected_uri, actual_uri.into_instances()); + assert_eq!(expected_uri, *actual_uri.into_instances()); assert_eq!( merged_token_data.royalties, managed_biguint!(FIRST_ROYALTIES) ); - }, - ); - - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( - MERGED_TOKEN_ID_EXPR, - 2, - NFT_AMOUNT, - Option::<&Empty>::None, - ), - )); + }); + + world + .check_account(USER_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes(MERGED_TOKEN_ID_EXPR, 2, NFT_AMOUNT, &Empty); // merge NFT with an already merged token let combined_transfers = vec![ - TxESDT { - esdt_token_identifier: NFT_TOKEN_ID.into(), - nonce: SECOND_NFT_NONCE.into(), - esdt_value: NFT_AMOUNT.into(), - }, - TxESDT { - esdt_token_identifier: MERGED_TOKEN_ID.into(), - nonce: 2u64.into(), - esdt_value: NFT_AMOUNT.into(), - }, + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT), + TestEsdtTransfer(MERGED_TOKEN_ID_EXPR, 2u64, NFT_AMOUNT), ]; - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .multi_esdt_transfer(combined_transfers), - |sc| { + world + .tx() + .from(USER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .multi_esdt(combined_transfers) + .whitebox(use_module::contract_obj, |sc| { let merged_token = sc.merge_tokens_endpoint(); assert_eq!( merged_token.token_identifier, - managed_token_id!(MERGED_TOKEN_ID) + MERGED_TOKEN_ID_EXPR.to_token_identifier() ); assert_eq!(merged_token.token_nonce, 3); assert_eq!(merged_token.amount, managed_biguint!(NFT_AMOUNT)); let merged_token_data = sc.blockchain().get_esdt_token_data( - &managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), - &managed_token_id!(MERGED_TOKEN_ID), + &USER_ADDRESS_EXPR.to_managed_address(), + &MERGED_TOKEN_ID_EXPR.into(), 3, ); - let mut expected_uri = ArrayVec::new(); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - FIRST_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(FUNGIBLE_TOKEN_ID), - 0, - managed_biguint!(FUNGIBLE_AMOUNT), - )); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - SECOND_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); + let expected_uri = ArrayVec::from([ + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + FIRST_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + EsdtTokenPayment::new( + FUNGIBLE_TOKEN_ID_EXPR.to_token_identifier(), + 0, + managed_biguint!(FUNGIBLE_AMOUNT), + ), + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + SECOND_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + ]); let actual_uri = MergedTokenInstances::decode_from_first_uri(&merged_token_data.uris); - assert_eq!(expected_uri, actual_uri.into_instances()); + assert_eq!(expected_uri, *actual_uri.into_instances()); assert_eq!( merged_token_data.royalties, managed_biguint!(SECOND_ROYALTIES) ); - }, - ); - - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( - MERGED_TOKEN_ID_EXPR, - 3, - NFT_AMOUNT, - Option::<&Empty>::None, - ), - )); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(USER_ADDRESS_EXPR).esdt_transfer( - MERGED_TOKEN_ID_EXPR, - 3, - NFT_AMOUNT, - ), - |sc| { + }); + + world + .check_account(USER_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes(MERGED_TOKEN_ID_EXPR, 3, NFT_AMOUNT, &Empty); + + world + .tx() + .from(USER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .payment(TestEsdtTransfer(MERGED_TOKEN_ID_EXPR, 3, NFT_AMOUNT)) + .whitebox(use_module::contract_obj, |sc| { let output_tokens = sc.split_tokens_endpoint(); - let mut expected_output_tokens = ManagedVec::new(); - expected_output_tokens.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - FIRST_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - expected_output_tokens.push(EsdtTokenPayment::new( - managed_token_id!(FUNGIBLE_TOKEN_ID), - 0, - managed_biguint!(FUNGIBLE_AMOUNT), - )); - expected_output_tokens.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - SECOND_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - - assert_eq!(output_tokens, expected_output_tokens); - }, - ); - - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( + let expected_output_tokens = vec![ + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT), + TestEsdtTransfer(FUNGIBLE_TOKEN_ID_EXPR, 0, FUNGIBLE_AMOUNT), + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT), + ]; + + assert_eq!(output_tokens, expected_output_tokens.into()); + }); + + world + .check_account(USER_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes( NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT, - Some(FIRST_ATTRIBUTES), - ), - )); + FIRST_ATTRIBUTES, + ); - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( + world + .check_account(USER_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes( NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT, - Some(SECOND_ATTRIBUTES), - ), - )); - - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_balance(FUNGIBLE_TOKEN_ID_EXPR, FUNGIBLE_AMOUNT), - )); + SECOND_ATTRIBUTES, + ); + + world + .check_account(USER_ADDRESS_EXPR) + .esdt_balance(FUNGIBLE_TOKEN_ID_EXPR, FUNGIBLE_AMOUNT); } #[test] fn test_partial_split() { let mut world = world(); - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); - let use_module_code = world.code_expression(USE_MODULE_PATH_EXPR); - let roles = vec![ "ESDTRoleNFTCreate".to_string(), "ESDTRoleNFTBurn".to_string(), ]; - - world.set_state_step( - SetStateStep::new() - .put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .put_account( - USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(FUNGIBLE_TOKEN_ID_EXPR, FUNGIBLE_AMOUNT) - .esdt_nft_all_properties( - NFT_TOKEN_ID_EXPR, - FIRST_NFT_NONCE, - NFT_AMOUNT, - Some(FIRST_ATTRIBUTES), - FIRST_ROYALTIES, - None, - None, - Vec::from(FIRST_URIS), - ) - .esdt_nft_all_properties( - NFT_TOKEN_ID_EXPR, - SECOND_NFT_NONCE, - NFT_AMOUNT, - Some(SECOND_ATTRIBUTES), - SECOND_ROYALTIES, - None, - None, - Vec::from(SECOND_URIS), - ), - ) - .put_account( - USE_MODULE_ADDRESS_EXPR, - Account::new() - .nonce(1) - .code(use_module_code) - .owner(OWNER_ADDRESS_EXPR) - .esdt_roles(MERGED_TOKEN_ID_EXPR, roles), - ), - ); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| { + let first_uris = FIRST_URIS + .iter() + .map(|first_uri| managed_buffer!(first_uri)) + .collect(); + let second_uris = SECOND_URIS + .iter() + .map(|second_uri| managed_buffer!(second_uri)) + .collect(); + + world.account(OWNER_ADDRESS_EXPR).nonce(1); + world + .account(USER_ADDRESS_EXPR) + .nonce(1) + .esdt_balance(FUNGIBLE_TOKEN_ID_EXPR, FUNGIBLE_AMOUNT) + .esdt_nft_all_properties( + NFT_TOKEN_ID_EXPR, + FIRST_NFT_NONCE, + NFT_AMOUNT, + managed_buffer!(FIRST_ATTRIBUTES), + FIRST_ROYALTIES, + None::, + (), + first_uris, + ) + .esdt_nft_all_properties( + NFT_TOKEN_ID_EXPR, + SECOND_NFT_NONCE, + NFT_AMOUNT, + managed_buffer!(SECOND_ATTRIBUTES), + SECOND_ROYALTIES, + None::, + (), + second_uris, + ); + + world + .account(USE_MODULE_ADDRESS_EXPR) + .nonce(1) + .code(USE_MODULE_PATH_EXPR) + .owner(OWNER_ADDRESS_EXPR) + .esdt_roles(MERGED_TOKEN_ID_EXPR, roles); + + world + .tx() + .from(OWNER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .whitebox(use_module::contract_obj, |sc| { sc.merged_token() - .set_token_id(managed_token_id!(MERGED_TOKEN_ID)); - let _ = sc - .mergeable_tokens_whitelist() - .insert(managed_token_id!(NFT_TOKEN_ID)); - let _ = sc - .mergeable_tokens_whitelist() - .insert(managed_token_id!(FUNGIBLE_TOKEN_ID)); - }, - ); + .set_token_id(MERGED_TOKEN_ID_EXPR.to_token_identifier()); + sc.mergeable_tokens_whitelist() + .insert(NFT_TOKEN_ID_EXPR.to_token_identifier()); + sc.mergeable_tokens_whitelist() + .insert(FUNGIBLE_TOKEN_ID_EXPR.to_token_identifier()); + }); // merge 2 NFTs and a fungible token let esdt_transfers = vec![ - TxESDT { - esdt_token_identifier: NFT_TOKEN_ID.into(), - nonce: FIRST_NFT_NONCE.into(), - esdt_value: NFT_AMOUNT.into(), - }, - TxESDT { - esdt_token_identifier: NFT_TOKEN_ID.into(), - nonce: SECOND_NFT_NONCE.into(), - esdt_value: NFT_AMOUNT.into(), - }, - TxESDT { - esdt_token_identifier: FUNGIBLE_TOKEN_ID.into(), - nonce: 0u64.into(), - esdt_value: FUNGIBLE_AMOUNT.into(), - }, + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT), + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT), + TestEsdtTransfer(FUNGIBLE_TOKEN_ID_EXPR, 0u64, FUNGIBLE_AMOUNT), ]; - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .multi_esdt_transfer(esdt_transfers), - |sc| { + world + .tx() + .from(USER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .multi_esdt(esdt_transfers) + .whitebox(use_module::contract_obj, |sc| { let merged_token = sc.merge_tokens_endpoint(); assert_eq!( merged_token.token_identifier, - managed_token_id!(MERGED_TOKEN_ID) + MERGED_TOKEN_ID_EXPR.to_token_identifier() ); assert_eq!(merged_token.token_nonce, 1); assert_eq!(merged_token.amount, managed_biguint!(NFT_AMOUNT)); let merged_token_data = sc.blockchain().get_esdt_token_data( - &managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), - &managed_token_id!(MERGED_TOKEN_ID), + &USER_ADDRESS_EXPR.to_managed_address(), + &MERGED_TOKEN_ID_EXPR.to_token_identifier(), 1, ); - let mut expected_uri = ArrayVec::new(); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - FIRST_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - SECOND_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(FUNGIBLE_TOKEN_ID), - 0, - managed_biguint!(FUNGIBLE_AMOUNT), - )); + let expected_uri = ArrayVec::from([ + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + FIRST_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + SECOND_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + EsdtTokenPayment::new( + FUNGIBLE_TOKEN_ID_EXPR.to_token_identifier(), + 0, + managed_biguint!(FUNGIBLE_AMOUNT), + ), + ]); let actual_uri = MergedTokenInstances::decode_from_first_uri(&merged_token_data.uris); - assert_eq!(expected_uri, actual_uri.into_instances()); - }, - ); + assert_eq!(expected_uri, *actual_uri.into_instances()); + }); // split part of the fungible token - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(USER_ADDRESS_EXPR).esdt_transfer( - MERGED_TOKEN_ID_EXPR, - 1, - NFT_AMOUNT, - ), - |sc| { + world + .tx() + .from(USER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .payment(TestEsdtTransfer(MERGED_TOKEN_ID_EXPR, 1, NFT_AMOUNT)) + .whitebox(use_module::contract_obj, |sc| { let mut tokens_to_remove = ManagedVec::new(); tokens_to_remove.push(EsdtTokenPayment::new( - managed_token_id!(FUNGIBLE_TOKEN_ID), + FUNGIBLE_TOKEN_ID_EXPR.to_token_identifier(), 0, managed_biguint!(40), )); - let output_payments = sc.split_token_partial_endpoint(tokens_to_remove); + let output_payments = sc.split_token_partial_endpoint(tokens_to_remove); let mut expected_output_payments = ManagedVec::new(); expected_output_payments.push(EsdtTokenPayment::new( - managed_token_id!(FUNGIBLE_TOKEN_ID), + FUNGIBLE_TOKEN_ID_EXPR.to_token_identifier(), 0, managed_biguint!(40), )); expected_output_payments.push(EsdtTokenPayment::new( - managed_token_id!(MERGED_TOKEN_ID), + MERGED_TOKEN_ID_EXPR.to_token_identifier(), 2, managed_biguint!(NFT_AMOUNT), )); assert_eq!(output_payments, expected_output_payments); - }, - ); + }); // fully remove instance - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(USER_ADDRESS_EXPR).esdt_transfer( - MERGED_TOKEN_ID_EXPR, - 2, - NFT_AMOUNT, - ), - |sc| { + world + .tx() + .from(USER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .payment(TestEsdtTransfer(MERGED_TOKEN_ID_EXPR, 2, NFT_AMOUNT)) + .whitebox(use_module::contract_obj, |sc| { let mut tokens_to_remove = ManagedVec::new(); tokens_to_remove.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), + NFT_TOKEN_ID_EXPR.to_token_identifier(), FIRST_NFT_NONCE, managed_biguint!(NFT_AMOUNT), )); @@ -617,12 +504,12 @@ fn test_partial_split() { let mut expected_output_payments = ManagedVec::new(); expected_output_payments.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), + NFT_TOKEN_ID_EXPR.to_token_identifier(), FIRST_NFT_NONCE, managed_biguint!(NFT_AMOUNT), )); expected_output_payments.push(EsdtTokenPayment::new( - managed_token_id!(MERGED_TOKEN_ID), + MERGED_TOKEN_ID_EXPR.to_token_identifier(), 3, managed_biguint!(NFT_AMOUNT), )); @@ -630,112 +517,101 @@ fn test_partial_split() { // check newest token attributes let merged_token_data = sc.blockchain().get_esdt_token_data( - &managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), - &managed_token_id!(MERGED_TOKEN_ID), + &USER_ADDRESS_EXPR.to_managed_address(), + &MERGED_TOKEN_ID_EXPR.to_token_identifier(), 3, ); - let mut expected_uri = ArrayVec::new(); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - SECOND_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(FUNGIBLE_TOKEN_ID), - 0, - managed_biguint!(FUNGIBLE_AMOUNT - 40), - )); + let expected_uri = ArrayVec::from([ + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + SECOND_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + EsdtTokenPayment::new( + FUNGIBLE_TOKEN_ID_EXPR.to_token_identifier(), + 0, + managed_biguint!(FUNGIBLE_AMOUNT - 40), + ), + ]); let actual_uri = MergedTokenInstances::decode_from_first_uri(&merged_token_data.uris); - assert_eq!(expected_uri, actual_uri.into_instances()); + assert_eq!(expected_uri, *actual_uri.into_instances()); assert_eq!( merged_token_data.royalties, managed_biguint!(SECOND_ROYALTIES) ); - }, - ); + }); } #[test] fn test_custom_attributes() { let mut world = world(); - let use_module_whitebox = - WhiteboxContract::new(USE_MODULE_ADDRESS_EXPR, use_module::contract_obj); - let use_module_code = world.code_expression(USE_MODULE_PATH_EXPR); - let roles = vec![ "ESDTRoleNFTCreate".to_string(), "ESDTRoleNFTBurn".to_string(), ]; - world.set_state_step( - SetStateStep::new() - .put_account(OWNER_ADDRESS_EXPR, Account::new().nonce(1)) - .put_account( - USER_ADDRESS_EXPR, - Account::new() - .nonce(1) - .esdt_balance(FUNGIBLE_TOKEN_ID_EXPR, FUNGIBLE_AMOUNT) - .esdt_nft_all_properties( - NFT_TOKEN_ID_EXPR, - FIRST_NFT_NONCE, - NFT_AMOUNT, - Some(FIRST_ATTRIBUTES), - FIRST_ROYALTIES, - None, - None, - Vec::from(FIRST_URIS), - ) - .esdt_nft_all_properties( - NFT_TOKEN_ID_EXPR, - SECOND_NFT_NONCE, - NFT_AMOUNT, - Some(SECOND_ATTRIBUTES), - SECOND_ROYALTIES, - None, - None, - Vec::from(SECOND_URIS), - ), - ) - .put_account( - USE_MODULE_ADDRESS_EXPR, - Account::new() - .nonce(1) - .code(use_module_code) - .owner(OWNER_ADDRESS_EXPR) - .esdt_roles(MERGED_TOKEN_ID_EXPR, roles), - ), - ); - - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new().from(OWNER_ADDRESS_EXPR), - |sc| { + let first_uris = FIRST_URIS + .iter() + .map(|first_uri| managed_buffer!(first_uri)) + .collect(); + let second_uris = SECOND_URIS + .iter() + .map(|second_uri| managed_buffer!(second_uri)) + .collect(); + world.account(OWNER_ADDRESS_EXPR).nonce(1); + world + .account(USER_ADDRESS_EXPR) + .nonce(1) + .esdt_balance(FUNGIBLE_TOKEN_ID_EXPR, FUNGIBLE_AMOUNT) + .esdt_nft_all_properties( + NFT_TOKEN_ID_EXPR, + FIRST_NFT_NONCE, + NFT_AMOUNT, + managed_buffer!(FIRST_ATTRIBUTES), + FIRST_ROYALTIES, + None::, + (), + first_uris, + ) + .esdt_nft_all_properties( + NFT_TOKEN_ID_EXPR, + SECOND_NFT_NONCE, + NFT_AMOUNT, + managed_buffer!(SECOND_ATTRIBUTES), + SECOND_ROYALTIES, + None::, + (), + second_uris, + ); + world + .account(USE_MODULE_ADDRESS_EXPR) + .nonce(1) + .code(USE_MODULE_PATH_EXPR) + .owner(OWNER_ADDRESS_EXPR) + .esdt_roles(MERGED_TOKEN_ID_EXPR, roles); + + world + .tx() + .from(OWNER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .whitebox(use_module::contract_obj, |sc| { sc.merged_token() - .set_token_id(managed_token_id!(MERGED_TOKEN_ID)); + .set_token_id(MERGED_TOKEN_ID_EXPR.to_token_identifier()); let _ = sc .mergeable_tokens_whitelist() - .insert(managed_token_id!(NFT_TOKEN_ID)); + .insert(NFT_TOKEN_ID_EXPR.to_token_identifier()); let _ = sc .mergeable_tokens_whitelist() - .insert(managed_token_id!(FUNGIBLE_TOKEN_ID)); - }, - ); + .insert(FUNGIBLE_TOKEN_ID_EXPR.to_token_identifier()); + }); // merge two NFTs let nft_transfers = vec![ - TxESDT { - esdt_token_identifier: NFT_TOKEN_ID.into(), - nonce: FIRST_NFT_NONCE.into(), - esdt_value: NFT_AMOUNT.into(), - }, - TxESDT { - esdt_token_identifier: NFT_TOKEN_ID.into(), - nonce: SECOND_NFT_NONCE.into(), - esdt_value: NFT_AMOUNT.into(), - }, + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT), + TestEsdtTransfer(NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT), ]; let expected_attributes = CustomAttributes { @@ -743,39 +619,39 @@ fn test_custom_attributes() { second: 10u64, }; - world.whitebox_call( - &use_module_whitebox, - ScCallStep::new() - .from(USER_ADDRESS_EXPR) - .multi_esdt_transfer(nft_transfers), - |sc| { + world + .tx() + .from(USER_ADDRESS_EXPR) + .to(USE_MODULE_ADDRESS_EXPR) + .multi_esdt(nft_transfers) + .whitebox(use_module::contract_obj, |sc| { let merged_token = sc.merge_tokens_custom_attributes_endpoint(); assert_eq!( merged_token.token_identifier, - managed_token_id!(MERGED_TOKEN_ID) + MERGED_TOKEN_ID_EXPR.to_token_identifier() ); assert_eq!(merged_token.token_nonce, 1); assert_eq!(merged_token.amount, managed_biguint!(NFT_AMOUNT)); let merged_token_data = sc.blockchain().get_esdt_token_data( - &managed_address!(&address_expr_to_address(USER_ADDRESS_EXPR)), - &managed_token_id!(MERGED_TOKEN_ID), + &USER_ADDRESS_EXPR.to_managed_address(), + &MERGED_TOKEN_ID_EXPR.to_token_identifier(), 1, ); - let mut expected_uri = ArrayVec::new(); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - FIRST_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - expected_uri.push(EsdtTokenPayment::new( - managed_token_id!(NFT_TOKEN_ID), - SECOND_NFT_NONCE, - managed_biguint!(NFT_AMOUNT), - )); - + let expected_uri = ArrayVec::from([ + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + FIRST_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + EsdtTokenPayment::new( + NFT_TOKEN_ID_EXPR.to_token_identifier(), + SECOND_NFT_NONCE, + managed_biguint!(NFT_AMOUNT), + ), + ]); let actual_uri = MergedTokenInstances::decode_from_first_uri(&merged_token_data.uris); - assert_eq!(expected_uri, actual_uri.into_instances()); + assert_eq!(expected_uri, *actual_uri.into_instances()); let actual_attributes: CustomAttributes = merged_token_data.decode_attributes(); assert_eq!(expected_attributes, actual_attributes); @@ -784,40 +660,26 @@ fn test_custom_attributes() { merged_token_data.royalties, managed_biguint!(SECOND_ROYALTIES) ); - }, - ); - - world.check_state_step(CheckStateStep::new().put_account( - USER_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( - MERGED_TOKEN_ID_EXPR, - 1, - NFT_AMOUNT, - Some(top_encode_to_vec_u8_or_panic(&expected_attributes)), - ), - )); + }); + + world + .check_account(USER_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes(MERGED_TOKEN_ID_EXPR, 1, NFT_AMOUNT, expected_attributes); - world.check_state_step(CheckStateStep::new().put_account( - USE_MODULE_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( + world + .check_account(USE_MODULE_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes( NFT_TOKEN_ID_EXPR, FIRST_NFT_NONCE, NFT_AMOUNT, - Some(FIRST_ATTRIBUTES), - ), - )); - - world.check_state_step(CheckStateStep::new().put_account( - USE_MODULE_ADDRESS_EXPR, - CheckAccount::new().esdt_nft_balance_and_attributes( + FIRST_ATTRIBUTES, + ); + world + .check_account(USE_MODULE_ADDRESS_EXPR) + .esdt_nft_balance_and_attributes( NFT_TOKEN_ID_EXPR, SECOND_NFT_NONCE, NFT_AMOUNT, - Some(SECOND_ATTRIBUTES), - ), - )); -} - -fn address_expr_to_address(address_expr: &str) -> Address { - AddressValue::from(address_expr).to_address() + SECOND_ATTRIBUTES, + ); } 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_go_test.rs b/contracts/feature-tests/use-module/tests/use_module_scenario_go_test.rs index 6b077edad0..5767c9ea08 100644 --- a/contracts/feature-tests/use-module/tests/use_module_scenario_go_test.rs +++ b/contracts/feature-tests/use-module/tests/use_module_scenario_go_test.rs @@ -10,6 +10,7 @@ fn use_module_claim_developer_rewards_go() { } #[test] +#[ignore = "uses multi-level async"] fn use_module_dns_register_go() { world().run("scenarios/use_module_dns_register.scen.json"); } 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 c5748252dd..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(); } } } @@ -33,10 +21,13 @@ use multiversx_sc_scenario::*; fn world() -> ScenarioWorld { let mut blockchain = ScenarioWorld::new(); - blockchain.register_contract("file:output/use-module.wasm", use_module::ContractBuilder); + blockchain.register_contract( + "mxsc:output/use-module.mxsc.json", + use_module::ContractBuilder, + ); blockchain.register_contract( - "file:test-wasm/elrond-wasm-sc-dns.wasm", + "mxsc:test-wasm/elrond-wasm-sc-dns.mxsc.json", dns_mock::ContractBuilder, ); 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 f338e5af5d..7a339475d8 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.44.0" + "version": "0.53.0" } }, "docs": [ @@ -1000,6 +1000,14 @@ "type": "EsdtTokenPayment" } ] + }, + { + "identifier": "pauseContract", + "inputs": [] + }, + { + "identifier": "unpauseContract", + "inputs": [] } ], "esdtAttributes": [ 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 b1e820c4d9..66e7bf4817 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.44.0" + "version": "0.53.0" } }, "docs": [ @@ -244,6 +244,14 @@ "type": "EsdtTokenPayment" } ] + }, + { + "identifier": "pauseContract", + "inputs": [] + }, + { + "identifier": "unpauseContract", + "inputs": [] } ], "esdtAttributes": [ 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 8e295dcc87..a124843123 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 @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,61 +34,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -174,26 +142,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -206,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" @@ -221,29 +184,3 @@ dependencies = [ "multiversx-sc-wasm-adapter", "use-module", ] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] 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 6e4576f438..67b031e181 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 @@ -1,23 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "use-module-view-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] 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.use-module] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 87b8d984c8..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 @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 4233793776..9c7fadeec0 100644 --- a/contracts/feature-tests/use-module/wasm/Cargo.lock +++ b/contracts/feature-tests/use-module/wasm/Cargo.lock @@ -2,41 +2,23 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "ahash" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "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 = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "endian-type" @@ -44,15 +26,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - [[package]] name = "hex" version = "0.4.3" @@ -61,61 +34,62 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" dependencies = [ "bitflags", - "hashbrown", "hex-literal", "multiversx-sc-codec", "multiversx-sc-derive", "num-traits", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", + "unwrap-infallible", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.18.1" +version = "0.21.0" dependencies = [ "hex", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" dependencies = [ "hex", "proc-macro2", "quote", "radix_trie", - "syn 1.0.109", + "syn", ] [[package]] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.44.0" +version = "0.53.0" dependencies = [ "multiversx-sc", ] @@ -131,33 +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 = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -174,26 +142,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -206,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" @@ -221,29 +184,3 @@ dependencies = [ "multiversx-sc-wasm-adapter", "use-module", ] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092cd76b01a033a9965b9097da258689d9e17c69ded5dcf41bca001dd20ebc6d" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a20a7c6a90e2034bcc65495799da92efcec6a8dd4f3fcb6f7a48988637ead" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] diff --git a/contracts/feature-tests/use-module/wasm/Cargo.toml b/contracts/feature-tests/use-module/wasm/Cargo.toml index 11167ad61a..c2540ab89c 100644 --- a/contracts/feature-tests/use-module/wasm/Cargo.toml +++ b/contracts/feature-tests/use-module/wasm/Cargo.toml @@ -1,7 +1,12 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + [package] name = "use-module-wasm" version = "0.0.0" -authors = ["Andrei Marinica "] edition = "2021" publish = false @@ -14,12 +19,16 @@ opt-level = "z" lto = true debug = false panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" [dependencies.use-module] path = ".." [dependencies.multiversx-sc-wasm-adapter] -version = "0.44.0" +version = "0.53.0" 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 97651ae723..7171b56ecd 100644 --- a/contracts/feature-tests/use-module/wasm/src/lib.rs +++ b/contracts/feature-tests/use-module/wasm/src/lib.rs @@ -1,4 +1,4 @@ -// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -11,10 +11,6 @@ #![no_std] -// Configuration that works with rustc < 1.73.0. -// TODO: Recommended rustc version: 1.73.0 or newer. -#![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 22b841d8a8..cbe440e21e 100644 --- a/contracts/modules/Cargo.toml +++ b/contracts/modules/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-modules" -version = "0.44.0" +version = "0.53.0" edition = "2021" authors = ["MultiversX "] @@ -17,5 +17,5 @@ categories = ["no-std", "wasm", "cryptography::cryptocurrencies"] alloc = ["multiversx-sc/alloc"] [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" 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/pause.rs b/contracts/modules/src/pause.rs index a02be8b5cc..db877a0d56 100644 --- a/contracts/modules/src/pause.rs +++ b/contracts/modules/src/pause.rs @@ -30,14 +30,14 @@ pub trait PauseModule { #[endpoint(pause)] fn pause_endpoint(&self) { self.set_paused(true); - // TODO: event + self.pause_event(); } #[only_owner] #[endpoint(unpause)] fn unpause_endpoint(&self) { self.set_paused(false); - // TODO: event + self.unpause_event(); } fn require_paused(&self) { @@ -48,6 +48,12 @@ pub trait PauseModule { require!(self.not_paused(), "Contract is paused"); } + #[event("pauseContract")] + fn pause_event(&self); + + #[event("unpauseContract")] + fn unpause_event(&self); + #[view(isPaused)] #[storage_mapper("pause_module:paused")] fn paused_status(&self) -> SingleValueMapper; 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 1d0c2c6591..4b18e0d167 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.1" +version = "0.21.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.66" -quote = "1.0.33" -syn = "1.0" -hex = "0.4" +proc-macro2 = "=1.0.86" +quote = "=1.0.37" +syn = "=2.0.77" +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 bbd358e80d..f24ab1a256 100644 --- a/data/codec-derive/src/nested_de_derive.rs +++ b/data/codec-derive/src/nested_de_derive.rs @@ -11,11 +11,11 @@ pub fn dep_decode_snippet( let ty = &field.ty; if let Some(ident) = &field.ident { quote! { - #ident: <#ty as codec::NestedDecode>::dep_decode_or_handle_err(#input_value, h)? + #ident: <#ty as codec::NestedDecode>::dep_decode_or_handle_err(#input_value, __h__)? } } else { quote! { - <#ty as codec::NestedDecode>::dep_decode_or_handle_err(#input_value, h)? + <#ty as codec::NestedDecode>::dep_decode_or_handle_err(#input_value, __h__)? } } } @@ -25,21 +25,22 @@ pub fn variant_dep_decode_snippets( data_enum: &syn::DataEnum, input_value: &proc_macro2::TokenStream, ) -> Vec { + let mut previous_disc: Vec = Vec::new(); data_enum - .variants - .iter() - .enumerate() - .map(|(variant_index, variant)| { - let variant_index_u8 = variant_index as u8; - 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_index_u8 => core::result::Result::Ok( #name::#variant_ident #variant_field_snippets ), - } - }) - .collect() + .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! { + #variant_discriminant => core::result::Result::Ok( #name::#variant_ident #variant_field_snippets ), + } + }) + .collect() } pub fn nested_decode_impl(ast: &syn::DeriveInput) -> TokenStream { @@ -53,7 +54,7 @@ pub fn nested_decode_impl(ast: &syn::DeriveInput) -> TokenStream { }); quote! { impl #impl_generics codec::NestedDecode for #name #ty_generics #where_clause { - fn dep_decode_or_handle_err(input: &mut I, h: H) -> core::result::Result + fn dep_decode_or_handle_err(input: &mut I, __h__: H) -> core::result::Result where I: codec::NestedDecodeInput, H: codec::DecodeErrorHandler, @@ -66,23 +67,21 @@ pub fn nested_decode_impl(ast: &syn::DeriveInput) -> TokenStream { } }, syn::Data::Enum(data_enum) => { - assert!( - data_enum.variants.len() < 256, - "enums with more than 256 variants not supported" - ); + validate_enum_variants(&data_enum.variants); + let variant_dep_decode_snippets = variant_dep_decode_snippets(name, data_enum, "e! {input}); quote! { impl #impl_generics codec::NestedDecode for #name #ty_generics #where_clause { - fn dep_decode_or_handle_err(input: &mut I, h: H) -> core::result::Result + fn dep_decode_or_handle_err(input: &mut I, __h__: H) -> core::result::Result where I: codec::NestedDecodeInput, H: codec::DecodeErrorHandler, { - match ::dep_decode_or_handle_err(input, h)? { + match ::dep_decode_or_handle_err(input, __h__)? { #(#variant_dep_decode_snippets)* - _ => core::result::Result::Err(h.handle_error(codec::DecodeError::INVALID_VALUE)), + _ => core::result::Result::Err(__h__.handle_error(codec::DecodeError::INVALID_VALUE)), } } } diff --git a/data/codec-derive/src/nested_en_derive.rs b/data/codec-derive/src/nested_en_derive.rs index 97e70dd977..7a716d2d8d 100644 --- a/data/codec-derive/src/nested_en_derive.rs +++ b/data/codec-derive/src/nested_en_derive.rs @@ -4,7 +4,7 @@ use quote::quote; pub fn dep_encode_snippet(value: &proc_macro2::TokenStream) -> proc_macro2::TokenStream { quote! { - codec::NestedEncode::dep_encode_or_handle_err(&#value, dest, h)?; + codec::NestedEncode::dep_encode_or_handle_err(&#value, __dest__, __h__)?; } } @@ -12,12 +12,13 @@ fn variant_dep_encode_snippets( name: &syn::Ident, data_enum: &syn::DataEnum, ) -> Vec { + let mut previous_disc: Vec = Vec::new(); data_enum .variants .iter() .enumerate() .map(|(variant_index, variant)| { - let variant_index_u8 = variant_index as u8; + let variant_discriminant = get_discriminant(variant_index, variant, &mut previous_disc); let variant_ident = &variant.ident; let local_var_declarations = fields_decl_syntax(&variant.fields, local_variable_for_field); @@ -26,7 +27,7 @@ fn variant_dep_encode_snippets( }); quote! { #name::#variant_ident #local_var_declarations => { - codec::NestedEncode::dep_encode_or_handle_err(&#variant_index_u8, dest, h)?; + codec::NestedEncode::dep_encode_or_handle_err(&#variant_discriminant, __dest__, __h__)?; #(#variant_field_snippets)* }, } @@ -44,7 +45,7 @@ pub fn nested_encode_impl(ast: &syn::DeriveInput) -> TokenStream { }); quote! { impl #impl_generics codec::NestedEncode for #name #ty_generics #where_clause { - fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> core::result::Result<(), H::HandledErr> + fn dep_encode_or_handle_err(&self, __dest__: &mut O, __h__: H) -> core::result::Result<(), H::HandledErr> where O: codec::NestedEncodeOutput, H: codec::EncodeErrorHandler, @@ -56,15 +57,13 @@ pub fn nested_encode_impl(ast: &syn::DeriveInput) -> TokenStream { } }, syn::Data::Enum(data_enum) => { - assert!( - data_enum.variants.len() < 256, - "enums with more than 256 variants not supported" - ); + validate_enum_variants(&data_enum.variants); + let variant_dep_encode_snippets = variant_dep_encode_snippets(name, data_enum); quote! { impl #impl_generics codec::NestedEncode for #name #ty_generics #where_clause { - fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> core::result::Result<(), H::HandledErr> + fn dep_encode_or_handle_err(&self, __dest__: &mut O, __h__: H) -> core::result::Result<(), H::HandledErr> where O: codec::NestedEncodeOutput, H: codec::EncodeErrorHandler, diff --git a/data/codec-derive/src/top_de_derive.rs b/data/codec-derive/src/top_de_derive.rs index 30e79e1362..9c6245210d 100644 --- a/data/codec-derive/src/top_de_derive.rs +++ b/data/codec-derive/src/top_de_derive.rs @@ -7,15 +7,16 @@ fn fieldless_enum_match_arm_result_ok( name: &syn::Ident, data_enum: &syn::DataEnum, ) -> Vec { + let mut previous_disc: Vec = Vec::new(); data_enum .variants .iter() .enumerate() .map(|(variant_index, variant)| { - let variant_index_u8 = variant_index as u8; + let variant_discriminant = get_discriminant(variant_index, variant, &mut previous_disc); let variant_ident = &variant.ident; quote! { - #variant_index_u8 => core::result::Result::Ok( #name::#variant_ident ), + #variant_discriminant => core::result::Result::Ok( #name::#variant_ident ), } }) .collect() @@ -61,23 +62,21 @@ fn top_decode_method_body(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { let mut nested_buffer = top_input.into_nested_buffer(); let result = #name #field_dep_decode_snippets ; if !codec::NestedDecodeInput::is_depleted(&nested_buffer) { - return core::result::Result::Err(h.handle_error(codec::DecodeError::INPUT_TOO_LONG)); + return core::result::Result::Err(__h__.handle_error(codec::DecodeError::INPUT_TOO_LONG)); } core::result::Result::Ok(result) } }, syn::Data::Enum(data_enum) => { - assert!( - data_enum.variants.len() < 256, - "enums with more than 256 variants not supported" - ); + validate_enum_variants(&data_enum.variants); + if is_fieldless_enum(data_enum) { // fieldless enums are special, they can be top-decoded as u8 directly let top_decode_arms = fieldless_enum_match_arm_result_ok(name, data_enum); quote! { - match ::top_decode_or_handle_err(top_input, h)? { + match ::top_decode_or_handle_err(top_input, __h__)? { #(#top_decode_arms)* - _ => core::result::Result::Err(h.handle_error(codec::DecodeError::INVALID_VALUE)), + _ => core::result::Result::Err(__h__.handle_error(codec::DecodeError::INVALID_VALUE)), } } } else { @@ -86,15 +85,15 @@ fn top_decode_method_body(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { quote! { let mut nested_buffer = top_input.into_nested_buffer(); - let result = match ::dep_decode_or_handle_err(&mut nested_buffer, h)? { + let result = match ::dep_decode_or_handle_err(&mut nested_buffer, __h__)? { #(#variant_dep_decode_snippets)* _ => core::result::Result::Err( - h.handle_error(codec::DecodeError::INVALID_VALUE), + __h__.handle_error(codec::DecodeError::INVALID_VALUE), ), }; if !codec::NestedDecodeInput::is_depleted(&nested_buffer) { return core::result::Result::Err( - h.handle_error(codec::DecodeError::INPUT_TOO_LONG), + __h__.handle_error(codec::DecodeError::INPUT_TOO_LONG), ); } result @@ -113,7 +112,7 @@ pub fn top_decode_impl(ast: &syn::DeriveInput) -> TokenStream { let gen = quote! { impl #impl_generics codec::TopDecode for #name #ty_generics #where_clause { - fn top_decode_or_handle_err(top_input: I, h: H) -> core::result::Result + fn top_decode_or_handle_err(top_input: I, __h__: H) -> core::result::Result where I: codec::TopDecodeInput, H: codec::DecodeErrorHandler, @@ -134,7 +133,7 @@ pub fn top_decode_or_default_impl(ast: &syn::DeriveInput) -> TokenStream { let gen = quote! { impl #impl_generics codec::TopDecode for #name #ty_generics #where_clause { - fn top_decode_or_handle_err(top_input: I, h: H) -> core::result::Result + fn top_decode_or_handle_err(top_input: I, __h__: H) -> core::result::Result where I: codec::TopDecodeInput, H: codec::DecodeErrorHandler, diff --git a/data/codec-derive/src/top_en_derive.rs b/data/codec-derive/src/top_en_derive.rs index 448a283c74..ccaccb7da5 100644 --- a/data/codec-derive/src/top_en_derive.rs +++ b/data/codec-derive/src/top_en_derive.rs @@ -7,18 +7,19 @@ pub fn variant_top_encode_snippets( name: &syn::Ident, data_enum: &syn::DataEnum, ) -> Vec { + let mut previous_disc: Vec = Vec::new(); data_enum .variants .iter() .enumerate() .map(|(variant_index, variant)| { - let variant_index_u8 = variant_index as u8; + let variant_discriminant = get_discriminant(variant_index, variant, &mut previous_disc); let variant_ident = &variant.ident; if variant.fields.is_empty() { // top-encode discriminant directly quote! { #name::#variant_ident => - codec::TopEncode::top_encode_or_handle_err(&#variant_index_u8, output, h), + codec::TopEncode::top_encode_or_handle_err(&#variant_discriminant, output, __h__), } } else { // dep-encode to buffer first @@ -29,11 +30,11 @@ pub fn variant_top_encode_snippets( }); quote! { #name::#variant_ident #local_var_declarations => { - let mut buffer = output.start_nested_encode(); - let dest = &mut buffer; - codec::NestedEncode::dep_encode_or_handle_err(&#variant_index_u8, dest, h)?; + let mut __buffer__ = output.start_nested_encode(); + let __dest__ = &mut __buffer__; + codec::NestedEncode::dep_encode_or_handle_err(&#variant_discriminant, __dest__, __h__)?; #(#variant_field_snippets)* - output.finalize_nested_encode(buffer); + output.finalize_nested_encode(__buffer__); core::result::Result::Ok(()) }, } @@ -51,18 +52,16 @@ fn top_encode_method_body(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { dep_encode_snippet(&self_field_expr(index, field)) }); quote! { - let mut buffer = output.start_nested_encode(); - let dest = &mut buffer; + let mut __buffer__ = output.start_nested_encode(); + let __dest__ = &mut __buffer__; #(#field_dep_encode_snippets)* - output.finalize_nested_encode(buffer); + output.finalize_nested_encode(__buffer__); core::result::Result::Ok(()) } }, syn::Data::Enum(data_enum) => { - assert!( - data_enum.variants.len() < 256, - "enums with more than 256 variants not supported" - ); + validate_enum_variants(&data_enum.variants); + let variant_top_encode_snippets = variant_top_encode_snippets(name, data_enum); quote! { @@ -82,7 +81,7 @@ pub fn top_encode_impl(ast: &syn::DeriveInput) -> TokenStream { let gen = quote! { impl #impl_generics codec::TopEncode for #name #ty_generics #where_clause { - fn top_encode_or_handle_err(&self, output: O, h: H) -> core::result::Result<(), H::HandledErr> + fn top_encode_or_handle_err(&self, output: O, __h__: H) -> core::result::Result<(), H::HandledErr> where O: codec::TopEncodeOutput, H: codec::EncodeErrorHandler, @@ -101,7 +100,7 @@ pub fn top_encode_or_default_impl(ast: &syn::DeriveInput) -> TokenStream { let gen = quote! { impl #impl_generics codec::TopEncode for #name #ty_generics #where_clause { - fn top_encode_or_handle_err(&self, output: O, h: H) -> core::result::Result<(), H::HandledErr> + fn top_encode_or_handle_err(&self, output: O, __h__: H) -> core::result::Result<(), H::HandledErr> where O: codec::TopEncodeOutput, H: codec::EncodeErrorHandler, diff --git a/data/codec-derive/src/util.rs b/data/codec-derive/src/util.rs index 380d7c94ee..e2e7f93acd 100644 --- a/data/codec-derive/src/util.rs +++ b/data/codec-derive/src/util.rs @@ -1,4 +1,10 @@ use quote::quote; +use syn::{punctuated::Punctuated, token::Comma, Variant}; + +pub struct ExplicitDiscriminant { + pub variant_index: usize, + pub value: u8, +} pub fn is_fieldless_enum(data_enum: &syn::DataEnum) -> bool { data_enum @@ -85,3 +91,53 @@ where syn::Fields::Unit => quote! {}, } } + +pub fn validate_enum_variants(variants: &Punctuated) { + assert!( + variants.len() <= 256, + "enums with more than 256 variants not supported" + ); +} + +pub fn get_discriminant( + variant_index: usize, + variant: &syn::Variant, + previous_disc: &mut Vec, +) -> proc_macro2::TokenStream { + // if it has explicit discriminant + if let Some((_, syn::Expr::Lit(expr))) = &variant.discriminant { + let lit = match &expr.lit { + syn::Lit::Int(val) => { + let value = val.base10_parse().unwrap_or_else(|_| { + panic!("Can not unwrap int value from explicit discriminant") + }); + previous_disc.push(ExplicitDiscriminant { + variant_index, + value, + }); + value + }, + _ => panic!("Only integer values as discriminants"), // theoretically covered by the compiler + }; + return quote! { #lit}; + } + + // if no explicit discriminant, check previous discriminants + // get previous explicit + 1 if there has been any explicit before + let next_value = match previous_disc.last() { + //there are previous explicit discriminants + Some(ExplicitDiscriminant { + variant_index: prev_index, + value: prev_value, + }) if *prev_index < variant_index - 1 => prev_value + (variant_index - prev_index) as u8, + Some(ExplicitDiscriminant { + variant_index: _, + value: prev_value, + }) => prev_value + 1, + + // vec is empty, return index + None => variant_index as u8, + }; + + quote! { #next_value} +} diff --git a/data/codec/Cargo.toml b/data/codec/Cargo.toml index e834e76b5e..1bb9ceb0bd 100644 --- a/data/codec/Cargo.toml +++ b/data/codec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-codec" -version = "0.18.1" +version = "0.21.0" edition = "2021" authors = ["Andrei Marinica ", "MultiversX "] @@ -15,17 +15,17 @@ categories = ["no-std", "wasm", "cryptography::cryptocurrencies", "development-t [features] derive = ["multiversx-sc-codec-derive"] -alloc = [] [dependencies.multiversx-sc-codec-derive] path = "../codec-derive" -version = "=0.18.1" +version = "=0.21.0" optional = true [dependencies] -arrayvec = { version = "0.7.1", default-features = false } -num-bigint = { version = "0.4.2", optional = true } # can only be used in std contexts +arrayvec = { version = "=0.7.6", default-features = false } +num-bigint = { version = "0.4", 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.1" +version = "=0.21.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/mod.rs b/data/codec/src/multi_types/mod.rs index 2bb9948b41..bf6a01ec61 100644 --- a/data/codec/src/multi_types/mod.rs +++ b/data/codec/src/multi_types/mod.rs @@ -3,14 +3,10 @@ mod multi_value_optional; mod multi_value_placeholder; mod multi_value_tuple; mod multi_value_unit; - -#[cfg(feature = "alloc")] mod multi_value_vec; pub use multi_value_ignore::IgnoreValue; pub use multi_value_optional::OptionalValue; pub use multi_value_placeholder::*; pub use multi_value_tuple::*; - -#[cfg(feature = "alloc")] pub use multi_value_vec::MultiValueVec; 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 8d79597b8d..978aab3280 100644 --- a/data/codec/src/num_conv.rs +++ b/data/codec/src/num_conv.rs @@ -1,38 +1,107 @@ +pub type TopEncodeNumberBuffer = [u8; 8]; + +/// This buffer is needed to provide some underlying structure on stack off which to build a variable-length slice. +/// +/// Its length is 9 (one more than necessary, to elegantly deal with the edge case "-1"). +pub const fn top_encode_number_buffer() -> TopEncodeNumberBuffer { + [0u8; 8] +} + /// Encodes number to minimimum number of bytes (top-encoding). /// /// Smaller types need to be converted to u64 before using this function. /// /// No generics here, we avoid monomorphization to make the SC binary as small as possible. -pub fn top_encode_number(x: u64, signed: bool, buffer: &mut [u8; 8]) -> &[u8] { - *buffer = x.to_be_bytes(); - if x == 0 { - // 0 is a special case - return &[]; - } +pub fn top_encode_number(x: u64, signed: bool, buffer: &mut TopEncodeNumberBuffer) -> &[u8] { + let offset = fill_buffer_find_offset(x, signed, buffer); - if signed && x == u64::MAX { - // -1 is a special case - // will return a single 0xFF byte - return &buffer[7..]; - } + debug_assert!(offset < 9); - let negative = signed && // only possible when signed flag - buffer[0] > 0x7fu8; // most significant bit is 1 + unsafe { buffer.get_unchecked(offset..) } +} - let irrelevant_byte = if negative { 0xffu8 } else { 0x00u8 }; +/// At the same time fills the buffer, +/// and performs the algorithm that tells us how many bytes can be skipped. +/// +/// Everything done in one function instead of 2, to avoid any unwanted bounds checks. +/// +/// This function is hyper-optimized to not contain any jumps. There are no ifs or loops in this, +/// the entire algorithm is performed via arithmetic, boolean and bitwise operations. +fn fill_buffer_find_offset(x: u64, signed: bool, buffer: &mut TopEncodeNumberBuffer) -> usize { + let b0 = (x >> 56 & 0xff) as u8; + + let negative = signed && msbit_is_one(b0); + let skippable_byte = skippable_byte(negative); let mut offset = 0usize; - while buffer[offset] == irrelevant_byte { - debug_assert!(offset < 7); - offset += 1; - } + let mut cursor = 1usize; - if signed && buffer[offset] >> 7 != negative as u8 { - debug_assert!(offset > 0); - offset -= 1; - } + change_one_to_zero_unless(&mut cursor, b0 == skippable_byte); + offset += cursor; + + let b1 = (x >> 48 & 0xff) as u8; + change_one_to_zero_unless(&mut cursor, b1 == skippable_byte); + offset += cursor; - &buffer[offset..] + let b2 = (x >> 40 & 0xff) as u8; + change_one_to_zero_unless(&mut cursor, b2 == skippable_byte); + offset += cursor; + + let b3 = (x >> 32 & 0xff) as u8; + change_one_to_zero_unless(&mut cursor, b3 == skippable_byte); + offset += cursor; + + let b4 = (x >> 24 & 0xff) as u8; + change_one_to_zero_unless(&mut cursor, b4 == skippable_byte); + offset += cursor; + + let b5 = (x >> 16 & 0xff) as u8; + change_one_to_zero_unless(&mut cursor, b5 == skippable_byte); + offset += cursor; + + let b6 = (x >> 8 & 0xff) as u8; + change_one_to_zero_unless(&mut cursor, b6 == skippable_byte); + offset += cursor; + + // The last byte: it can only get skipped for the number 0. + // Writing `b7 == skippable_byte` instead would also have caught -1, + // but that is an edge case where we do not want the last byte skipped. + let b7 = (x & 0xff) as u8; + change_one_to_zero_unless(&mut cursor, x == 0); + offset += cursor; + + buffer[0] = b0; + buffer[1] = b1; + buffer[2] = b2; + buffer[3] = b3; + buffer[4] = b4; + buffer[5] = b5; + buffer[6] = b6; + buffer[7] = b7; + + // For signed numbers, it can sometimes happen that we are skipping too many bytes, + // and the most significant bit ends up different than what we started with. + // In this case we need to backtrack one step. + // e.g. 255: [255] -> [0, 255] + // e.g. -129: [0x7f] -> [0xff, 0x7f] + cursor = 1; + change_one_to_zero_unless(&mut cursor, signed); + change_one_to_zero_unless(&mut cursor, offset > 0); + + // The only time when the offset can be 8 (and thus out of bounds) + // is for the number 0. Conveniently, for 0 all bytes are 0, so applying modulo 8 does not change the outcome. + let byte_at_offset = buffer[offset % 8]; + + // The main condition for stepping back one step: the most significant bit changed in the process. + let msbit_corrupted = msbit_is_one(byte_at_offset) != msbit_is_one(b0); + change_one_to_zero_unless(&mut cursor, msbit_corrupted); + + // According to this algorithm, it should be impossible to underflow + // using wrapping_sub to avoid unnecessary underflow check + debug_assert!(offset >= cursor); + offset = offset.wrapping_sub(cursor); + + offset } /// Handles both top-encoding and nested-encoding, signed and unsigned, of any length. @@ -41,21 +110,126 @@ pub fn top_encode_number(x: u64, signed: bool, buffer: &mut [u8; 8]) -> &[u8] { /// /// 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; + // 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. +#[inline] +fn msbit_is_one(byte: u8) -> bool { + byte >= 0b1000_0000u8 +} + +#[inline] +fn change_one_to_zero_unless(x: &mut usize, condition: bool) { + debug_assert!(*x <= 1); + *x &= condition as usize; +} + +/// For negative = true, yields 0xff. +/// +/// For negative = false, yields 0x00. +/// +/// Has no if, doesn't branch. +#[inline] +fn skippable_byte(negative: bool) -> u8 { + 0u8.wrapping_sub(negative as u8) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_set_to_zero_unless() { + let mut x = 1; + change_one_to_zero_unless(&mut x, true); + assert_eq!(x, 1); + change_one_to_zero_unless(&mut x, false); + assert_eq!(x, 0); + } + + #[test] + fn test_skippable_byte() { + assert_eq!(skippable_byte(true), 0xffu8); + assert_eq!(skippable_byte(false), 0x00u8); + } + + /// Only checks the filling out of the buffer. + #[test] + fn test_populate_buffer() { + let mut buffer = top_encode_number_buffer(); + let _ = fill_buffer_find_offset(0x12345678abcdef12, false, &mut buffer); + assert_eq!(buffer, [0x12, 0x34, 0x56, 0x78, 0xab, 0xcd, 0xef, 0x12]); + } + + fn test_encode_decode(x: u64, signed: bool, bytes: &[u8]) { + let mut buffer = top_encode_number_buffer(); + assert_eq!( + top_encode_number(x, signed, &mut buffer), + bytes, + "encode failed for {x}" + ); + assert_eq!( + universal_decode_number(bytes, signed,), + x, + "decode failed for {x}" + ); } - let negative = signed && bytes[0] >> 7 == 1; - 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; + + #[test] + #[rustfmt::skip] + fn test_top_encode_number() { + // unsigned + test_encode_decode(0x00, false, &[]); + test_encode_decode(0x01, false, &[1]); + test_encode_decode(0x7f, false, &[0x7f]); + test_encode_decode(0x80, false, &[0x80]); + test_encode_decode(0xff, false, &[0xff]); + test_encode_decode(0x0100, false, &[1, 0]); + test_encode_decode(0xff00, false, &[0xff, 0]); + test_encode_decode(0xffff, false, &[0xff, 0xff]); + test_encode_decode(0xffffffffffffffff, false, &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); + + // signed, positive + test_encode_decode(0x00, true, &[]); + test_encode_decode(0x01, true, &[1]); + test_encode_decode(0x7f, true, &[0x7f]); + test_encode_decode(0x80, true, &[0x00, 0x80]); + test_encode_decode(0x0100, true, &[1, 0]); + test_encode_decode(0xff00, true, &[0x00, 0xff, 0]); + test_encode_decode(0xffff, true, &[0x00, 0xff, 0xff]); + test_encode_decode(0x7fffffffffffffff, true, &[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); + test_encode_decode(0x8000000000000000, true, &[0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); + + // signed, negative + test_encode_decode(-1i64 as u64, true, &[0xff]); + test_encode_decode(-2i64 as u64, true, &[0xfe]); + test_encode_decode(-126i64 as u64, true, &[0x82]); + test_encode_decode(-127i64 as u64, true, &[0x81]); + test_encode_decode(-128i64 as u64, true, &[0x80]); + test_encode_decode(-129i64 as u64, true, &[0xff, 0x7f]); + test_encode_decode(-255i64 as u64, true, &[0xff, 0x01]); + test_encode_decode(-256i64 as u64, true, &[0xff, 0x00]); + test_encode_decode(-257i64 as u64, true, &[0xfe, 0xff]); } - result } 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 68d86667a1..9b5ddf10a4 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 { /// 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/single/top_en_output.rs b/data/codec/src/single/top_en_output.rs index d409a9e4c1..4f955ca2f2 100644 --- a/data/codec/src/single/top_en_output.rs +++ b/data/codec/src/single/top_en_output.rs @@ -1,5 +1,6 @@ use crate::{ - num_conv::top_encode_number, EncodeError, EncodeErrorHandler, NestedEncodeOutput, TryStaticCast, + num_conv::{top_encode_number, top_encode_number_buffer}, + EncodeError, EncodeErrorHandler, NestedEncodeOutput, TryStaticCast, }; use alloc::vec::Vec; @@ -20,13 +21,13 @@ pub trait TopEncodeOutput: Sized { fn set_slice_u8(self, bytes: &[u8]); fn set_u64(self, value: u64) { - let mut buffer = [0u8; 8]; + let mut buffer = top_encode_number_buffer(); let slice = top_encode_number(value, false, &mut buffer); self.set_slice_u8(slice); } fn set_i64(self, value: i64) { - let mut buffer = [0u8; 8]; + let mut buffer = top_encode_number_buffer(); let slice = top_encode_number(value as u64, true, &mut buffer); self.set_slice_u8(slice); } 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 b7e01b045e..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,16 +103,283 @@ 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); } + +#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, PartialEq, Eq, Clone, Debug)] +pub enum Enum256Variants { + Zero = 0, + One = 1, + Two = 2, + Three = 3, + Four = 4, + Five = 5, + Six = 6, + Seven = 7, + Eight = 8, + Nine = 9, + Ten = 10, + Eleven = 11, + Twelve = 12, + Thirteen = 13, + Fourteen = 14, + Fifteen = 15, + Sixteen = 16, + Seventeen = 17, + Eighteen = 18, + Nineteen = 19, + Twenty = 20, + TwentyOne = 21, + TwentyTwo = 22, + TwentyThree = 23, + TwentyFour = 24, + TwentyFive = 25, + TwentySix = 26, + TwentySeven = 27, + TwentyEight = 28, + TwentyNine = 29, + Thirty = 30, + ThirtyOne = 31, + ThirtyTwo = 32, + ThirtyThree = 33, + ThirtyFour = 34, + ThirtyFive = 35, + ThirtySix = 36, + ThirtySeven = 37, + ThirtyEight = 38, + ThirtyNine = 39, + Forty = 40, + FortyOne = 41, + FortyTwo = 42, + FortyThree = 43, + FortyFour = 44, + FortyFive = 45, + FortySix = 46, + FortySeven = 47, + FortyEight = 48, + FortyNine = 49, + Fifty = 50, + FiftyOne = 51, + FiftyTwo = 52, + FiftyThree = 53, + FiftyFour = 54, + FiftyFive = 55, + FiftySix = 56, + FiftySeven = 57, + FiftyEight = 58, + FiftyNine = 59, + Sixty = 60, + SixtyOne = 61, + SixtyTwo = 62, + SixtyThree = 63, + SixtyFour = 64, + SixtyFive = 65, + SixtySix = 66, + SixtySeven = 67, + SixtyEight = 68, + SixtyNine = 69, + Seventy = 70, + SeventyOne = 71, + SeventyTwo = 72, + SeventyThree = 73, + SeventyFour = 74, + SeventyFive = 75, + SeventySix = 76, + SeventySeven = 77, + SeventyEight = 78, + SeventyNine = 79, + Eighty = 80, + EightyOne = 81, + EightyTwo = 82, + EightyThree = 83, + EightyFour = 84, + EightyFive = 85, + EightySix = 86, + EightySeven = 87, + EightyEight = 88, + EightyNine = 89, + Ninety = 90, + NinetyOne = 91, + NinetyTwo = 92, + NinetyThree = 93, + NinetyFour = 94, + NinetyFive = 95, + NinetySix = 96, + NinetySeven = 97, + NinetyEight = 98, + NinetyNine = 99, + OneHundred = 100, + OneHundredOne = 101, + OneHundredTwo = 102, + OneHundredThree = 103, + OneHundredFour = 104, + OneHundredFive = 105, + OneHundredSix = 106, + OneHundredSeven = 107, + OneHundredEight = 108, + OneHundredNine = 109, + OneHundredTen = 110, + OneHundredEleven = 111, + OneHundredTwelve = 112, + OneHundredThirteen = 113, + OneHundredFourteen = 114, + OneHundredFifteen = 115, + OneHundredSixteen = 116, + OneHundredSeventeen = 117, + OneHundredEighteen = 118, + OneHundredNineteen = 119, + OneHundredTwenty = 120, + OneHundredTwentyOne = 121, + OneHundredTwentyTwo = 122, + OneHundredTwentyThree = 123, + OneHundredTwentyFour = 124, + OneHundredTwentyFive = 125, + OneHundredTwentySix = 126, + OneHundredTwentySeven = 127, + OneHundredTwentyEight = 128, + OneHundredTwentyNine = 129, + OneHundredThirty = 130, + OneHundredThirtyOne = 131, + OneHundredThirtyTwo = 132, + OneHundredThirtyThree = 133, + OneHundredThirtyFour = 134, + OneHundredThirtyFive = 135, + OneHundredThirtySix = 136, + OneHundredThirtySeven = 137, + OneHundredThirtyEight = 138, + OneHundredThirtyNine = 139, + OneHundredForty = 140, + OneHundredFortyOne = 141, + OneHundredFortyTwo = 142, + OneHundredFortyThree = 143, + OneHundredFortyFour = 144, + OneHundredFortyFive = 145, + OneHundredFortySix = 146, + OneHundredFortySeven = 147, + OneHundredFortyEight = 148, + OneHundredFortyNine = 149, + OneHundredFifty = 150, + OneHundredFiftyOne = 151, + OneHundredFiftyTwo = 152, + OneHundredFiftyThree = 153, + OneHundredFiftyFour = 154, + OneHundredFiftyFive = 155, + OneHundredFiftySix = 156, + OneHundredFiftySeven = 157, + OneHundredFiftyEight = 158, + OneHundredFiftyNine = 159, + OneHundredSixty = 160, + OneHundredSixtyOne = 161, + OneHundredSixtyTwo = 162, + OneHundredSixtyThree = 163, + OneHundredSixtyFour = 164, + OneHundredSixtyFive = 165, + OneHundredSixtySix = 166, + OneHundredSixtySeven = 167, + OneHundredSixtyEight = 168, + OneHundredSixtyNine = 169, + OneHundredSeventy = 170, + OneHundredSeventyOne = 171, + OneHundredSeventyTwo = 172, + OneHundredSeventyThree = 173, + OneHundredSeventyFour = 174, + OneHundredSeventyFive = 175, + OneHundredSeventySix = 176, + OneHundredSeventySeven = 177, + OneHundredSeventyEight = 178, + OneHundredSeventyNine = 179, + OneHundredEighty = 180, + OneHundredEightyOne = 181, + OneHundredEightyTwo = 182, + OneHundredEightyThree = 183, + OneHundredEightyFour = 184, + OneHundredEightyFive = 185, + OneHundredEightySix = 186, + OneHundredEightySeven = 187, + OneHundredEightyEight = 188, + OneHundredEightyNine = 189, + OneHundredNinety = 190, + OneHundredNinetyOne = 191, + OneHundredNinetyTwo = 192, + OneHundredNinetyThree = 193, + OneHundredNinetyFour = 194, + OneHundredNinetyFive = 195, + OneHundredNinetySix = 196, + OneHundredNinetySeven = 197, + OneHundredNinetyEight = 198, + OneHundredNinetyNine = 199, + TwoHundred = 200, + TwoHundredOne = 201, + TwoHundredTwo = 202, + TwoHundredThree = 203, + TwoHundredFour = 204, + TwoHundredFive = 205, + TwoHundredSix = 206, + TwoHundredSeven = 207, + TwoHundredEight = 208, + TwoHundredNine = 209, + TwoTen = 210, + TwoEleven = 211, + TwoTwelve = 212, + TwoThirteen = 213, + TwoFourteen = 214, + TwoFifteen = 215, + TwoSixteen = 216, + TwoSeventeen = 217, + TwoEighteen = 218, + TwoNineteen = 219, + TwoTwenty = 220, + TwoTwentyOne = 221, + TwoTwentyTwo = 222, + TwoTwentyThree = 223, + TwoTwentyFour = 224, + TwoTwentyFive = 225, + TwoTwentySix = 226, + TwoTwentySeven = 227, + TwoTwentyEight = 228, + TwoTwentyNine = 229, + TwoThirty = 230, + TwoThirtyOne = 231, + TwoThirtyTwo = 232, + TwoThirtyThree = 233, + TwoThirtyFour = 234, + TwoThirtyFive = 235, + TwoThirtySix = 236, + TwoThirtySeven = 237, + TwoThirtyEight = 238, + TwoThirtyNine = 239, + TwoForty = 240, + TwoFortyOne = 241, + TwoFortyTwo = 242, + TwoFortyThree = 243, + TwoFortyFour = 244, + TwoFortyFive = 245, + TwoFortySix = 246, + TwoFortySeven = 247, + TwoFortyEight = 248, + TwoFortyNine = 249, + TwoFifty = 250, + TwoFiftyOne = 251, + TwoFiftyTwo = 252, + TwoFiftyThree = 253, + TwoFiftyFour = 254, + TwoFiftyFive = 255, +} + +#[test] +fn enum_256_variants() { + check_top_encode_decode(Enum256Variants::Zero, &[][..]); + check_top_encode_decode(Enum256Variants::One, &[1u8][..]); + check_dep_encode_decode(Enum256Variants::TwoFiftyFive, &[255u8][..]); +} diff --git a/data/codec/tests/derive_hygiene.rs b/data/codec/tests/derive_hygiene.rs index 9013e2838c..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() {} @@ -51,6 +52,9 @@ pub struct Struct { pub another_byte: u8, pub uint_32: u32, pub uint_64: u64, + buffer: bool, // used to occur in derive implementation + dest: bool, // used to occur in derive implementation + h: bool, // used to occur in derive implementation } #[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, PartialEq, Eq, Clone, Debug)] @@ -78,6 +82,9 @@ enum EnumWithEverything { another_byte: u8, uint_32: u32, uint_64: u64, + buffer: bool, // used to occur in derive implementation + dest: bool, // used to occur in derive implementation + h: bool, // used to occur in derive implementation }, } 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/data/codec/tests/explicit_impl_struct_opt_field.rs b/data/codec/tests/explicit_impl_struct_opt_field.rs new file mode 100644 index 0000000000..7be9b0e2c7 --- /dev/null +++ b/data/codec/tests/explicit_impl_struct_opt_field.rs @@ -0,0 +1,67 @@ +use multiversx_sc_codec as codec; + +// Some structures with explicit encode/decode, for testing. +use codec::{ + test_util::check_top_encode_decode, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, + NestedDecodeInput, NestedEncode, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, +}; +use core::fmt::Debug; + +/// Example of how to have an optional, or variable-length field at the end of a structure. +/// +/// Careful! This is non-standard and is not really friendly to nested encoding. +#[derive(PartialEq, Eq, Debug, Clone)] +pub struct StructOptField { + pub field: u32, + pub opt_items: Vec, +} + +impl TopEncode for StructOptField { + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + let mut nested_buffer = output.start_nested_encode(); + self.field.dep_encode_or_handle_err(&mut nested_buffer, h)?; + for opt_item in &self.opt_items { + opt_item.dep_encode_or_handle_err(&mut nested_buffer, h)?; + } + output.finalize_nested_encode(nested_buffer); + Ok(()) + } +} + +impl TopDecode for StructOptField { + fn top_decode_or_handle_err(input: I, h: H) -> Result + where + I: TopDecodeInput, + H: DecodeErrorHandler, + { + let mut nested_buffer = input.into_nested_buffer(); + let field = u32::dep_decode_or_handle_err(&mut nested_buffer, h)?; + let mut opt_items = Vec::new(); + while !nested_buffer.is_depleted() { + opt_items.push(u8::dep_decode_or_handle_err(&mut nested_buffer, h)?); + } + Ok(StructOptField { field, opt_items }) + } +} + +#[test] +fn test_struct_opt_field_1() { + let test = StructOptField { + field: 0x01020304, + opt_items: vec![], + }; + check_top_encode_decode(test, &[1, 2, 3, 4]); +} + +#[test] +fn test_struct_opt_field_2() { + let test = StructOptField { + field: 0x01020304, + opt_items: vec![5, 6, 7], + }; + check_top_encode_decode(test, &[1, 2, 3, 4, 5, 6, 7]); +} diff --git a/data/human-readable/Cargo.toml b/data/human-readable/Cargo.toml index 500d566244..e86f655417 100644 --- a/data/human-readable/Cargo.toml +++ b/data/human-readable/Cargo.toml @@ -17,9 +17,9 @@ categories = ["cryptography::cryptocurrencies", "development-tools"] [dependencies] [dependencies.multiversx-sc-scenario] -version = "=0.44.0" +version = "=0.53.0" path = "../../framework/scenario" -[dependencies.multiversx-sc-meta] -version = "=0.44.0" -path = "../../framework/meta" +[dependencies.multiversx-sc-meta-lib] +version = "=0.53.0" +path = "../../framework/meta-lib" diff --git a/data/human-readable/src/interpret.rs b/data/human-readable/src/interpret.rs index 6b8b4caaf2..1ef0cd803e 100644 --- a/data/human-readable/src/interpret.rs +++ b/data/human-readable/src/interpret.rs @@ -1,8 +1,8 @@ use std::{error::Error, fmt::Display}; use crate::multiversx_sc::abi::{TypeContents, TypeDescription}; -use multiversx_sc_meta::abi_json::ContractAbiJson; -use multiversx_sc_scenario::num_bigint::BigUint; +use multiversx_sc_meta_lib::abi_json::ContractAbiJson; +use multiversx_sc_scenario::{multiversx_sc::abi::TypeNames, num_bigint::BigUint}; use crate::{AnyValue, SingleValue::UnsignedNumber}; @@ -12,12 +12,13 @@ pub fn interpret_value_according_to_abi( contract_abi: &ContractAbiJson, // TODO: will need to convert to high-level ContractAbi first, this is just a prototype ) -> Result> { let type_description = if let Some(type_description_json) = contract_abi.types.get(type_name) { - type_description_json.to_type_description(type_name) + type_description_json.to_type_description(TypeNames::abi_only(type_name.to_owned())) } else { TypeDescription { docs: Vec::new(), - name: type_name.to_string(), + names: TypeNames::abi_only(type_name.to_owned()), contents: TypeContents::NotSpecified, + macro_attributes: Vec::new(), } }; interpret_any_value(input, &type_description) @@ -28,7 +29,7 @@ pub fn interpret_any_value( type_description: &TypeDescription, ) -> Result> { match &type_description.contents { - TypeContents::NotSpecified => interpret_single_value(input, type_description.name.as_str()), + TypeContents::NotSpecified => interpret_single_value(input, &type_description.names.abi), TypeContents::Enum(_) => todo!(), TypeContents::Struct(_) => todo!(), TypeContents::ExplicitEnum(_) => panic!("not supported"), diff --git a/data/human-readable/src/lib.rs b/data/human-readable/src/lib.rs index 613e656b7e..1153a44138 100644 --- a/data/human-readable/src/lib.rs +++ b/data/human-readable/src/lib.rs @@ -1,6 +1,6 @@ mod interpret; mod value; -use multiversx_sc_scenario::multiversx_sc; pub use interpret::*; +use multiversx_sc_scenario::multiversx_sc; pub use value::*; diff --git a/data/human-readable/tests/single_value_basic_test.rs b/data/human-readable/tests/single_value_basic_test.rs index 0728a30902..575668e814 100644 --- a/data/human-readable/tests/single_value_basic_test.rs +++ b/data/human-readable/tests/single_value_basic_test.rs @@ -1,5 +1,5 @@ use multiversx_sc_codec_human_readable::interpret_value_according_to_abi; -use multiversx_sc_meta::abi_json::{deserialize_abi_from_json, ContractAbiJson}; +use multiversx_sc_meta_lib::abi_json::{deserialize_abi_from_json, ContractAbiJson}; use multiversx_sc_scenario::multiversx_sc::codec::top_encode_to_vec_u8; const TEST_ABI_JSON: &str = r#"{ diff --git a/framework/base/Cargo.toml b/framework/base/Cargo.toml index 09fbe0c73c..0402d16f81 100644 --- a/framework/base/Cargo.toml +++ b/framework/base/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "multiversx-sc" -version = "0.44.0" +version = "0.53.0" edition = "2021" +rust-version = "1.78" authors = ["Andrei Marinica ", "MultiversX "] license = "GPL-3.0-only" @@ -18,23 +19,21 @@ all-features = true [features] num-bigint = ["multiversx-sc-codec/num-bigint"] -alloc = ["multiversx-sc-codec/alloc"] -promises = [] -managed-map = [] -back-transfers = [] +alloc = [] +managed-buffer-builder-cached = [] esdt-token-payment-legacy-decode = [] [dependencies] -hashbrown = "0.14.2" -hex-literal = "0.4.1" -bitflags = "1.3.2" -num-traits = { version = "0.2", default-features = false } +hex-literal = "=0.4.1" +bitflags = "=2.6.0" +num-traits = { version = "=0.2.19", default-features = false } +unwrap-infallible = "0.1.5" [dependencies.multiversx-sc-derive] -version = "=0.44.0" +version = "=0.53.0" path = "../derive" [dependencies.multiversx-sc-codec] -version = "=0.18.1" +version = "=0.21.0" path = "../../data/codec" features = ["derive"] diff --git a/framework/base/src/abi.rs b/framework/base/src/abi.rs index b79ae26124..16e712ad98 100644 --- a/framework/base/src/abi.rs +++ b/framework/base/src/abi.rs @@ -4,18 +4,45 @@ 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(), + } + } + + pub fn abi_only(abi_name: alloc::string::String) -> Self { + TypeNames { + abi: abi_name, + 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..a10755d3e8 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,28 @@ +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, +{ +} + 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 +32,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 +73,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 - $($name: TypeAbi,)+ + $($t: TypeAbiFrom<$u>,)+ + {} + + impl<$($t),+> TypeAbi for crate::codec::multi_types::$mval_struct<$($t,)+> + where + $($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 +93,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 +126,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 +141,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 00a86e9578..16dda2c8b9 100644 --- a/framework/base/src/abi/type_description_container.rs +++ b/framework/base/src/abi/type_description_container.rs @@ -1,5 +1,5 @@ use super::*; -use hashbrown::HashMap; +use multiversx_sc_codec::Vec; pub trait TypeDescriptionContainer { fn new() -> Self; @@ -8,34 +8,44 @@ 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 HashMap); +pub struct TypeDescriptionContainerImpl(pub Vec<(TypeNames, TypeDescription)>); impl TypeDescriptionContainer for TypeDescriptionContainerImpl { fn new() -> Self { - TypeDescriptionContainerImpl(HashMap::new()) + TypeDescriptionContainerImpl(Vec::new()) } fn contains_type(&self, type_name: &str) -> bool { - self.0.contains_key(type_name) + self.0 + .iter() + .any(|(existing_type_name, _)| existing_type_name.abi == type_name) } - fn insert(&mut self, type_name: TypeName, type_description: TypeDescription) { - self.0.insert(type_name, type_description); + 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_names, type_description)); + } } fn insert_all(&mut self, other: &Self) { for (key, value) in other.0.iter() { - self.0.insert(key.clone(), value.clone()); + self.insert(key.clone(), value.clone()); } } } 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/blockchain_api.rs b/framework/base/src/api/blockchain_api.rs index a879c8cdce..e33beaaa4b 100644 --- a/framework/base/src/api/blockchain_api.rs +++ b/framework/base/src/api/blockchain_api.rs @@ -146,4 +146,12 @@ pub trait BlockchainApiImpl: ManagedTypeApiImpl { &self, token_id_handle: Self::ManagedBufferHandle, ) -> EsdtLocalRoleFlags; + + fn managed_get_code_metadata( + &self, + address_handle: Self::ManagedBufferHandle, + response_handle: Self::ManagedBufferHandle, + ); + + fn managed_is_builtin_function(&self, function_name_handle: Self::ManagedBufferHandle) -> bool; } 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/crypto_api.rs b/framework/base/src/api/crypto_api.rs index 3c5c374a87..f6eaf80fe4 100644 --- a/framework/base/src/api/crypto_api.rs +++ b/framework/base/src/api/crypto_api.rs @@ -44,7 +44,7 @@ pub trait CryptoApiImpl: ManagedTypeApiImpl { key: Self::ManagedBufferHandle, message: Self::ManagedBufferHandle, signature: Self::ManagedBufferHandle, - ) -> bool; + ); fn verify_ed25519_managed( &self, @@ -76,4 +76,25 @@ pub trait CryptoApiImpl: ManagedTypeApiImpl { s: Self::ManagedBufferHandle, dest: Self::ManagedBufferHandle, ); + + fn verify_secp256r1_managed( + &self, + key: Self::ManagedBufferHandle, + message: Self::ManagedBufferHandle, + signature: Self::ManagedBufferHandle, + ); + + fn verify_bls_signature_share_managed( + &self, + key: Self::ManagedBufferHandle, + message: Self::ManagedBufferHandle, + signature: Self::ManagedBufferHandle, + ); + + fn verify_bls_aggregated_signature_managed( + &self, + key: Self::ManagedBufferHandle, + message: Self::ManagedBufferHandle, + signature: Self::ManagedBufferHandle, + ); } diff --git a/framework/base/src/api/endpoint_arg_api.rs b/framework/base/src/api/endpoint_arg_api.rs index 7779d3106c..4d80935f52 100644 --- a/framework/base/src/api/endpoint_arg_api.rs +++ b/framework/base/src/api/endpoint_arg_api.rs @@ -20,8 +20,6 @@ pub trait EndpointArgumentApi: HandleTypeInfo { /// Interface to only be used by code generated by the macros. /// The smart contract code doesn't have access to these methods directly. pub trait EndpointArgumentApiImpl: ErrorApi + ManagedTypeApi { - fn endpoint_init(&self) {} - fn get_num_arguments(&self) -> i32; fn load_argument_managed_buffer(&self, arg_index: i32, dest: Self::ManagedBufferHandle); @@ -61,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()) } } @@ -71,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..2baee82ef7 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()); } } @@ -52,7 +52,7 @@ pub trait BigIntApiImpl: HandleTypeInfo + ErrorApi { fn bi_sqrt(&self, dest: Self::BigIntHandle, x: Self::BigIntHandle); fn bi_pow(&self, dest: Self::BigIntHandle, x: Self::BigIntHandle, y: Self::BigIntHandle); - fn bi_log2(&self, x: Self::BigIntHandle) -> u32; + fn bi_log2(&self, x: Self::BigIntHandle) -> i32; fn bi_and(&self, dest: Self::BigIntHandle, x: Self::BigIntHandle, y: Self::BigIntHandle); fn bi_or(&self, dest: Self::BigIntHandle, x: Self::BigIntHandle, y: Self::BigIntHandle); diff --git a/framework/base/src/api/managed_types/const_handles.rs b/framework/base/src/api/managed_types/const_handles.rs index bd92bcc1db..283d9c55c6 100644 --- a/framework/base/src/api/managed_types/const_handles.rs +++ b/framework/base/src/api/managed_types/const_handles.rs @@ -13,6 +13,7 @@ pub const CALL_VALUE_SINGLE_ESDT: RawHandle = -13; pub const BIG_INT_TEMPORARY_1: RawHandle = -14; pub const BIG_INT_TEMPORARY_2: RawHandle = -15; +pub const BIG_FLOAT_TEMPORARY: RawHandle = -16; /// WARNING! With the current VM this still needs to be initialized before use. pub const MBUF_CONST_EMPTY: RawHandle = -20; @@ -22,7 +23,19 @@ pub const CALLBACK_CLOSURE_ARGS_BUFFER: RawHandle = -23; pub const MBUF_TEMPORARY_1: RawHandle = -25; pub const MBUF_TEMPORARY_2: RawHandle = -26; -pub const NEW_HANDLE_START_FROM: RawHandle = -100; // > -100 reserved for APIs +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 +pub const SCALING_FACTOR_START: RawHandle = -100; +pub const SCALING_FACTOR_LENGTH: usize = 64; /// Used as a flag. Do not use as a regular handle. pub const MANAGED_OPTION_NONE: RawHandle = i32::MAX - 1; + +pub const fn get_scaling_factor_handle(decimals: usize) -> i32 { + let decimals_i32 = decimals as i32; + SCALING_FACTOR_START - decimals_i32 +} diff --git a/framework/base/src/api/managed_types/static_var_api.rs b/framework/base/src/api/managed_types/static_var_api.rs index 59f65dc3b6..8eaf474ef3 100644 --- a/framework/base/src/api/managed_types/static_var_api.rs +++ b/framework/base/src/api/managed_types/static_var_api.rs @@ -31,4 +31,8 @@ pub trait StaticVarApiImpl { fn set_call_value_multi_esdt_handle(&self, handle: RawHandle); fn get_call_value_multi_esdt_handle(&self) -> RawHandle; + + fn is_scaling_factor_cached(&self, decimals: usize) -> bool; + + fn set_scaling_factor_cached(&self, decimals: usize); } diff --git a/framework/base/src/api/uncallable/big_int_api_uncallable.rs b/framework/base/src/api/uncallable/big_int_api_uncallable.rs index 46b997926d..9615633f3b 100644 --- a/framework/base/src/api/uncallable/big_int_api_uncallable.rs +++ b/framework/base/src/api/uncallable/big_int_api_uncallable.rs @@ -59,7 +59,7 @@ impl BigIntApiImpl for super::UncallableApi { unreachable!() } - fn bi_log2(&self, _x: Self::BigIntHandle) -> u32 { + fn bi_log2(&self, _x: Self::BigIntHandle) -> i32 { unreachable!() } diff --git a/framework/base/src/api/uncallable/blockchain_api_uncallable.rs b/framework/base/src/api/uncallable/blockchain_api_uncallable.rs index 03d7d61aa5..1838659a06 100644 --- a/framework/base/src/api/uncallable/blockchain_api_uncallable.rs +++ b/framework/base/src/api/uncallable/blockchain_api_uncallable.rs @@ -157,4 +157,19 @@ impl BlockchainApiImpl for UncallableApi { ) -> crate::types::EsdtLocalRoleFlags { unreachable!() } + + fn managed_get_code_metadata( + &self, + _address_handle: Self::ManagedBufferHandle, + _response_handle: Self::ManagedBufferHandle, + ) { + unreachable!() + } + + fn managed_is_builtin_function( + &self, + _function_name_handle: Self::ManagedBufferHandle, + ) -> bool { + unreachable!() + } } diff --git a/framework/base/src/api/uncallable/crypto_api_uncallable.rs b/framework/base/src/api/uncallable/crypto_api_uncallable.rs index 59195618c9..fe0547c5d7 100644 --- a/framework/base/src/api/uncallable/crypto_api_uncallable.rs +++ b/framework/base/src/api/uncallable/crypto_api_uncallable.rs @@ -42,7 +42,7 @@ impl CryptoApiImpl for UncallableApi { _key: Self::ManagedBufferHandle, _message: Self::ManagedBufferHandle, _signature: Self::ManagedBufferHandle, - ) -> bool { + ) { unreachable!() } @@ -82,4 +82,31 @@ impl CryptoApiImpl for UncallableApi { ) { unreachable!() } + + fn verify_secp256r1_managed( + &self, + _key: Self::ManagedBufferHandle, + _message: Self::ManagedBufferHandle, + _signature: Self::ManagedBufferHandle, + ) { + unreachable!() + } + + fn verify_bls_signature_share_managed( + &self, + _key: Self::ManagedBufferHandle, + _message: Self::ManagedBufferHandle, + _signature: Self::ManagedBufferHandle, + ) { + unreachable!() + } + + fn verify_bls_aggregated_signature_managed( + &self, + _key: Self::ManagedBufferHandle, + _message: Self::ManagedBufferHandle, + _signature: Self::ManagedBufferHandle, + ) { + unreachable!() + } } diff --git a/framework/base/src/api/uncallable/static_var_api_uncallable.rs b/framework/base/src/api/uncallable/static_var_api_uncallable.rs index 3ed707e06b..1da3c772cf 100644 --- a/framework/base/src/api/uncallable/static_var_api_uncallable.rs +++ b/framework/base/src/api/uncallable/static_var_api_uncallable.rs @@ -56,4 +56,12 @@ impl StaticVarApiImpl for UncallableApi { fn get_call_value_multi_esdt_handle(&self) -> RawHandle { unreachable!() } + + fn is_scaling_factor_cached(&self, _decimals: usize) -> bool { + unreachable!() + } + + fn set_scaling_factor_cached(&self, _decimals: usize) { + unreachable!() + } } 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.rs b/framework/base/src/contract_base/wrappers.rs index 4a32bf0a7b..e90e5dbcc2 100644 --- a/framework/base/src/contract_base/wrappers.rs +++ b/framework/base/src/contract_base/wrappers.rs @@ -1,6 +1,5 @@ mod blockchain_wrapper; mod call_value_wrapper; -mod callback_args_wrapper; mod crypto_wrapper; mod error_helper; mod send_raw_wrapper; @@ -10,7 +9,6 @@ mod storage_raw_wrapper; pub use blockchain_wrapper::BlockchainWrapper; pub use call_value_wrapper::CallValueWrapper; -pub use callback_args_wrapper::CallbackArgApiWrapper; pub use crypto_wrapper::CryptoWrapper; pub use error_helper::ErrorHelper; pub use send_raw_wrapper::SendRawWrapper; diff --git a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs index 79aa391b0d..684e8524f2 100644 --- a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs @@ -10,8 +10,9 @@ use crate::{ err_msg::{ONLY_OWNER_CALLER, ONLY_USER_ACCOUNT_CALLER}, storage::{self}, types::{ - BigUint, EgldOrEsdtTokenIdentifier, EsdtLocalRoleFlags, EsdtTokenData, EsdtTokenType, - ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedType, ManagedVec, TokenIdentifier, + BackTransfers, BigUint, CodeMetadata, EgldOrEsdtTokenIdentifier, EsdtLocalRoleFlags, + EsdtTokenData, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedType, + ManagedVec, TokenIdentifier, }, }; @@ -76,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()); } } @@ -84,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()); } } @@ -134,11 +135,27 @@ where BigUint::from_handle(handle) } + #[inline] + pub fn get_code_metadata(&self, address: &ManagedAddress) -> CodeMetadata { + let mbuf_temp_1: A::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); + A::blockchain_api_impl() + .managed_get_code_metadata(address.get_handle(), mbuf_temp_1.clone()); + let mut buffer = [0u8; 2]; + ManagedBuffer::::from_handle(mbuf_temp_1).load_to_byte_array(&mut buffer); + CodeMetadata::from(buffer) + } + + #[inline] + pub fn is_builtin_function(&self, function_name: &ManagedBuffer) -> bool { + A::blockchain_api_impl().managed_is_builtin_function(function_name.get_handle()) + } + #[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) }, ) @@ -347,8 +364,7 @@ where /// Works after: /// - synchronous calls /// - asynchronous calls too, in callbacks. - #[cfg(feature = "back-transfers")] - pub fn get_back_transfers(&self) -> crate::types::BackTransfers { + pub fn get_back_transfers(&self) -> BackTransfers { let esdt_transfer_value_handle: A::BigIntHandle = use_raw_handle(A::static_var_api_impl().next_handle()); let call_value_handle: A::BigIntHandle = @@ -359,7 +375,7 @@ where call_value_handle.get_raw_handle(), ); - crate::types::BackTransfers { + BackTransfers { total_egld_amount: BigUint::from_raw_handle(call_value_handle.get_raw_handle()), esdt_payments: ManagedVec::from_raw_handle(esdt_transfer_value_handle.get_raw_handle()), } diff --git a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs index 520ee4228e..3006805ef0 100644 --- a/framework/base/src/contract_base/wrappers/call_value_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/call_value_wrapper.rs @@ -7,8 +7,9 @@ use crate::{ }, err_msg, types::{ - BigUint, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, - EsdtTokenPayment, ManagedRef, ManagedVec, TokenIdentifier, + BigUint, ConstDecimals, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, + EgldOrMultiEsdtPayment, EsdtTokenPayment, ManagedDecimal, ManagedRef, ManagedVec, + TokenIdentifier, }, }; @@ -43,6 +44,13 @@ where unsafe { ManagedRef::wrap_handle(call_value_handle) } } + /// Returns the EGLD call value from the VM as ManagedDecimal + pub fn egld_decimal(&self) -> ManagedDecimal> { + ManagedDecimal::>::const_decimals_from_raw( + self.egld_value().clone_value(), + ) + } + /// Returns all ESDT transfers that accompany this SC call. /// Will return 0 results if nothing was transfered, or just EGLD. /// Fully managed underlying types, very efficient. diff --git a/framework/base/src/contract_base/wrappers/callback_args_wrapper.rs b/framework/base/src/contract_base/wrappers/callback_args_wrapper.rs deleted file mode 100644 index 2baef24c70..0000000000 --- a/framework/base/src/contract_base/wrappers/callback_args_wrapper.rs +++ /dev/null @@ -1,100 +0,0 @@ -use core::marker::PhantomData; - -use crate::{ - api::{ - const_handles, use_raw_handle, EndpointArgumentApi, EndpointArgumentApiImpl, ErrorApi, - HandleTypeInfo, ManagedBufferApiImpl, ManagedTypeApi, StaticVarApi, VMApi, - }, - types::{ManagedArgBuffer, ManagedBuffer, ManagedType}, -}; - -/// Replaces the EndpointArgumentApi inside a promises callback, -/// and causes it to read arguments from the callback data instead of the regular tx input. -#[derive(Clone, Default)] -pub struct CallbackArgApiWrapper { - _phantom: PhantomData, -} - -impl CallbackArgApiWrapper { - pub fn new() -> Self { - CallbackArgApiWrapper { - _phantom: PhantomData, - } - } -} - -impl HandleTypeInfo for CallbackArgApiWrapper -where - A: VMApi, -{ - type ManagedBufferHandle = ::ManagedBufferHandle; - - type BigIntHandle = ::BigIntHandle; - - type BigFloatHandle = ::BigFloatHandle; - - type EllipticCurveHandle = ::EllipticCurveHandle; - - type ManagedMapHandle = ::ManagedMapHandle; -} - -impl ErrorApi for CallbackArgApiWrapper { - type ErrorApiImpl = A::ErrorApiImpl; - - fn error_api_impl() -> Self::ErrorApiImpl { - A::error_api_impl() - } -} - -impl StaticVarApi for CallbackArgApiWrapper { - type StaticVarApiImpl = A::StaticVarApiImpl; - - fn static_var_api_impl() -> Self::StaticVarApiImpl { - A::static_var_api_impl() - } -} - -impl ManagedTypeApi for CallbackArgApiWrapper { - type ManagedTypeApiImpl = A::ManagedTypeApiImpl; - - fn managed_type_impl() -> Self::ManagedTypeApiImpl { - A::managed_type_impl() - } -} - -impl EndpointArgumentApi for CallbackArgApiWrapper { - type EndpointArgumentApiImpl = Self; - - fn argument_api_impl() -> Self::EndpointArgumentApiImpl { - Self::new() - } -} - -impl EndpointArgumentApiImpl for CallbackArgApiWrapper { - fn endpoint_init(&self) { - A::argument_api_impl() - .load_callback_closure_buffer(use_raw_handle(const_handles::MBUF_TEMPORARY_1)); - let cb_closure_args_serialized = - ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); - let mut cb_closure_args_buffer = - ManagedArgBuffer::::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER); - cb_closure_args_buffer.deserialize_overwrite(cb_closure_args_serialized); - } - - fn get_num_arguments(&self) -> i32 { - ManagedArgBuffer::::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER).len() - as i32 - } - - fn load_argument_managed_buffer(&self, arg_index: i32, dest: Self::ManagedBufferHandle) { - let cb_closure_args_buffer = - ManagedArgBuffer::::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER); - let item_buffer = cb_closure_args_buffer.get(arg_index as usize); - A::managed_type_impl().mb_overwrite(dest.clone(), &[]); - A::managed_type_impl().mb_append(dest, item_buffer.get_handle()); - } - - fn load_callback_closure_buffer(&self, dest: Self::ManagedBufferHandle) { - A::argument_api_impl().load_callback_closure_buffer(dest); - } -} diff --git a/framework/base/src/contract_base/wrappers/crypto_wrapper.rs b/framework/base/src/contract_base/wrappers/crypto_wrapper.rs index c314899eaa..369cca1a63 100644 --- a/framework/base/src/contract_base/wrappers/crypto_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/crypto_wrapper.rs @@ -5,7 +5,7 @@ use crate::{ use_raw_handle, CryptoApi, CryptoApiImpl, StaticVarApiImpl, KECCAK256_RESULT_LEN, SHA256_RESULT_LEN, }, - types::{ManagedBuffer, ManagedByteArray, ManagedType, MessageHashType}, + types::{ManagedBuffer, ManagedByteArray, ManagedType, ManagedVec, MessageHashType}, }; #[derive(Default)] @@ -61,7 +61,7 @@ where key: &ManagedBuffer, message: &ManagedBuffer, signature: &ManagedBuffer, - ) -> bool { + ) { A::crypto_api_impl().verify_bls_managed( key.get_handle(), message.get_handle(), @@ -69,7 +69,9 @@ where ) } - /// Will crash if the verification fails. + /// Calls the Vm to verify ed25519 signature. + /// + /// Does not return result, will fail tx directly! /// /// The error comes straight form the VM, the message is "invalid signature". pub fn verify_ed25519( @@ -129,4 +131,52 @@ where ); ManagedBuffer::from_handle(new_handle) } + + /// Calls the Vm to verify secp256r1 signature. + /// + /// Does not return result, will fail tx directly! + pub fn verify_secp256r1( + &self, + key: &ManagedBuffer, + message: &ManagedBuffer, + signature: &ManagedBuffer, + ) { + A::crypto_api_impl().verify_secp256r1_managed( + key.get_handle(), + message.get_handle(), + signature.get_handle(), + ) + } + + /// Calls the Vm to verify BLS signature share. + /// + /// Does not return result, will fail tx directly! + pub fn verify_bls_signature_share( + &self, + key: &ManagedBuffer, + message: &ManagedBuffer, + signature: &ManagedBuffer, + ) { + A::crypto_api_impl().verify_bls_signature_share_managed( + key.get_handle(), + message.get_handle(), + signature.get_handle(), + ) + } + + /// Calls the Vm to verify BLS aggregated signature. + /// + /// Does not return result, will fail tx directly! + pub fn verify_bls_aggregated_signature( + &self, + keys: &ManagedVec>, + message: &ManagedBuffer, + signature: &ManagedBuffer, + ) { + A::crypto_api_impl().verify_bls_aggregated_signature_managed( + keys.get_handle(), + message.get_handle(), + signature.get_handle(), + ) + } } 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..7417d6ca52 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,8 @@ use core::marker::PhantomData; +use unwrap_infallible::UnwrapInfallible; + +use crate::api::HandleConstraints; use crate::codec::{TopDecode, TopEncode}; use crate::{ @@ -63,9 +66,11 @@ 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::::new(key.get_handle().get_raw_handle_unchecked()), + ) + .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..361775d5f9 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,35 @@ 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_1: &str = "storage decode error (key: "; +pub const STORAGE_DECODE_ERROR_2: &str = "): "; +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 UNSIGNED_NEGATIVE: &str = "cannot convert to unsigned, number is negative"; pub const DESERIALIZATION_INVALID_BYTE: &str = "call data deserialization error: not a valid byte"; pub const DESERIALIZATION_NOT_32_BYTES: &str = @@ -48,14 +49,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_impl_bytes.rs b/framework/base/src/formatter/formatter_impl_bytes.rs index 6fb525bb86..ca3f2f0b41 100644 --- a/framework/base/src/formatter/formatter_impl_bytes.rs +++ b/framework/base/src/formatter/formatter_impl_bytes.rs @@ -1,4 +1,7 @@ -use super::{FormatByteReceiver, SCBinary, SCDisplay, SCLowerHex}; +use super::{ + hex_util::{byte_to_binary_digits, encode_bytes_as_hex}, + FormatByteReceiver, SCBinary, SCDisplay, SCLowerHex, +}; impl SCDisplay for &[u8] { fn fmt(&self, f: &mut F) { @@ -8,12 +11,14 @@ impl SCDisplay for &[u8] { impl SCLowerHex for &[u8] { fn fmt(&self, f: &mut F) { - f.append_bytes(self); + f.append_bytes(encode_bytes_as_hex(self).as_bytes()); } } impl SCBinary for &[u8] { fn fmt(&self, f: &mut F) { - f.append_bytes(self); + for b in self.iter() { + f.append_bytes(&byte_to_binary_digits(*b)); + } } } 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 1766e0ec78..fca34c9886 100644 --- a/framework/base/src/io/arg_nested_tuple.rs +++ b/framework/base/src/io/arg_nested_tuple.rs @@ -1,13 +1,15 @@ -use super::{EndpointDynArgLoader, EndpointSingleArgLoader}; +use unwrap_infallible::UnwrapInfallible; + +use super::{EndpointDynArgLoader, EndpointSingleArgLoader, ManagedResultArgLoader}; use crate::{ api::{ - EndpointArgumentApi, EndpointArgumentApiImpl, ErrorApi, ErrorApiImpl, ManagedTypeApi, - StaticVarApiImpl, VMApi, + const_handles, use_raw_handle, EndpointArgumentApi, EndpointArgumentApiImpl, ErrorApi, + ErrorApiImpl, ManagedTypeApi, StaticVarApiImpl, VMApi, }, codec::{DecodeError, TopDecodeMulti, TopDecodeMultiInput}, - contract_base::CallbackArgApiWrapper, err_msg, io::{ArgErrorHandler, ArgId}, + types::{ManagedArgBuffer, ManagedBuffer, ManagedType}, }; /// Argument count cannot change during execution, and it can get queried multiple times, @@ -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. @@ -177,10 +176,10 @@ where pub fn load_callback_closure_args(arg_names: N::ArgNames) -> N where AA: VMApi, - N: ArgNestedTuple>, + N: ArgNestedTuple, { - CallbackArgApiWrapper::::argument_api_impl().endpoint_init(); - load_endpoint_args::, N>(arg_names) + let loader = callback_closure_args_loader::(); + N::next_multi_arg(loader, arg_names) } /// Currently used for the callback closure. No distinction there for single values. @@ -194,3 +193,18 @@ where init_arguments_static_data::(); N::next_multi_arg(loader, arg_names) } + +fn callback_closure_args_loader() -> ManagedResultArgLoader +where + AA: VMApi, +{ + AA::argument_api_impl() + .load_callback_closure_buffer(use_raw_handle(const_handles::MBUF_TEMPORARY_1)); + let cb_closure_args_serialized = + ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); + let mut cb_closure_args_buffer = + ManagedArgBuffer::::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER); + cb_closure_args_buffer.deserialize_overwrite(cb_closure_args_serialized); + + ManagedResultArgLoader::new(cb_closure_args_buffer.into_vec_of_buffers()) +} diff --git a/framework/base/src/io/finish.rs b/framework/base/src/io/finish.rs index f44cc02c5e..69bf879b1d 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); @@ -83,7 +86,7 @@ where FA::finish_api_impl().finish_managed_buffer_raw(managed_buffer.handle.clone()); Ok(()) } else if let Some(big_uint) = value.try_cast_ref::>() { - FA::finish_api_impl().finish_big_uint_raw(big_uint.handle.clone()); + FA::finish_api_impl().finish_big_uint_raw(big_uint.value.handle.clone()); Ok(()) } else if let Some(big_int) = value.try_cast_ref::>() { FA::finish_api_impl().finish_big_int_raw(big_int.handle.clone()); @@ -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 b90cb89409..3b8fc6c0f5 100644 --- a/framework/base/src/lib.rs +++ b/framework/base/src/lib.rs @@ -1,17 +1,6 @@ #![no_std] -#![feature(never_type)] -#![feature(exhaustive_patterns)] -#![feature(try_trait_v2)] -#![feature(control_flow_enum)] -#![allow(clippy::type_complexity)] #![allow(deprecated)] -#![feature(maybe_uninit_uninit_array)] -#![feature(maybe_uninit_array_assume_init)] -#![feature(negative_impls)] -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] -#![feature(slice_partition_dedup)] -#![feature(is_sorted)] + pub use multiversx_sc_derive::{self as derive, contract, module, proxy}; // re-export basic heap types @@ -27,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; @@ -36,8 +24,20 @@ 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::*; 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; + +/// Conveniently groups all imports required for deriving framework-related traits for types. +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 159b639195..86c963a057 100644 --- a/framework/base/src/macros.rs +++ b/framework/base/src/macros.rs @@ -5,32 +5,7 @@ #[macro_export] macro_rules! imports { () => { - use core::ops::{ - Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, - DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, - SubAssign, - }; - use multiversx_sc::{ - 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, require_old, sc_error, sc_format, sc_panic, sc_print, - storage::mappers::*, - types::{ - SCResult::{Err, Ok}, - *, - }, - }; + use multiversx_sc::imports::*; }; } @@ -38,18 +13,15 @@ macro_rules! imports { #[macro_export] macro_rules! derive_imports { () => { - use multiversx_sc::{ - codec, - codec::derive::{ - NestedDecode, NestedEncode, TopDecode, TopDecodeOrDefault, TopEncode, - TopEncodeOrDefault, - }, - derive::{ManagedVecItem, TypeAbi}, - }; + use multiversx_sc::derive_imports::*; }; } /// Compact way of returning a static error message. +#[deprecated( + since = "0.48.0", + note = "Use `sc_panic!` instead, which terminates immediately." +)] #[macro_export] macro_rules! sc_error { ($s:expr) => { @@ -74,6 +46,10 @@ macro_rules! sc_error { /// } /// # } /// ``` +#[deprecated( + since = "0.48.0", + note = "Use `require!` instead, which terminates immediately." +)] #[macro_export] macro_rules! require_old { ($expression:expr, $error_msg:expr) => { @@ -87,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()); }}; @@ -147,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() }}; @@ -197,7 +173,7 @@ macro_rules! sc_try { macro_rules! only_owner { ($trait_self: expr, $error_msg:expr) => { if ($trait_self.blockchain().get_caller() != $trait_self.blockchain().get_owner_address()) { - return sc_error!($error_msg); + return multiversx_sc::sc_error!($error_msg); } }; } diff --git a/framework/base/src/storage/mappers.rs b/framework/base/src/storage/mappers.rs index a34a175352..d04b26e3e2 100644 --- a/framework/base/src/storage/mappers.rs +++ b/framework/base/src/storage/mappers.rs @@ -4,6 +4,7 @@ mod linked_list_mapper; mod map_mapper; mod map_storage_mapper; mod mapper; +mod ordered_binary_tree_mapper; mod queue_mapper; mod set_mapper; mod single_value_mapper; @@ -14,12 +15,15 @@ mod user_mapper; mod vec_mapper; mod whitelist_mapper; -pub use address_to_id_mapper::{AddressId, AddressToIdMapper}; +pub use address_to_id_mapper::{AddressId, AddressToIdMapper, NULL_ID}; pub use bi_di_mapper::BiDiMapper; pub use linked_list_mapper::{LinkedListMapper, LinkedListNode}; pub use map_mapper::MapMapper; pub use map_storage_mapper::MapStorageMapper; -pub use mapper::{StorageClearable, StorageMapper}; +pub use mapper::{StorageClearable, StorageMapper, StorageMapperFromAddress}; +pub use ordered_binary_tree_mapper::{ + NodeId, OrderedBinaryTreeMapper, OrderedBinaryTreeNode, NULL_NODE_ID, +}; pub use queue_mapper::QueueMapper; pub use set_mapper::SetMapper; pub use single_value_mapper::{SingleValue, SingleValueMapper}; diff --git a/framework/base/src/storage/mappers/address_to_id_mapper.rs b/framework/base/src/storage/mappers/address_to_id_mapper.rs index 2d02854d12..44c1237407 100644 --- a/framework/base/src/storage/mappers/address_to_id_mapper.rs +++ b/framework/base/src/storage/mappers/address_to_id_mapper.rs @@ -1,15 +1,14 @@ use core::marker::PhantomData; -use super::StorageMapper; +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + StorageMapper, StorageMapperFromAddress, +}; use crate::{ api::{ErrorApiImpl, StorageMapperApi}, - storage::{ - storage_clear, storage_get, storage_get_from_address, storage_get_len, storage_set, - StorageKey, - }, + storage::{storage_clear, storage_set, StorageKey}, types::{ManagedAddress, ManagedType}, }; -use storage_get_from_address::storage_get_len_from_address; static ID_SUFFIX: &[u8] = b"addrId"; static ADDRESS_SUFFIX: &[u8] = b"addr"; @@ -20,11 +19,13 @@ static UNKNOWN_ADDR_ERR_MSG: &[u8] = b"Unknown address"; pub type AddressId = u64; pub const NULL_ID: AddressId = 0; -pub struct AddressToIdMapper +pub struct AddressToIdMapper where SA: StorageMapperApi, + A: StorageAddress, { _phantom_api: PhantomData, + address: A, base_key: StorageKey, } @@ -35,32 +36,38 @@ where fn new(base_key: StorageKey) -> Self { AddressToIdMapper { _phantom_api: PhantomData, + address: CurrentStorage, base_key, } } } -impl AddressToIdMapper +impl StorageMapperFromAddress for AddressToIdMapper> where SA: StorageMapperApi, +{ + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + AddressToIdMapper { + _phantom_api: PhantomData, + address, + base_key, + } + } +} + +impl AddressToIdMapper +where + SA: StorageMapperApi, + A: StorageAddress, { pub fn contains_id(&self, id: AddressId) -> bool { let key = self.id_to_address_key(id); - storage_get_len(key.as_ref()) != 0 + self.address.address_storage_get_len(key.as_ref()) != 0 } pub fn get_id(&self, address: &ManagedAddress) -> AddressId { let key = self.address_to_id_key(address); - storage_get(key.as_ref()) - } - - pub fn get_id_at_address( - &self, - sc_address: &ManagedAddress, - address_to_find: &ManagedAddress, - ) -> AddressId { - let key = self.address_to_id_key(address_to_find); - storage_get_from_address(sc_address.as_ref(), key.as_ref()) + self.address.address_storage_get(key.as_ref()) } pub fn get_id_non_zero(&self, address: &ManagedAddress) -> AddressId { @@ -72,54 +79,53 @@ where id } - pub fn get_id_at_address_non_zero( - &self, - sc_address: &ManagedAddress, - address_to_find: &ManagedAddress, - ) -> AddressId { - let id = self.get_id_at_address(sc_address, address_to_find); - if id == NULL_ID { - SA::error_api_impl().signal_error(UNKNOWN_ADDR_ERR_MSG); + pub fn get_address(&self, id: AddressId) -> Option> { + let key = self.id_to_address_key(id); + if self.address.address_storage_get_len(key.as_ref()) == 0 { + return None; } - id + let addr = self.address.address_storage_get(key.as_ref()); + Some(addr) } - pub fn insert_new(&self, address: &ManagedAddress) -> AddressId { - let existing_id = self.get_id(address); - if existing_id != NULL_ID { - SA::error_api_impl().signal_error(b"Address already registered"); - } + fn id_to_address_key(&self, id: AddressId) -> StorageKey { + let mut item_key = self.base_key.clone(); + item_key.append_bytes(ID_SUFFIX); + item_key.append_item(&id); - self.insert_address(address) + item_key } - pub fn get_address(&self, id: AddressId) -> Option> { - let key = self.id_to_address_key(id); - if storage_get_len(key.as_ref()) == 0 { - return None; - } + fn address_to_id_key(&self, address: &ManagedAddress) -> StorageKey { + let mut item_key = self.base_key.clone(); + item_key.append_bytes(ADDRESS_SUFFIX); + item_key.append_item(address); - let addr = storage_get(key.as_ref()); - Some(addr) + item_key } - pub fn get_address_at_address( - &self, - sc_address: &ManagedAddress, - id: AddressId, - ) -> Option> { - let key = self.id_to_address_key(id); - if storage_get_len_from_address(sc_address.as_ref(), key.as_ref()) == 0 { - return None; - } + fn last_id_key(&self) -> StorageKey { + let mut item_key = self.base_key.clone(); + item_key.append_bytes(LAST_ID_SUFFIX); - let addr = storage_get_from_address(sc_address.as_ref(), key.as_ref()); - Some(addr) + item_key } + pub fn get_last_id(&self) -> AddressId { + self.address + .address_storage_get(self.last_id_key().as_ref()) + } +} + +impl AddressToIdMapper +where + SA: StorageMapperApi, +{ pub fn get_id_or_insert(&self, address: &ManagedAddress) -> AddressId { - let current_id = storage_get(self.address_to_id_key(address).as_ref()); + let current_id = self + .address + .address_storage_get(self.address_to_id_key(address).as_ref()); if current_id != 0 { return current_id; } @@ -127,6 +133,15 @@ where self.insert_address(address) } + pub fn insert_new(&self, address: &ManagedAddress) -> AddressId { + let existing_id = self.get_id(address); + if existing_id != NULL_ID { + SA::error_api_impl().signal_error(b"Address already registered"); + } + + self.insert_address(address) + } + pub fn remove_by_id(&self, id: AddressId) -> Option> { let address = self.get_address(id)?; self.remove_entry(id, &address); @@ -153,38 +168,6 @@ where new_id } - fn remove_entry(&self, id: AddressId, address: &ManagedAddress) { - storage_clear(self.address_to_id_key(address).as_ref()); - storage_clear(self.id_to_address_key(id).as_ref()); - } - - fn id_to_address_key(&self, id: AddressId) -> StorageKey { - let mut item_key = self.base_key.clone(); - item_key.append_bytes(ID_SUFFIX); - item_key.append_item(&id); - - item_key - } - - fn address_to_id_key(&self, address: &ManagedAddress) -> StorageKey { - let mut item_key = self.base_key.clone(); - item_key.append_bytes(ADDRESS_SUFFIX); - item_key.append_item(address); - - item_key - } - - fn last_id_key(&self) -> StorageKey { - let mut item_key = self.base_key.clone(); - item_key.append_bytes(LAST_ID_SUFFIX); - - item_key - } - - pub fn get_last_id(&self) -> AddressId { - storage_get(self.last_id_key().as_ref()) - } - fn set_last_id(&self, last_id: AddressId) { if last_id == 0 { SA::error_api_impl().signal_error(b"ID Overflow"); @@ -192,4 +175,9 @@ where storage_set(self.last_id_key().as_ref(), &last_id); } + + fn remove_entry(&self, id: AddressId, address: &ManagedAddress) { + storage_clear(self.address_to_id_key(address).as_ref()); + storage_clear(self.id_to_address_key(id).as_ref()); + } } diff --git a/framework/base/src/storage/mappers/bi_di_mapper.rs b/framework/base/src/storage/mappers/bi_di_mapper.rs index 15503955d5..ce0f24c159 100644 --- a/framework/base/src/storage/mappers/bi_di_mapper.rs +++ b/framework/base/src/storage/mappers/bi_di_mapper.rs @@ -1,15 +1,22 @@ use core::marker::PhantomData; -use crate::codec::{ - multi_encode_iter_or_handle_err, multi_types::MultiValue2, CodecFrom, EncodeErrorHandler, - NestedDecode, NestedEncode, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, +use crate::{ + abi::TypeAbiFrom, + codec::{ + multi_encode_iter_or_handle_err, multi_types::MultiValue2, EncodeErrorHandler, + NestedDecode, NestedEncode, TopDecode, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, + }, + types::ManagedAddress, }; -use super::{unordered_set_mapper, StorageMapper, UnorderedSetMapper}; +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + unordered_set_mapper, StorageMapper, StorageMapperFromAddress, UnorderedSetMapper, +}; use crate::{ abi::{TypeAbi, TypeDescriptionContainer, TypeName}, api::StorageMapperApi, - storage::{storage_get, storage_set, StorageKey}, + storage::{storage_set, StorageKey}, storage_clear, types::{ManagedType, MultiValueEncoded}, }; @@ -19,23 +26,25 @@ const ID_SUFIX: &[u8] = b"_id"; const VALUE_TO_ID_SUFFIX: &[u8] = b"_value_to_id"; const ID_TO_VALUE_SUFFIX: &[u8] = b"_id_to_value"; -type Keys<'a, SA, T> = unordered_set_mapper::Iter<'a, SA, T>; +type Keys<'a, SA, T, A> = unordered_set_mapper::Iter<'a, SA, T, A>; /// A bi-directional map, from values to ids and viceversa. /// The mapper is based on UnorderedSetMapper, reason why the remove is done by swap_remove -pub struct BiDiMapper +pub struct BiDiMapper where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, { _phantom_api: PhantomData, - id_set_mapper: UnorderedSetMapper, - value_set_mapper: UnorderedSetMapper, + address: A, + id_set_mapper: UnorderedSetMapper, + value_set_mapper: UnorderedSetMapper, base_key: StorageKey, } -impl StorageMapper for BiDiMapper +impl StorageMapper for BiDiMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, @@ -49,6 +58,7 @@ where value_key.append_bytes(VALUE_SUFIX); BiDiMapper { _phantom_api: PhantomData, + address: CurrentStorage, id_set_mapper: UnorderedSetMapper::::new(id_key), value_set_mapper: UnorderedSetMapper::::new(value_key), base_key, @@ -56,11 +66,34 @@ where } } -impl BiDiMapper +impl StorageMapperFromAddress for BiDiMapper> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, +{ + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + let mut id_key = base_key.clone(); + id_key.append_bytes(ID_SUFIX); + + let mut value_key = base_key.clone(); + value_key.append_bytes(VALUE_SUFIX); + BiDiMapper { + _phantom_api: PhantomData, + address: address.clone(), + id_set_mapper: UnorderedSetMapper::new_from_address(address.clone(), id_key), + value_set_mapper: UnorderedSetMapper::new_from_address(address, value_key), + base_key, + } + } +} + +impl BiDiMapper +where + SA: StorageMapperApi, + A: StorageAddress, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, + V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, { fn get_id_key(&self, value: &V) -> StorageKey { let mut key = self.base_key.clone(); @@ -77,15 +110,52 @@ where } pub fn get_id(&self, value: &V) -> K { - storage_get(self.get_id_key(value).as_ref()) + self.address + .address_storage_get(self.get_id_key(value).as_ref()) } - fn set_id(&mut self, value: &V, id: &K) { - storage_set(self.get_id_key(value).as_ref(), id); + pub fn get_value(&self, id: &K) -> V { + self.address + .address_storage_get(self.get_value_key(id).as_ref()) } - pub fn get_value(&self, id: &K) -> V { - storage_get(self.get_value_key(id).as_ref()) + pub fn contains_id(&self, id: &K) -> bool { + self.id_set_mapper.contains(id) + } + + pub fn contains_value(&self, value: &V) -> bool { + self.value_set_mapper.contains(value) + } + + pub fn get_all_values(&self) -> unordered_set_mapper::Iter { + self.value_set_mapper.iter() + } + + pub fn get_all_ids(&self) -> unordered_set_mapper::Iter { + self.id_set_mapper.iter() + } + + pub fn iter(&self) -> Iter { + Iter::new(self) + } + + pub fn is_empty(&self) -> bool { + self.value_set_mapper.is_empty() + } + + pub fn len(&self) -> usize { + self.value_set_mapper.len() + } +} + +impl BiDiMapper +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, + V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, +{ + fn set_id(&mut self, value: &V, id: &K) { + storage_set(self.get_id_key(value).as_ref(), id); } fn set_value(&mut self, id: &K, value: &V) { @@ -99,14 +169,6 @@ where storage_clear(self.get_value_key(id).as_ref()); } - pub fn contains_id(&self, id: &K) -> bool { - self.id_set_mapper.contains(id) - } - - pub fn contains_value(&self, value: &V) -> bool { - self.value_set_mapper.contains(value) - } - pub fn insert(&mut self, id: K, value: V) -> bool { if self.contains_id(&id) || self.contains_value(&value) { return false; @@ -158,60 +220,43 @@ where self.remove_by_value(&item); } } - - pub fn get_all_values(&self) -> unordered_set_mapper::Iter { - self.value_set_mapper.iter() - } - - pub fn get_all_ids(&self) -> unordered_set_mapper::Iter { - self.id_set_mapper.iter() - } - - pub fn iter(&self) -> Iter { - Iter::new(self) - } - - pub fn is_empty(&self) -> bool { - self.value_set_mapper.is_empty() - } - - pub fn len(&self) -> usize { - self.value_set_mapper.len() - } } -impl<'a, SA, K, V> IntoIterator for &'a BiDiMapper +impl<'a, SA, K, V, A> IntoIterator for &'a BiDiMapper where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, { type Item = (K, V); - type IntoIter = Iter<'a, SA, K, V>; + type IntoIter = Iter<'a, SA, K, V, A>; fn into_iter(self) -> Self::IntoIter { self.iter() } } -pub struct Iter<'a, SA, K, V> +pub struct Iter<'a, SA, K, V, A> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, { - key_iter: Keys<'a, SA, K>, - hash_map: &'a BiDiMapper, + key_iter: Keys<'a, SA, K, A>, + hash_map: &'a BiDiMapper, } -impl<'a, SA, K, V> Iter<'a, SA, K, V> +impl<'a, SA, K, V, A> Iter<'a, SA, K, V, A> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, { - fn new(hash_map: &'a BiDiMapper) -> Iter<'a, SA, K, V> { + fn new(hash_map: &'a BiDiMapper) -> Iter<'a, SA, K, V, A> { Iter { key_iter: hash_map.get_all_ids(), hash_map, @@ -219,9 +264,10 @@ where } } -impl<'a, SA, K, V> Iterator for Iter<'a, SA, K, V> +impl<'a, SA, K, V, A> Iterator for Iter<'a, SA, K, V, A> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, V: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, { @@ -237,7 +283,7 @@ where } } -impl TopEncodeMulti for BiDiMapper +impl TopEncodeMulti for BiDiMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, @@ -253,7 +299,8 @@ where } } -impl CodecFrom> for MultiValueEncoded> +impl TypeAbiFrom> + for MultiValueEncoded> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static + Default + PartialEq, @@ -261,7 +308,15 @@ where { } -impl TypeAbi for BiDiMapper +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, K: TopEncode @@ -281,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 30869451f1..a259467c29 100644 --- a/framework/base/src/storage/mappers/linked_list_mapper.rs +++ b/framework/base/src/storage/mappers/linked_list_mapper.rs @@ -1,8 +1,11 @@ use core::marker::PhantomData; -use super::{StorageClearable, StorageMapper}; +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + StorageClearable, StorageMapper, StorageMapperFromAddress, +}; use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::StorageMapperApi, codec::{ self, @@ -10,14 +13,13 @@ 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_get, storage_set, StorageKey}, - types::{heap::BoxedBytes, ManagedType, MultiValueEncoded}, + storage::{storage_set, StorageKey}, + types::{heap::BoxedBytes, ManagedAddress, ManagedType, MultiValueEncoded}, }; use alloc::vec::Vec; -use storage_get::storage_get_len; const NULL_ENTRY: u32 = 0; const INFO_IDENTIFIER: &[u8] = b".info"; @@ -89,17 +91,19 @@ impl LinkedListInfo { } } -pub struct LinkedListMapper +pub struct LinkedListMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, { _phantom_api: PhantomData, + address: A, base_key: StorageKey, _phantom_item: PhantomData, } -impl StorageMapper for LinkedListMapper +impl StorageMapper for LinkedListMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, @@ -107,6 +111,22 @@ where fn new(base_key: StorageKey) -> Self { LinkedListMapper { _phantom_api: PhantomData, + address: CurrentStorage, + base_key, + _phantom_item: PhantomData, + } + } +} + +impl StorageMapperFromAddress for LinkedListMapper> +where + SA: StorageMapperApi, + T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, +{ + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + LinkedListMapper { + _phantom_api: PhantomData, + address, base_key, _phantom_item: PhantomData, } @@ -132,9 +152,10 @@ where } } -impl LinkedListMapper +impl LinkedListMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, { fn build_node_id_named_key(&self, name: &[u8], node_id: u32) -> StorageKey { @@ -151,43 +172,24 @@ where } fn get_info(&self) -> LinkedListInfo { - storage_get(self.build_name_key(INFO_IDENTIFIER).as_ref()) - } - - fn set_info(&mut self, value: LinkedListInfo) { - storage_set(self.build_name_key(INFO_IDENTIFIER).as_ref(), &value); + self.address + .address_storage_get(self.build_name_key(INFO_IDENTIFIER).as_ref()) } fn get_node(&self, node_id: u32) -> LinkedListNode { - storage_get( + self.address.address_storage_get( self.build_node_id_named_key(NODE_IDENTIFIER, node_id) .as_ref(), ) } fn is_empty_node(&self, node_id: u32) -> bool { - storage_get_len( + self.address.address_storage_get_len( self.build_node_id_named_key(NODE_IDENTIFIER, node_id) .as_ref(), ) == 0 } - fn set_node(&mut self, node_id: u32, item: &LinkedListNode) { - storage_set( - self.build_node_id_named_key(NODE_IDENTIFIER, node_id) - .as_ref(), - item, - ); - } - - fn clear_node(&mut self, node_id: u32) { - storage_set( - self.build_node_id_named_key(NODE_IDENTIFIER, node_id) - .as_ref(), - &BoxedBytes::empty(), - ); - } - pub fn is_empty(&self) -> bool { self.get_info().len == 0 } @@ -208,6 +210,108 @@ where self.get_node_by_id(info.back) } + pub fn get_node_by_id(&self, node_id: u32) -> Option> { + if self.is_empty_node(node_id) { + return None; + } + + Some(self.get_node(node_id)) + } + + pub fn iter(&self) -> Iter { + Iter::new(self) + } + + pub fn iter_from_node_id(&self, node_id: u32) -> Iter { + Iter::new_from_node_id(self, node_id) + } + + pub fn check_internal_consistency(&self) -> bool { + let info = self.get_info(); + let mut front = info.front; + let mut back = info.back; + + if info.len == 0 { + if front != NULL_ENTRY { + return false; + } + if back != NULL_ENTRY { + return false; + } + true + } else { + if front == NULL_ENTRY { + return false; + } + if back == NULL_ENTRY { + return false; + } + + if self.get_node(front).prev_id != NULL_ENTRY { + return false; + } + if self.get_node(back).next_id != NULL_ENTRY { + return false; + } + + let mut forwards = Vec::new(); + while front != NULL_ENTRY { + forwards.push(front); + front = self.get_node(front).next_id; + } + if forwards.len() != info.len as usize { + return false; + } + + let mut backwards = Vec::new(); + while back != NULL_ENTRY { + backwards.push(back); + back = self.get_node(back).prev_id; + } + if backwards.len() != info.len as usize { + return false; + } + + let backwards_reversed: Vec = backwards.iter().rev().cloned().collect(); + if forwards != backwards_reversed { + return false; + } + + forwards.sort_unstable(); + forwards.dedup(); + if forwards.len() != info.len as usize { + return false; + } + true + } + } +} + +impl LinkedListMapper +where + SA: StorageMapperApi, + T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, +{ + fn set_info(&mut self, value: LinkedListInfo) { + storage_set(self.build_name_key(INFO_IDENTIFIER).as_ref(), &value); + } + + fn set_node(&mut self, node_id: u32, item: &LinkedListNode) { + storage_set( + self.build_node_id_named_key(NODE_IDENTIFIER, node_id) + .as_ref(), + item, + ); + } + + fn clear_node(&mut self, node_id: u32) { + storage_set( + self.build_node_id_named_key(NODE_IDENTIFIER, node_id) + .as_ref(), + &BoxedBytes::empty(), + ); + } + pub fn pop_back(&mut self) -> Option> { let info = self.get_info(); @@ -423,120 +527,50 @@ where self.remove_node(&node); Some(node) } - - pub fn get_node_by_id(&self, node_id: u32) -> Option> { - if self.is_empty_node(node_id) { - return None; - } - - Some(self.get_node(node_id)) - } - - pub fn iter(&self) -> Iter { - Iter::new(self) - } - - pub fn iter_from_node_id(&self, node_id: u32) -> Iter { - Iter::new_from_node_id(self, node_id) - } - - pub fn check_internal_consistency(&self) -> bool { - let info = self.get_info(); - let mut front = info.front; - let mut back = info.back; - - if info.len == 0 { - if front != NULL_ENTRY { - return false; - } - if back != NULL_ENTRY { - return false; - } - true - } else { - if front == NULL_ENTRY { - return false; - } - if back == NULL_ENTRY { - return false; - } - - if self.get_node(front).prev_id != NULL_ENTRY { - return false; - } - if self.get_node(back).next_id != NULL_ENTRY { - return false; - } - - let mut forwards = Vec::new(); - while front != NULL_ENTRY { - forwards.push(front); - front = self.get_node(front).next_id; - } - if forwards.len() != info.len as usize { - return false; - } - - let mut backwards = Vec::new(); - while back != NULL_ENTRY { - backwards.push(back); - back = self.get_node(back).prev_id; - } - if backwards.len() != info.len as usize { - return false; - } - - let backwards_reversed: Vec = backwards.iter().rev().cloned().collect(); - if forwards != backwards_reversed { - return false; - } - - forwards.sort_unstable(); - forwards.dedup(); - if forwards.len() != info.len as usize { - return false; - } - true - } - } } -impl<'a, SA, T> IntoIterator for &'a LinkedListMapper +impl<'a, SA, T, A> IntoIterator for &'a LinkedListMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, { type Item = LinkedListNode; - type IntoIter = Iter<'a, SA, T>; + type IntoIter = Iter<'a, SA, T, A>; fn into_iter(self) -> Self::IntoIter { self.iter() } } -pub struct Iter<'a, SA, T> +pub struct Iter<'a, SA, T, A> where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, { node_opt: Option>, - linked_list: &'a LinkedListMapper, + linked_list: &'a LinkedListMapper, } -impl<'a, SA, T> Iter<'a, SA, T> +impl<'a, SA, T, A> Iter<'a, SA, T, A> where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, { - fn new(linked_list: &'a LinkedListMapper) -> Iter<'a, SA, T> { + fn new(linked_list: &'a LinkedListMapper) -> Iter<'a, SA, T, A> { Iter { node_opt: linked_list.front(), linked_list, } } - fn new_from_node_id(linked_list: &'a LinkedListMapper, node_id: u32) -> Iter<'a, SA, T> { + fn new_from_node_id( + linked_list: &'a LinkedListMapper, + node_id: u32, + ) -> Iter<'a, SA, T, A> { Iter { node_opt: linked_list.get_node_by_id(node_id), linked_list, @@ -544,9 +578,10 @@ where } } -impl<'a, SA, T> Iterator for Iter<'a, SA, T> +impl<'a, SA, T, A> Iterator for Iter<'a, SA, T, A> where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, { type Item = LinkedListNode; @@ -577,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, { } @@ -590,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 145ae6d4e3..0da042334a 100644 --- a/framework/base/src/storage/mappers/map_mapper.rs +++ b/framework/base/src/storage/mappers/map_mapper.rs @@ -1,33 +1,38 @@ use core::marker::PhantomData; -use super::{set_mapper, SetMapper, StorageClearable, StorageMapper}; +use super::{ + set_mapper::{self, CurrentStorage, StorageAddress}, + SetMapper, StorageClearable, StorageMapper, StorageMapperFromAddress, +}; 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_get, storage_set, StorageKey}, - types::{ManagedType, MultiValueEncoded}, + storage::{storage_clear, storage_set, StorageKey}, + types::{ManagedAddress, ManagedType, MultiValueEncoded}, }; const MAPPED_VALUE_IDENTIFIER: &[u8] = b".mapped"; -type Keys<'a, SA, T> = set_mapper::Iter<'a, SA, T>; +type Keys<'a, SA, A, T> = set_mapper::Iter<'a, SA, A, T>; -pub struct MapMapper +pub struct MapMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: TopEncode + TopDecode + 'static, { _phantom_api: PhantomData, + address: A, base_key: StorageKey, - keys_set: SetMapper, + keys_set: SetMapper, _phantom_value: PhantomData, } -impl StorageMapper for MapMapper +impl StorageMapper for MapMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode, @@ -36,14 +41,15 @@ where fn new(base_key: StorageKey) -> Self { MapMapper { _phantom_api: PhantomData, + address: CurrentStorage, base_key: base_key.clone(), - keys_set: SetMapper::::new(base_key), + keys_set: SetMapper::new(base_key), _phantom_value: PhantomData, } } } -impl StorageClearable for MapMapper +impl StorageClearable for MapMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode, @@ -57,12 +63,87 @@ where } } -impl MapMapper +impl MapMapper +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode, + V: TopEncode + TopDecode, +{ + fn set_mapped_value(&self, key: &K, value: &V) { + storage_set( + self.build_named_key(MAPPED_VALUE_IDENTIFIER, key).as_ref(), + &value, + ); + } + + fn clear_mapped_value(&self, key: &K) { + storage_clear(self.build_named_key(MAPPED_VALUE_IDENTIFIER, key).as_ref()); + } + + /// Sets the value of the entry, and returns the entry's old value. + pub fn insert(&mut self, k: K, v: V) -> Option { + let old_value = self.get(&k); + self.set_mapped_value(&k, &v); + self.keys_set.insert(k); + old_value + } + + /// Takes the value out of the entry, and returns it. + pub fn remove(&mut self, k: &K) -> Option { + if self.keys_set.remove(k) { + let value = self.get_mapped_value(k); + self.clear_mapped_value(k); + return Some(value); + } + None + } +} + +impl StorageMapperFromAddress for MapMapper> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode, V: TopEncode + TopDecode, { + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + MapMapper { + _phantom_api: PhantomData, + address: address.clone(), + base_key: base_key.clone(), + keys_set: SetMapper::new_from_address(address, base_key), + _phantom_value: PhantomData, + } + } +} + +impl<'a, SA, A, K, V> IntoIterator for &'a MapMapper +where + SA: StorageMapperApi, + A: StorageAddress, + K: TopEncode + TopDecode + NestedEncode + NestedDecode, + V: TopEncode + TopDecode, +{ + type Item = (K, V); + + type IntoIter = Iter<'a, SA, A, K, V>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl MapMapper +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode, + A: StorageAddress, + V: TopEncode + TopDecode, +{ + /// Returns `true` if the map contains a value for the specified key. + pub fn contains_key(&self, k: &K) -> bool { + self.keys_set.contains(k) + } + fn build_named_key(&self, name: &[u8], key: &K) -> StorageKey { let mut named_key = self.base_key.clone(); named_key.append_bytes(name); @@ -71,18 +152,20 @@ where } fn get_mapped_value(&self, key: &K) -> V { - storage_get(self.build_named_key(MAPPED_VALUE_IDENTIFIER, key).as_ref()) + self.address + .address_storage_get(self.build_named_key(MAPPED_VALUE_IDENTIFIER, key).as_ref()) } - fn set_mapped_value(&self, key: &K, value: &V) { - storage_set( - self.build_named_key(MAPPED_VALUE_IDENTIFIER, key).as_ref(), - &value, - ); + /// Gets a reference to the value in the entry. + pub fn get(&self, k: &K) -> Option { + if self.keys_set.contains(k) { + return Some(self.get_mapped_value(k)); + } + None } - fn clear_mapped_value(&self, key: &K) { - storage_clear(self.build_named_key(MAPPED_VALUE_IDENTIFIER, key).as_ref()); + pub fn keys(&self) -> Keys { + self.keys_set.iter() } /// Returns `true` if the map contains no elements. @@ -95,13 +178,8 @@ where self.keys_set.len() } - /// Returns `true` if the map contains a value for the specified key. - pub fn contains_key(&self, k: &K) -> bool { - self.keys_set.contains(k) - } - /// Gets the given key's corresponding entry in the map for in-place manipulation. - pub fn entry(&mut self, key: K) -> Entry<'_, SA, K, V> { + pub fn entry(&mut self, key: K) -> Entry<'_, SA, A, K, V> { if self.contains_key(&key) { Entry::Occupied(OccupiedEntry { key, @@ -117,83 +195,38 @@ where } } - /// Gets a reference to the value in the entry. - pub fn get(&self, k: &K) -> Option { - if self.keys_set.contains(k) { - return Some(self.get_mapped_value(k)); - } - None - } - - /// Sets the value of the entry, and returns the entry's old value. - pub fn insert(&mut self, k: K, v: V) -> Option { - let old_value = self.get(&k); - self.set_mapped_value(&k, &v); - self.keys_set.insert(k); - old_value - } - - /// Takes the value out of the entry, and returns it. - pub fn remove(&mut self, k: &K) -> Option { - if self.keys_set.remove(k) { - let value = self.get_mapped_value(k); - self.clear_mapped_value(k); - return Some(value); - } - None - } - - /// An iterator visiting all keys in arbitrary order. - /// The iterator element type is `&'a K`. - pub fn keys(&self) -> Keys { - self.keys_set.iter() - } - /// An iterator visiting all values in arbitrary order. /// The iterator element type is `&'a V`. - pub fn values(&self) -> Values { + pub fn values(&self) -> Values { Values::new(self) } /// An iterator visiting all key-value pairs in arbitrary order. /// The iterator element type is `(&'a K, &'a V)`. - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter { Iter::new(self) } } -impl<'a, SA, K, V> IntoIterator for &'a MapMapper -where - SA: StorageMapperApi, - K: TopEncode + TopDecode + NestedEncode + NestedDecode, - V: TopEncode + TopDecode, -{ - type Item = (K, V); - - type IntoIter = Iter<'a, SA, K, V>; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -pub struct Iter<'a, SA, K, V> +pub struct Iter<'a, SA, A, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: TopEncode + TopDecode + 'static, { - key_iter: Keys<'a, SA, K>, - hash_map: &'a MapMapper, + key_iter: Keys<'a, SA, A, K>, + hash_map: &'a MapMapper, } -impl<'a, SA, K, V> Iter<'a, SA, K, V> +impl<'a, SA, A, K, V> Iter<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, V: TopEncode + TopDecode + 'static, { - fn new(hash_map: &'a MapMapper) -> Iter<'a, SA, K, V> { + fn new(hash_map: &'a MapMapper) -> Iter<'a, SA, A, K, V> { Iter { key_iter: hash_map.keys(), hash_map, @@ -201,9 +234,10 @@ where } } -impl<'a, SA, K, V> Iterator for Iter<'a, SA, K, V> +impl<'a, SA, A, K, V> Iterator for Iter<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, V: TopEncode + TopDecode + 'static, { @@ -219,23 +253,25 @@ where } } -pub struct Values<'a, SA, K, V> +pub struct Values<'a, SA, A, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: TopEncode + TopDecode + 'static, { - key_iter: Keys<'a, SA, K>, - hash_map: &'a MapMapper, + key_iter: Keys<'a, SA, A, K>, + hash_map: &'a MapMapper, } -impl<'a, SA, K, V> Values<'a, SA, K, V> +impl<'a, SA, A, K, V> Values<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, V: TopEncode + TopDecode + 'static, { - fn new(hash_map: &'a MapMapper) -> Values<'a, SA, K, V> { + fn new(hash_map: &'a MapMapper) -> Values<'a, SA, A, K, V> { Values { key_iter: hash_map.keys(), hash_map, @@ -243,9 +279,10 @@ where } } -impl<'a, SA, K, V> Iterator for Values<'a, SA, K, V> +impl<'a, SA, A, K, V> Iterator for Values<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, V: TopEncode + TopDecode + 'static, { @@ -261,29 +298,31 @@ where } } -pub enum Entry<'a, SA, K: 'a, V: 'a> +pub enum Entry<'a, SA, A, K: 'a, V: 'a> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: TopEncode + TopDecode + 'static, { /// A vacant entry. - Vacant(VacantEntry<'a, SA, K, V>), + Vacant(VacantEntry<'a, SA, A, K, V>), /// An occupied entry. - Occupied(OccupiedEntry<'a, SA, K, V>), + Occupied(OccupiedEntry<'a, SA, A, K, V>), } /// A view into a vacant entry in a `MapMapper`. /// It is part of the [`Entry`] enum. -pub struct VacantEntry<'a, SA, K: 'a, V: 'a> +pub struct VacantEntry<'a, SA, A, K: 'a, V: 'a> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: TopEncode + TopDecode + 'static, { pub(super) key: K, - pub(super) map: &'a mut MapMapper, + pub(super) map: &'a mut MapMapper, // Be invariant in `K` and `V` pub(super) _marker: PhantomData<&'a mut (K, V)>, @@ -291,20 +330,37 @@ where /// A view into an occupied entry in a `MapMapper`. /// It is part of the [`Entry`] enum. -pub struct OccupiedEntry<'a, SA, K: 'a, V: 'a> +pub struct OccupiedEntry<'a, SA, A, K: 'a, V: 'a> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: TopEncode + TopDecode + 'static, { pub(super) key: K, - pub(super) map: &'a mut MapMapper, + pub(super) map: &'a mut MapMapper, // Be invariant in `K` and `V` pub(super) _marker: PhantomData<&'a mut (K, V)>, } -impl<'a, SA, K, V> Entry<'a, SA, K, V> +impl<'a, SA, A, K, V> Entry<'a, SA, A, K, V> +where + SA: StorageMapperApi, + A: StorageAddress, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, + V: TopEncode + TopDecode + 'static, +{ + /// Returns a reference to this entry's key. + pub fn key(&self) -> &K { + match *self { + Entry::Occupied(ref entry) => entry.key(), + Entry::Vacant(ref entry) => entry.key(), + } + } +} + +impl<'a, SA, K, V> Entry<'a, SA, CurrentStorage, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, @@ -312,7 +368,7 @@ where { /// Ensures a value is in the entry by inserting the default if empty, and returns /// an `OccupiedEntry`. - pub fn or_insert(self, default: V) -> OccupiedEntry<'a, SA, K, V> { + pub fn or_insert(self, default: V) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> { match self { Entry::Occupied(entry) => entry, Entry::Vacant(entry) => entry.insert(default), @@ -321,7 +377,10 @@ where /// Ensures a value is in the entry by inserting the result of the default function if empty, /// and returns an `OccupiedEntry`. - pub fn or_insert_with V>(self, default: F) -> OccupiedEntry<'a, SA, K, V> { + pub fn or_insert_with V>( + self, + default: F, + ) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> { match self { Entry::Occupied(entry) => entry, Entry::Vacant(entry) => entry.insert(default()), @@ -334,7 +393,10 @@ where /// /// The reference to the moved key is provided so that cloning or copying the key is /// unnecessary, unlike with `.or_insert_with(|| ... )`. - pub fn or_insert_with_key V>(self, default: F) -> OccupiedEntry<'a, SA, K, V> { + pub fn or_insert_with_key V>( + self, + default: F, + ) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> { match self { Entry::Occupied(entry) => entry, Entry::Vacant(entry) => { @@ -344,14 +406,6 @@ where } } - /// Returns a reference to this entry's key. - pub fn key(&self) -> &K { - match *self { - Entry::Occupied(ref entry) => entry.key(), - Entry::Vacant(ref entry) => entry.key(), - } - } - /// Provides in-place mutable access to an occupied entry before any /// potential inserts into the map. pub fn and_modify(self, f: F) -> Self @@ -368,7 +422,7 @@ where } } -impl<'a, SA, K, V: Default> Entry<'a, SA, K, V> +impl<'a, SA, K, V: Default> Entry<'a, SA, CurrentStorage, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, @@ -376,7 +430,7 @@ where { /// Ensures a value is in the entry by inserting the default value if empty, /// and returns an `OccupiedEntry`. - pub fn or_default(self) -> OccupiedEntry<'a, SA, K, V> { + pub fn or_default(self) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> { match self { Entry::Occupied(entry) => entry, Entry::Vacant(entry) => entry.insert(Default::default()), @@ -384,9 +438,10 @@ where } } -impl<'a, SA, K, V> VacantEntry<'a, SA, K, V> +impl<'a, SA, A, K, V> VacantEntry<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, V: TopEncode + TopDecode + 'static, { @@ -395,10 +450,17 @@ where pub fn key(&self) -> &K { &self.key } +} +impl<'a, SA, K, V> VacantEntry<'a, SA, CurrentStorage, K, V> +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, + V: TopEncode + TopDecode + 'static, +{ /// Sets the value of the entry with the `VacantEntry`'s key, /// and returns an `OccupiedEntry`. - pub fn insert(self, value: V) -> OccupiedEntry<'a, SA, K, V> { + pub fn insert(self, value: V) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> { self.map.insert(self.key.clone(), value); OccupiedEntry { key: self.key, @@ -408,9 +470,10 @@ where } } -impl<'a, SA, K, V> OccupiedEntry<'a, SA, K, V> +impl<'a, SA, A, K, V> OccupiedEntry<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, V: TopEncode + TopDecode + 'static, { @@ -419,17 +482,24 @@ where &self.key } + /// Gets the value in the entry. + pub fn get(&self) -> V { + self.map.get(&self.key).unwrap() + } +} + +impl<'a, SA, K, V> OccupiedEntry<'a, SA, CurrentStorage, K, V> +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone, + V: TopEncode + TopDecode + 'static, +{ /// Take ownership of the key and value from the map. pub fn remove_entry(self) -> (K, V) { let value = self.map.remove(&self.key).unwrap(); (self.key, value) } - /// Gets the value in the entry. - pub fn get(&self) -> V { - self.map.get(&self.key).unwrap() - } - /// Syntactic sugar, to more compactly express a get, update and set in one line. /// Takes whatever lies in storage, apples the given closure and saves the final value back to storage. /// Propagates the return value of the given function. @@ -453,7 +523,7 @@ where } /// Behaves like a MultiResultVec> when an endpoint result. -impl TopEncodeMulti for MapMapper +impl TopEncodeMulti for MapMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, @@ -469,7 +539,16 @@ where } } -impl CodecFrom> for MultiValueEncoded> +impl TypeAbiFrom> + for MultiValueEncoded> +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + V: TopEncode + TopDecode + 'static, +{ +} + +impl TypeAbiFrom for MapMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, @@ -478,16 +557,22 @@ where } /// Behaves like a MultiResultVec> when an endpoint result. -impl TypeAbi for MapMapper +impl TypeAbi for MapMapper where SA: StorageMapperApi, 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 23acfaf2cb..699a3bab36 100644 --- a/framework/base/src/storage/mappers/map_storage_mapper.rs +++ b/framework/base/src/storage/mappers/map_storage_mapper.rs @@ -1,28 +1,34 @@ use core::marker::PhantomData; -use super::{set_mapper, SetMapper, StorageClearable, StorageMapper}; +use super::{ + set_mapper::{self, CurrentStorage, StorageAddress}, + SetMapper, StorageClearable, StorageMapper, StorageMapperFromAddress, +}; use crate::{ api::StorageMapperApi, codec::{NestedDecode, NestedEncode, TopDecode, TopEncode}, + contract_base::ErrorHelper, storage::{self, StorageKey}, + types::ManagedAddress, }; const MAPPED_STORAGE_VALUE_IDENTIFIER: &[u8] = b".storage"; -type Keys<'a, SA, T> = set_mapper::Iter<'a, SA, T>; +type Keys<'a, SA, A, T> = set_mapper::Iter<'a, SA, A, T>; -pub struct MapStorageMapper +pub struct MapStorageMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: StorageMapper + StorageClearable, { _phantom_api: PhantomData, base_key: StorageKey, - keys_set: SetMapper, + keys_set: SetMapper, _phantom_value: PhantomData, } -impl StorageMapper for MapStorageMapper +impl StorageMapper for MapStorageMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode, @@ -32,13 +38,13 @@ where Self { _phantom_api: PhantomData, base_key: base_key.clone(), - keys_set: SetMapper::::new(base_key), + keys_set: SetMapper::new(base_key), _phantom_value: PhantomData, } } } -impl StorageClearable for MapStorageMapper +impl StorageClearable for MapStorageMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode, @@ -52,11 +58,57 @@ where } } -impl MapStorageMapper +impl MapStorageMapper where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode, V: StorageMapper + StorageClearable, +{ + /// Adds a default value for the key, if it is not already present. + /// + /// If the map did not have this key present, `true` is returned. + /// + /// If the map did have this value present, `false` is returned. + pub fn insert_default(&mut self, k: K) -> bool { + self.keys_set.insert(k) + } + + /// Removes the entry from the map. + /// + /// If the entry was removed, `true` is returned. + /// + /// If the map didn't contain an entry with this key, `false` is returned. + pub fn remove(&mut self, k: &K) -> bool { + if self.keys_set.remove(k) { + self.get_mapped_storage_value(k).clear(); + return true; + } + false + } +} + +impl StorageMapperFromAddress for MapStorageMapper> +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode, + V: StorageMapper + StorageClearable, +{ + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + MapStorageMapper { + _phantom_api: PhantomData, + base_key: base_key.clone(), + keys_set: SetMapper::new_from_address(address, base_key), + _phantom_value: PhantomData, + } + } +} + +impl MapStorageMapper +where + SA: StorageMapperApi, + A: StorageAddress, + K: TopEncode + TopDecode + NestedEncode + NestedDecode, + V: StorageMapper + StorageClearable, { fn build_named_key(&self, name: &[u8], key: &K) -> StorageKey { let mut named_key = self.base_key.clone(); @@ -70,6 +122,18 @@ where >::new(key) } + /// Gets a reference to the value in the entry. + pub fn get(&self, k: &K) -> Option { + if self.keys_set.contains(k) { + return Some(self.get_mapped_storage_value(k)); + } + None + } + + pub fn keys(&self) -> Keys { + self.keys_set.iter() + } + /// Returns `true` if the map contains no elements. pub fn is_empty(&self) -> bool { self.keys_set.is_empty() @@ -85,16 +149,8 @@ where self.keys_set.contains(k) } - /// Gets a reference to the value in the entry. - pub fn get(&self, k: &K) -> Option { - if self.keys_set.contains(k) { - return Some(self.get_mapped_storage_value(k)); - } - None - } - /// Gets the given key's corresponding entry in the map for in-place manipulation. - pub fn entry(&mut self, key: K) -> Entry { + pub fn entry(&mut self, key: K) -> Entry { if self.contains_key(&key) { Entry::Occupied(OccupiedEntry { key, @@ -110,79 +166,54 @@ where } } - /// Adds a default value for the key, if it is not already present. - /// - /// If the map did not have this key present, `true` is returned. - /// - /// If the map did have this value present, `false` is returned. - pub fn insert_default(&mut self, k: K) -> bool { - self.keys_set.insert(k) - } - - /// Removes the entry from the map. - /// - /// If the entry was removed, `true` is returned. - /// - /// If the map didn't contain an entry with this key, `false` is returned. - pub fn remove(&mut self, k: &K) -> bool { - if self.keys_set.remove(k) { - self.get_mapped_storage_value(k).clear(); - return true; - } - false - } - - /// An iterator visiting all keys in arbitrary order. - /// The iterator element type is `&'a K`. - pub fn keys(&self) -> Keys { - self.keys_set.iter() - } - /// An iterator visiting all values in arbitrary order. /// The iterator element type is `&'a V`. - pub fn values(&self) -> Values { + pub fn values(&self) -> Values { Values::new(self) } /// An iterator visiting all key-value pairs in arbitrary order. /// The iterator element type is `(&'a K, &'a V)`. - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter { Iter::new(self) } } -impl<'a, SA, K, V> IntoIterator for &'a MapStorageMapper +impl<'a, SA, A, K, V> IntoIterator for &'a MapStorageMapper where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, V: StorageMapper + StorageClearable, { type Item = (K, V); - type IntoIter = Iter<'a, SA, K, V>; + type IntoIter = Iter<'a, SA, A, K, V>; fn into_iter(self) -> Self::IntoIter { self.iter() } } -pub struct Iter<'a, SA, K, V> +pub struct Iter<'a, SA, A, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: StorageMapper + StorageClearable, { - key_iter: Keys<'a, SA, K>, - hash_map: &'a MapStorageMapper, + key_iter: Keys<'a, SA, A, K>, + hash_map: &'a MapStorageMapper, } -impl<'a, SA, K, V> Iter<'a, SA, K, V> +impl<'a, SA, A, K, V> Iter<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, V: StorageMapper + StorageClearable, { - fn new(hash_map: &'a MapStorageMapper) -> Iter<'a, SA, K, V> { + fn new(hash_map: &'a MapStorageMapper) -> Iter<'a, SA, A, K, V> { Iter { key_iter: hash_map.keys(), hash_map, @@ -190,9 +221,10 @@ where } } -impl<'a, SA, K, V> Iterator for Iter<'a, SA, K, V> +impl<'a, SA, A, K, V> Iterator for Iter<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, V: StorageMapper + StorageClearable, { @@ -201,30 +233,34 @@ 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 } } -pub struct Values<'a, SA, K, V> +pub struct Values<'a, SA, A, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: StorageMapper + StorageClearable, { - key_iter: Keys<'a, SA, K>, - hash_map: &'a MapStorageMapper, + key_iter: Keys<'a, SA, A, K>, + hash_map: &'a MapStorageMapper, } -impl<'a, SA, K, V> Values<'a, SA, K, V> +impl<'a, SA, A, K, V> Values<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, V: StorageMapper + StorageClearable, { - fn new(hash_map: &'a MapStorageMapper) -> Values<'a, SA, K, V> { + fn new(hash_map: &'a MapStorageMapper) -> Values<'a, SA, A, K, V> { Values { key_iter: hash_map.keys(), hash_map, @@ -232,9 +268,10 @@ where } } -impl<'a, SA, K, V> Iterator for Values<'a, SA, K, V> +impl<'a, SA, A, K, V> Iterator for Values<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, V: StorageMapper + StorageClearable, { @@ -250,29 +287,31 @@ where } } -pub enum Entry<'a, SA, K: 'a, V: 'a> +pub enum Entry<'a, SA, A, K: 'a, V: 'a> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: StorageMapper + StorageClearable, { /// A vacant entry. - Vacant(VacantEntry<'a, SA, K, V>), + Vacant(VacantEntry<'a, SA, A, K, V>), /// An occupied entry. - Occupied(OccupiedEntry<'a, SA, K, V>), + Occupied(OccupiedEntry<'a, SA, A, K, V>), } /// A view into a vacant entry in a `MapStorageMapper`. /// It is part of the [`Entry`] enum. -pub struct VacantEntry<'a, SA, K: 'a, V: 'a> +pub struct VacantEntry<'a, SA, A, K: 'a, V: 'a> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: StorageMapper + StorageClearable, { pub(super) key: K, - pub(super) map: &'a mut MapStorageMapper, + pub(super) map: &'a mut MapStorageMapper, // Be invariant in `K` and `V` pub(super) _marker: PhantomData<&'a mut (K, V)>, @@ -280,20 +319,21 @@ where /// A view into an occupied entry in a `MapStorageMapper`. /// It is part of the [`Entry`] enum. -pub struct OccupiedEntry<'a, SA, K: 'a, V: 'a> +pub struct OccupiedEntry<'a, SA, A, K: 'a, V: 'a> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, + A: StorageAddress, V: StorageMapper + StorageClearable, { pub(super) key: K, - pub(super) map: &'a mut MapStorageMapper, + pub(super) map: &'a mut MapStorageMapper, // Be invariant in `K` and `V` pub(super) _marker: PhantomData<&'a mut (K, V)>, } -impl<'a, SA, K, V> Entry<'a, SA, K, V> +impl<'a, SA, K, V> Entry<'a, SA, CurrentStorage, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, @@ -301,7 +341,7 @@ where { /// Ensures a value is in the entry by inserting the default if empty, and returns /// an `OccupiedEntry`. - pub fn or_insert_default(self) -> OccupiedEntry<'a, SA, K, V> { + pub fn or_insert_default(self) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> { match self { Entry::Occupied(entry) => entry, Entry::Vacant(entry) => entry.insert_default(), @@ -332,7 +372,7 @@ where } } -impl<'a, SA, K, V> Entry<'a, SA, K, V> +impl<'a, SA, K, V> Entry<'a, SA, CurrentStorage, K, V> where SA: StorageMapperApi, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, @@ -340,7 +380,7 @@ where { /// Ensures a value is in the entry by inserting the default value if empty, /// and returns an `OccupiedEntry`. - pub fn or_default(self) -> OccupiedEntry<'a, SA, K, V> { + pub fn or_default(self) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> { match self { Entry::Occupied(entry) => entry, Entry::Vacant(entry) => entry.insert_default(), @@ -348,9 +388,10 @@ where } } -impl<'a, SA, K, V> VacantEntry<'a, SA, K, V> +impl<'a, SA, A, K, V> VacantEntry<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, V: StorageMapper + StorageClearable, { @@ -359,10 +400,17 @@ where pub fn key(&self) -> &K { &self.key } +} +impl<'a, SA, K, V> VacantEntry<'a, SA, CurrentStorage, K, V> +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, + V: StorageMapper + StorageClearable, +{ /// Sets the value of the entry with the `VacantEntry`'s key, /// and returns an `OccupiedEntry`. - pub fn insert_default(self) -> OccupiedEntry<'a, SA, K, V> { + pub fn insert_default(self) -> OccupiedEntry<'a, SA, CurrentStorage, K, V> { self.map.insert_default(self.key.clone()); OccupiedEntry { key: self.key, @@ -372,9 +420,10 @@ where } } -impl<'a, SA, K, V> OccupiedEntry<'a, SA, K, V> +impl<'a, SA, A, K, V> OccupiedEntry<'a, SA, A, K, V> where SA: StorageMapperApi, + A: StorageAddress, K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, V: StorageMapper + StorageClearable, { @@ -387,7 +436,14 @@ where pub fn get(&self) -> V { self.map.get(&self.key).unwrap() } +} +impl<'a, SA, K, V> OccupiedEntry<'a, SA, CurrentStorage, K, V> +where + SA: StorageMapperApi, + K: TopEncode + TopDecode + NestedEncode + NestedDecode + Clone + 'static, + V: StorageMapper + StorageClearable, +{ /// Syntactic sugar, to more compactly express a get, update and set in one line. /// Takes whatever lies in storage, apples the given closure and saves the final value back to storage. /// Propagates the return value of the given function. diff --git a/framework/base/src/storage/mappers/mapper.rs b/framework/base/src/storage/mappers/mapper.rs index 3e21ad548e..89f9c80cd2 100644 --- a/framework/base/src/storage/mappers/mapper.rs +++ b/framework/base/src/storage/mappers/mapper.rs @@ -1,4 +1,4 @@ -use crate::{api::StorageMapperApi, storage::StorageKey}; +use crate::{api::StorageMapperApi, storage::StorageKey, types::ManagedAddress}; pub trait StorageMapper: 'static where @@ -8,6 +8,15 @@ where fn new(base_key: StorageKey) -> Self; } +pub trait StorageMapperFromAddress: 'static +where + SA: StorageMapperApi, +{ + /// Will be called automatically by the `#[storage_mapper_from_address]` + /// annotation generated code. + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self; +} + pub trait StorageClearable { /// Clears all the entries owned by the storage. fn clear(&mut self); diff --git a/framework/base/src/storage/mappers/ordered_binary_tree_mapper.rs b/framework/base/src/storage/mappers/ordered_binary_tree_mapper.rs new file mode 100644 index 0000000000..2425c59049 --- /dev/null +++ b/framework/base/src/storage/mappers/ordered_binary_tree_mapper.rs @@ -0,0 +1,474 @@ +use core::marker::PhantomData; + +use codec::Empty; + +use crate::{ + api::{ErrorApiImpl, StorageMapperApi}, + storage::StorageKey, + storage_set, + types::ManagedType, +}; + +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + StorageMapper, +}; + +use crate::codec::{ + self, + derive::{TopDecode, TopEncode}, + NestedDecode, NestedEncode, +}; + +pub type NodeId = u64; + +pub const NULL_NODE_ID: NodeId = 0; + +static ROOT_ID_SUFFIX: &[u8] = b"_rootId"; +static ID_SUFFIX: &[u8] = b"_id"; +static LAST_ID_KEY_SUFFIX: &[u8] = b"_lastId"; + +static CORRUPT_TREE_ERR_MGS: &[u8] = b"Corrupt tree"; + +// https://en.wikipedia.org/wiki/Binary_search_tree + +#[derive(TopEncode, TopDecode, Clone, PartialEq, Debug)] +pub struct OrderedBinaryTreeNode { + pub current_node_id: NodeId, + pub left_id: NodeId, + pub right_id: NodeId, + pub parent_id: NodeId, + pub data: T, +} + +impl OrderedBinaryTreeNode +where + T: NestedEncode + NestedDecode + PartialOrd + PartialEq + Clone, +{ + pub fn new(current_node_id: NodeId, data: T) -> Self { + Self { + data, + current_node_id, + left_id: NULL_NODE_ID, + right_id: NULL_NODE_ID, + parent_id: NULL_NODE_ID, + } + } +} + +pub struct OrderedBinaryTreeMapper +where + SA: StorageMapperApi, + A: StorageAddress, + T: NestedEncode + NestedDecode + PartialOrd + PartialEq + Clone, +{ + address: A, + key: StorageKey, + _phantom_api: PhantomData, + _phantom_item: PhantomData, +} + +impl StorageMapper for OrderedBinaryTreeMapper +where + SA: StorageMapperApi, + T: NestedEncode + NestedDecode + PartialOrd + PartialEq + Clone + 'static, +{ + #[inline] + fn new(base_key: StorageKey) -> Self { + OrderedBinaryTreeMapper { + address: CurrentStorage, + key: base_key, + _phantom_api: PhantomData, + _phantom_item: PhantomData, + } + } +} + +impl OrderedBinaryTreeMapper +where + SA: StorageMapperApi, + A: StorageAddress, + T: NestedEncode + NestedDecode + PartialOrd + PartialEq + Clone, +{ + pub fn get_root(&self) -> Option> { + let root_key = self.build_root_key(); + let storage_len = self.address.address_storage_get_len(root_key.as_ref()); + if storage_len == 0 { + return None; + } + + Some(self.address.address_storage_get(root_key.as_ref())) + } + + pub fn get_depth(&self, node: &OrderedBinaryTreeNode) -> usize { + let opt_left_node = self.get_node_by_id(node.left_id); + let opt_right_node = self.get_node_by_id(node.right_id); + + let l_depth = match opt_left_node { + Some(left_node) => self.get_depth(&left_node), + None => 0, + }; + let r_depth = match opt_right_node { + Some(right_node) => self.get_depth(&right_node), + None => 0, + }; + + core::cmp::max(l_depth, r_depth) + 1 + } + + pub fn recursive_search( + &self, + opt_node: Option>, + data: &T, + ) -> Option> { + opt_node.as_ref()?; + + let node = unsafe { opt_node.unwrap_unchecked() }; + if &node.data == data { + return Some(node); + } + + if data < &node.data { + let opt_left_node = self.get_node_by_id(node.left_id); + self.recursive_search(opt_left_node, data) + } else { + let opt_right_node = self.get_node_by_id(node.right_id); + self.recursive_search(opt_right_node, data) + } + } + + pub fn iterative_search( + &self, + mut opt_node: Option>, + data: &T, + ) -> Option> { + while opt_node.is_some() { + let node = unsafe { opt_node.unwrap_unchecked() }; + if &node.data == data { + return Some(node); + } + + if data < &node.data { + opt_node = self.get_node_by_id(node.left_id); + } else { + opt_node = self.get_node_by_id(node.right_id); + } + } + + None + } + + pub fn find_max(&self, mut node: OrderedBinaryTreeNode) -> OrderedBinaryTreeNode { + while node.right_id != NULL_NODE_ID { + node = self.try_get_node_by_id(node.right_id); + } + + node + } + + pub fn find_min(&self, mut node: OrderedBinaryTreeNode) -> OrderedBinaryTreeNode { + while node.left_id != NULL_NODE_ID { + node = self.try_get_node_by_id(node.left_id); + } + + node + } + + pub fn find_successor( + &self, + mut node: OrderedBinaryTreeNode, + ) -> Option> { + if node.right_id != NULL_NODE_ID { + let right_node = self.try_get_node_by_id(node.right_id); + return Some(self.find_min(right_node)); + } + + let mut successor_id = node.parent_id; + let mut opt_successor = self.get_node_by_id(successor_id); + while successor_id != NULL_NODE_ID { + if opt_successor.is_none() { + SA::error_api_impl().signal_error(CORRUPT_TREE_ERR_MGS); + } + + let successor = unsafe { opt_successor.unwrap_unchecked() }; + if node.current_node_id != successor.right_id { + return Some(successor); + } + + successor_id = successor.parent_id; + opt_successor = self.get_node_by_id(successor_id); + node = successor; + } + + opt_successor + } + + pub fn find_predecessor( + &self, + mut node: OrderedBinaryTreeNode, + ) -> Option> { + if node.left_id != NULL_NODE_ID { + let left_node = self.try_get_node_by_id(node.left_id); + return Some(self.find_max(left_node)); + } + + let mut predecessor_id = node.parent_id; + let mut opt_predecessor = self.get_node_by_id(predecessor_id); + while predecessor_id != NULL_NODE_ID { + if opt_predecessor.is_none() { + SA::error_api_impl().signal_error(CORRUPT_TREE_ERR_MGS); + } + + let predecessor = unsafe { opt_predecessor.unwrap_unchecked() }; + if node.current_node_id != predecessor.left_id { + return Some(predecessor); + } + + predecessor_id = predecessor.parent_id; + opt_predecessor = self.get_node_by_id(predecessor_id); + node = predecessor; + } + + opt_predecessor + } + + pub fn insert_element(&mut self, new_data: T) -> u64 { + let new_node_id = self.get_and_increment_last_id(); + let mut new_node = OrderedBinaryTreeNode::new(new_node_id, new_data); + + 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.clone_from(&opt_current_node); + + let current_node = unsafe { opt_current_node.unwrap_unchecked() }; + if new_node.data == current_node.data { + return 0u64; + } + + if new_node.data < current_node.data { + opt_current_node = self.get_node_by_id(current_node.left_id); + } else { + opt_current_node = self.get_node_by_id(current_node.right_id); + } + } + + let new_node_parent_id = match &opt_new_node_parent { + Some(node) => node.current_node_id, + None => NULL_NODE_ID, + }; + new_node.parent_id = new_node_parent_id; + + if opt_new_node_parent.is_none() { + let root_id_key = self.build_root_id_key(); + storage_set(root_id_key.as_ref(), &new_node.current_node_id); + + let root_key = self.build_root_key(); + storage_set(root_key.as_ref(), &new_node); + + return 0u64; + } + + let mut new_node_parent = unsafe { opt_new_node_parent.unwrap_unchecked() }; + if new_node.data < new_node_parent.data { + new_node_parent.left_id = new_node.current_node_id; + } else { + new_node_parent.right_id = new_node.current_node_id; + } + + self.set_item(new_node_id, &new_node); + self.set_item(new_node_parent.current_node_id, &new_node_parent); + + new_node_id + } + + pub fn delete_node(&mut self, data: T) { + let opt_root = self.get_root(); + let opt_node = self.iterative_search(opt_root, &data); + if opt_node.is_none() { + SA::error_api_impl().signal_error(b"Node not found"); + } + + let node = unsafe { opt_node.unwrap_unchecked() }; + if node.left_id == NULL_NODE_ID { + let opt_to_add = self.get_node_by_id(node.right_id); + self.shift_nodes(&node, opt_to_add); + + return; + } + + if node.right_id == NULL_NODE_ID { + let opt_to_add = self.get_node_by_id(node.left_id); + self.shift_nodes(&node, opt_to_add); + + return; + } + + let opt_successor = self.find_successor(node.clone()); + if opt_successor.is_none() { + SA::error_api_impl().signal_error(CORRUPT_TREE_ERR_MGS); + } + + let mut successor = unsafe { opt_successor.unwrap_unchecked() }; + if successor.parent_id != node.current_node_id { + let opt_right = self.get_node_by_id(successor.right_id); + self.shift_nodes(&successor, opt_right); + + successor = self.try_get_node_by_id(successor.current_node_id); + successor.right_id = node.right_id; + + let opt_successor_right_node = self.get_node_by_id(successor.right_id); + if opt_successor_right_node.is_none() { + SA::error_api_impl().signal_error(CORRUPT_TREE_ERR_MGS); + } + + let mut successor_right_node = unsafe { opt_successor_right_node.unwrap_unchecked() }; + successor_right_node.parent_id = successor.current_node_id; + + self.set_item(successor_right_node.current_node_id, &successor_right_node); + } + + self.shift_nodes(&node, Some(successor.clone())); + successor = self.try_get_node_by_id(successor.current_node_id); + successor.left_id = node.left_id; + + let opt_successor_left_node = self.get_node_by_id(successor.left_id); + if opt_successor_left_node.is_none() { + SA::error_api_impl().signal_error(CORRUPT_TREE_ERR_MGS); + } + + let mut successor_left_node = unsafe { opt_successor_left_node.unwrap_unchecked() }; + successor_left_node.parent_id = successor.current_node_id; + + self.set_item(successor_left_node.current_node_id, &successor_left_node); + self.set_item(successor.current_node_id, &successor); + } + + fn shift_nodes( + &mut self, + to_delete: &OrderedBinaryTreeNode, + mut opt_to_add: Option>, + ) { + if to_delete.parent_id == NULL_NODE_ID { + let root_id_key = self.build_root_id_key(); + match &mut opt_to_add { + Some(to_add) => { + to_add.parent_id = NULL_NODE_ID; + storage_set(root_id_key.as_ref(), &to_add.current_node_id); + + let root_key = self.build_root_key(); + storage_set(root_key.as_ref(), to_add); + }, + None => { + let root_key = self.build_root_key(); + + storage_set(root_id_key.as_ref(), &Empty); + storage_set(root_key.as_ref(), &Empty); + }, + }; + + return; + } + + let to_add_id = match &opt_to_add { + Some(to_add) => to_add.current_node_id, + None => NULL_NODE_ID, + }; + + let mut parent = self.try_get_node_by_id(to_delete.parent_id); + if to_delete.current_node_id == parent.left_id { + parent.left_id = to_add_id; + } else { + parent.right_id = to_add_id; + } + + if let Some(to_add) = &mut opt_to_add { + to_add.parent_id = to_delete.parent_id; + + self.set_item(to_add.current_node_id, to_add); + } + + self.set_item(parent.current_node_id, &parent); + self.clear_item(to_delete.current_node_id); + } +} + +impl OrderedBinaryTreeMapper +where + SA: StorageMapperApi, + A: StorageAddress, + T: NestedEncode + NestedDecode + PartialOrd + PartialEq + Clone, +{ + fn get_node_by_id(&self, id: NodeId) -> Option> { + if id == NULL_NODE_ID { + return None; + } + + let key = self.build_key_for_item(id); + let storage_len = self.address.address_storage_get_len(key.as_ref()); + if storage_len == 0 { + return None; + } + + Some(self.address.address_storage_get(key.as_ref())) + } + + fn try_get_node_by_id(&self, id: NodeId) -> OrderedBinaryTreeNode { + let opt_node = self.get_node_by_id(id); + if opt_node.is_none() { + SA::error_api_impl().signal_error(CORRUPT_TREE_ERR_MGS); + } + + unsafe { opt_node.unwrap_unchecked() } + } + + fn build_root_id_key(&self) -> StorageKey { + let mut key = self.key.clone(); + key.append_bytes(ROOT_ID_SUFFIX); + + key + } + + fn build_root_key(&self) -> StorageKey { + let mut key = self.key.clone(); + key.append_bytes(ROOT_ID_SUFFIX); + + let root_id = self.address.address_storage_get(key.as_ref()); + + self.build_key_for_item(root_id) + } + + fn build_key_for_item(&self, id: NodeId) -> StorageKey { + let mut item_key = self.key.clone(); + item_key.append_bytes(ID_SUFFIX); + item_key.append_item(&id); + + item_key + } + + fn build_last_id_key(&self) -> StorageKey { + let mut key = self.key.clone(); + key.append_bytes(LAST_ID_KEY_SUFFIX); + + key + } + + fn get_and_increment_last_id(&self) -> NodeId { + let key = self.build_last_id_key(); + let last_id: NodeId = self.address.address_storage_get(key.as_ref()); + let new_id = last_id + 1; + storage_set(key.as_ref(), &new_id); + + new_id + } + + fn set_item(&mut self, id: NodeId, node: &OrderedBinaryTreeNode) { + let key = self.build_key_for_item(id); + storage_set(key.as_ref(), node); + } + + fn clear_item(&mut self, id: NodeId) { + let key = self.build_key_for_item(id); + storage_set(key.as_ref(), &Empty); + } +} diff --git a/framework/base/src/storage/mappers/queue_mapper.rs b/framework/base/src/storage/mappers/queue_mapper.rs index 6bfaacfeb3..9937736b01 100644 --- a/framework/base/src/storage/mappers/queue_mapper.rs +++ b/framework/base/src/storage/mappers/queue_mapper.rs @@ -1,17 +1,20 @@ use core::marker::PhantomData; -use super::{StorageClearable, StorageMapper}; +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + StorageClearable, StorageMapper, StorageMapperFromAddress, +}; 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_get, storage_set, StorageKey}, - types::{ManagedType, MultiValueEncoded}, + storage::{storage_set, StorageKey}, + types::{ManagedAddress, ManagedType, MultiValueEncoded}, }; use alloc::vec::Vec; @@ -62,17 +65,19 @@ impl QueueMapperInfo { /// /// The `QueueMapper` allows pushing and popping elements at either end /// in constant time. -pub struct QueueMapper +pub struct QueueMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { _phantom_api: PhantomData, + address: A, base_key: StorageKey, _phantom_item: PhantomData, } -impl StorageMapper for QueueMapper +impl StorageMapper for QueueMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -80,13 +85,14 @@ where fn new(base_key: StorageKey) -> Self { QueueMapper { _phantom_api: PhantomData, + address: CurrentStorage, base_key, _phantom_item: PhantomData, } } } -impl StorageClearable for QueueMapper +impl StorageClearable for QueueMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -104,39 +110,15 @@ where } } -impl QueueMapper +impl QueueMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, { - fn build_node_id_named_key(&self, name: &[u8], node_id: u32) -> StorageKey { - let mut named_key = self.base_key.clone(); - named_key.append_bytes(name); - named_key.append_item(&node_id); - named_key - } - - fn build_name_key(&self, name: &[u8]) -> StorageKey { - let mut name_key = self.base_key.clone(); - name_key.append_bytes(name); - name_key - } - - fn get_info(&self) -> QueueMapperInfo { - storage_get(self.build_name_key(INFO_IDENTIFIER).as_ref()) - } - fn set_info(&mut self, value: QueueMapperInfo) { storage_set(self.build_name_key(INFO_IDENTIFIER).as_ref(), &value); } - fn get_node(&self, node_id: u32) -> Node { - storage_get( - self.build_node_id_named_key(NODE_IDENTIFIER, node_id) - .as_ref(), - ) - } - fn set_node(&mut self, node_id: u32, item: Node) { storage_set( self.build_node_id_named_key(NODE_IDENTIFIER, node_id) @@ -153,20 +135,6 @@ where ); } - fn get_value(&self, node_id: u32) -> T { - storage_get( - self.build_node_id_named_key(VALUE_IDENTIFIER, node_id) - .as_ref(), - ) - } - - fn get_value_option(&self, node_id: u32) -> Option { - if node_id == NULL_ENTRY { - return None; - } - Some(self.get_value(node_id)) - } - fn set_value(&mut self, node_id: u32, value: &T) { storage_set( self.build_node_id_named_key(VALUE_IDENTIFIER, node_id) @@ -183,20 +151,6 @@ where ) } - /// Returns `true` if the `Queue` is empty. - /// - /// This operation should compute in *O*(1) time. - pub fn is_empty(&self) -> bool { - self.get_info().len == 0 - } - - /// Returns the length of the `Queue`. - /// - /// This operation should compute in *O*(1) time. - pub fn len(&self) -> usize { - self.get_info().len as usize - } - /// Appends an element to the back of a queue /// and returns the node id of the newly added node. /// @@ -264,18 +218,6 @@ where self.set_info(info); } - /// Provides a copy to the front element, or `None` if the queue is - /// empty. - pub fn front(&self) -> Option { - self.get_value_option(self.get_info().front) - } - - /// Provides a copy to the back element, or `None` if the queue is - /// empty. - pub fn back(&self) -> Option { - self.get_value_option(self.get_info().back) - } - /// Removes the last element from a queue and returns it, or `None` if /// it is empty. /// @@ -327,12 +269,102 @@ where self.set_info(info); Some(removed_value) } +} + +impl StorageMapperFromAddress for QueueMapper> +where + SA: StorageMapperApi, + T: TopEncode + TopDecode, +{ + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + QueueMapper { + _phantom_api: PhantomData::, + address, + base_key, + _phantom_item: PhantomData::, + } + } +} - /// Provides a forward iterator. - pub fn iter(&self) -> Iter { +impl QueueMapper +where + SA: StorageMapperApi, + A: StorageAddress, + T: TopEncode + TopDecode + 'static, +{ + fn build_node_id_named_key(&self, name: &[u8], node_id: u32) -> StorageKey { + let mut named_key = self.base_key.clone(); + named_key.append_bytes(name); + named_key.append_item(&node_id); + named_key + } + + fn build_name_key(&self, name: &[u8]) -> StorageKey { + let mut name_key = self.base_key.clone(); + name_key.append_bytes(name); + name_key + } + + pub fn iter(&self) -> Iter { Iter::new(self) } + pub fn iter_from_node_id(&self, node_id: u32) -> Iter { + Iter::new_from_node_id(self, node_id) + } + + fn get_info(&self) -> QueueMapperInfo { + self.address + .address_storage_get(self.build_name_key(INFO_IDENTIFIER).as_ref()) + } + + pub fn get_node(&self, node_id: u32) -> Node { + self.address.address_storage_get( + self.build_node_id_named_key(NODE_IDENTIFIER, node_id) + .as_ref(), + ) + } + + fn get_value(&self, node_id: u32) -> T { + self.address.address_storage_get( + self.build_node_id_named_key(VALUE_IDENTIFIER, node_id) + .as_ref(), + ) + } + + pub fn get_value_option(&self, node_id: u32) -> Option { + if node_id == NULL_ENTRY { + return None; + } + Some(self.get_value(node_id)) + } + + /// Returns `true` if the `Queue` is empty. + /// + /// This operation should compute in *O*(1) time. + pub fn is_empty(&self) -> bool { + self.get_info().len == 0 + } + + /// Returns the length of the `Queue`. + /// + /// This operation should compute in *O*(1) time. + pub fn len(&self) -> usize { + self.get_info().len as usize + } + + /// Provides a copy to the front element, or `None` if the queue is + /// empty. + pub fn front(&self) -> Option { + self.get_value_option(self.get_info().front) + } + + /// Provides a copy to the back element, or `None` if the queue is + /// empty. + pub fn back(&self) -> Option { + self.get_value_option(self.get_info().back) + } + /// Runs several checks in order to verify that both forwards and backwards iteration /// yields the same node entries and that the number of items in the queue is correct. /// Used for unit testing. @@ -405,14 +437,15 @@ where } } -impl<'a, SA, T> IntoIterator for &'a QueueMapper +impl<'a, SA, A, T> IntoIterator for &'a QueueMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { type Item = T; - type IntoIter = Iter<'a, SA, T>; + type IntoIter = Iter<'a, SA, A, T>; fn into_iter(self) -> Self::IntoIter { self.iter() @@ -423,31 +456,38 @@ where /// /// This `struct` is created by [`QueueMapper::iter()`]. See its /// documentation for more. -pub struct Iter<'a, SA, T> +pub struct Iter<'a, SA, A, T> where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { node_id: u32, - queue: &'a QueueMapper, + queue: &'a QueueMapper, } -impl<'a, SA, T> Iter<'a, SA, T> +impl<'a, SA, A, T> Iter<'a, SA, A, T> where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { - fn new(queue: &'a QueueMapper) -> Iter<'a, SA, T> { + fn new(queue: &'a QueueMapper) -> Iter<'a, SA, A, T> { Iter { node_id: queue.get_info().front, queue, } } + + pub fn new_from_node_id(queue: &'a QueueMapper, node_id: u32) -> Iter<'a, SA, A, T> { + Iter { node_id, queue } + } } -impl<'a, SA, T> Iterator for Iter<'a, SA, T> +impl<'a, SA, A, T> Iterator for Iter<'a, SA, A, T> where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { type Item = T; @@ -464,7 +504,7 @@ where } /// Behaves like a MultiResultVec when an endpoint result. -impl TopEncodeMulti for QueueMapper +impl TopEncodeMulti for QueueMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -478,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, @@ -486,15 +533,21 @@ where } /// Behaves like a MultiResultVec when an endpoint result. -impl TypeAbi for QueueMapper +impl TypeAbi for QueueMapper 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 127164136a..fbbb41ba3b 100644 --- a/framework/base/src/storage/mappers/set_mapper.rs +++ b/framework/base/src/storage/mappers/set_mapper.rs @@ -1,32 +1,73 @@ use core::marker::PhantomData; +use storage_get_from_address::storage_get_len_from_address; + pub use super::queue_mapper::Iter; -use super::{QueueMapper, StorageClearable, StorageMapper}; +use super::{QueueMapper, StorageClearable, StorageMapper, StorageMapperFromAddress}; 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, storage_set, StorageKey}, - types::{ManagedType, MultiValueEncoded}, + storage::{storage_get_from_address, storage_set, StorageKey}, + storage_get, storage_get_len, + types::{ManagedAddress, ManagedRef, ManagedType, MultiValueEncoded}, }; const NULL_ENTRY: u32 = 0; const NODE_ID_IDENTIFIER: &[u8] = b".node_id"; -pub struct SetMapper +pub trait StorageAddress +where + SA: StorageMapperApi, +{ + fn address_storage_get(&self, key: ManagedRef<'_, SA, StorageKey>) -> T; + fn address_storage_get_len(&self, key: ManagedRef<'_, SA, StorageKey>) -> usize; +} + +pub struct CurrentStorage; + +impl StorageAddress for CurrentStorage +where + SA: StorageMapperApi, +{ + fn address_storage_get(&self, key: ManagedRef<'_, SA, StorageKey>) -> T { + storage_get(key) + } + + fn address_storage_get_len(&self, key: ManagedRef<'_, SA, StorageKey>) -> usize { + storage_get_len(key) + } +} + +impl StorageAddress for ManagedAddress where SA: StorageMapperApi, +{ + fn address_storage_get(&self, key: ManagedRef<'_, SA, StorageKey>) -> T { + storage_get_from_address(self.as_ref(), key) + } + + fn address_storage_get_len(&self, key: ManagedRef<'_, SA, StorageKey>) -> usize { + storage_get_len_from_address(self.as_ref(), key) + } +} + +pub struct SetMapper +where + SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, { _phantom_api: PhantomData, + address: A, base_key: StorageKey, - queue_mapper: QueueMapper, + queue_mapper: QueueMapper, } -impl StorageMapper for SetMapper +impl StorageMapper for SetMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode, @@ -34,13 +75,14 @@ where fn new(base_key: StorageKey) -> Self { SetMapper { _phantom_api: PhantomData, + address: CurrentStorage, base_key: base_key.clone(), - queue_mapper: QueueMapper::::new(base_key), + queue_mapper: QueueMapper::new(base_key), } } } -impl StorageClearable for SetMapper +impl StorageClearable for SetMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode, @@ -53,25 +95,26 @@ where } } -impl SetMapper +impl StorageMapperFromAddress for SetMapper> where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode, { - fn build_named_value_key(&self, name: &[u8], value: &T) -> StorageKey { - let mut named_key = self.base_key.clone(); - named_key.append_bytes(name); - named_key.append_item(value); - named_key - } - - fn get_node_id(&self, value: &T) -> u32 { - storage_get( - self.build_named_value_key(NODE_ID_IDENTIFIER, value) - .as_ref(), - ) + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + SetMapper { + _phantom_api: PhantomData, + address: address.clone(), + base_key: base_key.clone(), + queue_mapper: QueueMapper::new_from_address(address, base_key), + } } +} +impl SetMapper +where + SA: StorageMapperApi, + T: TopEncode + TopDecode + NestedEncode + NestedDecode, +{ fn set_node_id(&self, value: &T, node_id: u32) { storage_set( self.build_named_value_key(NODE_ID_IDENTIFIER, value) @@ -88,21 +131,6 @@ where ); } - /// Returns `true` if the set contains no elements. - pub fn is_empty(&self) -> bool { - self.queue_mapper.is_empty() - } - - /// Returns the number of elements in the set. - pub fn len(&self) -> usize { - self.queue_mapper.len() - } - - /// Returns `true` if the set contains a value. - pub fn contains(&self, value: &T) -> bool { - self.get_node_id(value) != NULL_ENTRY - } - /// Adds a value to the set. /// /// If the set did not have this value present, `true` is returned. @@ -137,34 +165,106 @@ where self.remove(&item); } } +} + +impl SetMapper +where + SA: StorageMapperApi, + A: StorageAddress, + T: TopEncode + TopDecode + NestedEncode + NestedDecode, +{ + pub fn build_named_value_key(&self, name: &[u8], value: &T) -> StorageKey { + let mut named_key = self.base_key.clone(); + named_key.append_bytes(name); + named_key.append_item(value); + named_key + } /// An iterator visiting all elements in arbitrary order. /// The iterator element type is `&'a T`. - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter { self.queue_mapper.iter() } + pub fn iter_from(&self, value: &T) -> Iter { + let node_id = self.get_node_id(value); + self.queue_mapper.iter_from_node_id(node_id) + } + + fn get_node_id(&self, value: &T) -> u32 { + self.address.address_storage_get( + self.build_named_value_key(NODE_ID_IDENTIFIER, value) + .as_ref(), + ) + } + + /// Returns `true` if the set contains a value. + pub fn contains(&self, value: &T) -> bool { + self.get_node_id(value) != NULL_ENTRY + } + + /// Returns `true` if the set contains no elements. + pub fn is_empty(&self) -> bool { + self.queue_mapper.is_empty() + } + + /// Returns the number of elements in the set. + pub fn len(&self) -> usize { + self.queue_mapper.len() + } + /// Checks the internal consistency of the collection. Used for unit tests. pub fn check_internal_consistency(&self) -> bool { self.queue_mapper.check_internal_consistency() } + + pub fn next(&self, value: &T) -> Option { + let node_id = self.get_node_id(value); + if node_id == NULL_ENTRY { + return None; + } + + let next_node_id = self.queue_mapper.get_node(node_id).next; + + self.queue_mapper.get_value_option(next_node_id) + } + + pub fn previous(&self, value: &T) -> Option { + let node_id = self.get_node_id(value); + if node_id == NULL_ENTRY { + return None; + } + + let next_node_id = self.queue_mapper.get_node(node_id).previous; + + self.queue_mapper.get_value_option(next_node_id) + } + + pub fn front(&self) -> Option { + self.queue_mapper.front() + } + + pub fn back(&self) -> Option { + self.queue_mapper.back() + } } -impl<'a, SA, T> IntoIterator for &'a SetMapper +impl<'a, SA, A, T> IntoIterator for &'a SetMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, { type Item = T; - type IntoIter = Iter<'a, SA, T>; + type IntoIter = Iter<'a, SA, A, T>; fn into_iter(self) -> Self::IntoIter { self.iter() } } -impl Extend for SetMapper +impl Extend for SetMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, @@ -180,7 +280,7 @@ where } /// Behaves like a MultiResultVec when an endpoint result. -impl TopEncodeMulti for SetMapper +impl TopEncodeMulti for SetMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, @@ -194,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, @@ -202,15 +309,21 @@ where } /// Behaves like a MultiResultVec when an endpoint result. -impl TypeAbi for SetMapper +impl TypeAbi for SetMapper 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 cc6763e9be..fa9448af69 100644 --- a/framework/base/src/storage/mappers/single_value_mapper.rs +++ b/framework/base/src/storage/mappers/single_value_mapper.rs @@ -1,34 +1,34 @@ use core::{borrow::Borrow, marker::PhantomData}; -use super::StorageMapper; +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + StorageMapper, StorageMapperFromAddress, +}; 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, - }, - storage::{ - storage_clear, storage_get, storage_get_from_address, storage_get_len, storage_set, - StorageKey, + multi_types::PlaceholderOutput, DecodeErrorHandler, EncodeErrorHandler, TopDecode, + TopDecodeInput, TopEncode, TopEncodeMulti, TopEncodeMultiOutput, TopEncodeOutput, }, + storage::{storage_clear, storage_set, StorageKey}, types::{ManagedAddress, ManagedType}, }; -use storage_get_from_address::storage_get_len_from_address; /// Manages a single serializable item in storage. -pub struct SingleValueMapper +pub struct SingleValueMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { + address: A, key: StorageKey, _phantom_api: PhantomData, _phantom_item: PhantomData, } -impl StorageMapper for SingleValueMapper +impl StorageMapper for SingleValueMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -36,6 +36,7 @@ where #[inline] fn new(base_key: StorageKey) -> Self { SingleValueMapper { + address: CurrentStorage, key: base_key, _phantom_api: PhantomData, _phantom_item: PhantomData, @@ -43,19 +44,31 @@ where } } -impl SingleValueMapper +impl StorageMapperFromAddress for SingleValueMapper> where SA: StorageMapperApi, T: TopEncode + TopDecode, { - /// Retrieves current value from storage. - pub fn get(&self) -> T { - storage_get(self.key.as_ref()) + #[inline] + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + SingleValueMapper { + address, + key: base_key, + _phantom_api: PhantomData, + _phantom_item: PhantomData, + } } +} - /// Gets the value from the given address. Both adresses have to be in the same shard. - pub fn get_from_address(&self, address: &ManagedAddress) -> T { - storage_get_from_address(address.as_ref(), self.key.as_ref()) +impl SingleValueMapper +where + SA: StorageMapperApi, + A: StorageAddress, + T: TopEncode + TopDecode, +{ + /// Retrieves current value from storage. + pub fn get(&self) -> T { + self.address.address_storage_get(self.key.as_ref()) } /// Returns whether the storage managed by this mapper is empty. @@ -63,13 +76,16 @@ where self.raw_byte_length() == 0 } - /// Returns whether the storage at the given key is empty at the given address. - /// Both adresses have to be in the same shard. - pub fn is_empty_at_address(&self, address: &ManagedAddress) -> bool { - let len = storage_get_len_from_address(address.as_ref(), self.key.as_ref()); - len == 0 + pub fn raw_byte_length(&self) -> usize { + self.address.address_storage_get_len(self.key.as_ref()) } +} +impl SingleValueMapper +where + SA: StorageMapperApi, + T: TopEncode + TopDecode, +{ /// Saves argument to storage. /// /// Accepts owned item of type `T`, or any borrowed form of it, such as `&T`. @@ -107,10 +123,6 @@ where result } - pub fn raw_byte_length(&self) -> usize { - storage_get_len(self.key.as_ref()) - } - /// Takes the value out of the storage, clearing it in the process. pub fn take(&self) -> T { let value = self.get(); @@ -129,7 +141,7 @@ where } } -impl TopEncodeMulti for SingleValueMapper +impl TopEncodeMulti for SingleValueMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -145,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 { @@ -164,13 +176,13 @@ impl TopDecode for SingleValue { I: TopDecodeInput, H: DecodeErrorHandler, { - Ok(SingleValue(T::top_decode_or_handle_err(input, h)?)) + Ok(SingleValue::(T::top_decode_or_handle_err(input, h)?)) } } impl From for SingleValue { fn from(value: T) -> Self { - SingleValue(value) + SingleValue::(value) } } @@ -181,37 +193,43 @@ impl SingleValue { } } -impl !CodecFromSelf for SingleValueMapper +impl TypeAbiFrom> for SingleValue where SA: StorageMapperApi, 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, { } -impl TypeAbi for SingleValueMapper +impl TypeAbi for SingleValueMapper 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 1d5b5df391..a1789d695a 100644 --- a/framework/base/src/storage/mappers/unique_id_mapper.rs +++ b/framework/base/src/storage/mappers/unique_id_mapper.rs @@ -1,9 +1,15 @@ -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, + }, + types::ManagedAddress, }; -use super::{StorageMapper, VecMapper}; +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + StorageMapper, StorageMapperFromAddress, VecMapper, +}; use crate::{ abi::{TypeAbi, TypeDescriptionContainer, TypeName}, api::{ErrorApiImpl, StorageMapperApi}, @@ -18,39 +24,47 @@ const EMPTY_ENTRY: UniqueId = 0; /// Holds the values from 1 to N with as little storage interaction as possible /// If Mapper[i] = i, then it stores nothing, i.e. "0" /// If Mapper[i] is equal to another value, then it stores the value -pub struct UniqueIdMapper +pub struct UniqueIdMapper where SA: StorageMapperApi, + A: StorageAddress, { + _address: A, base_key: StorageKey, - vec_mapper: VecMapper, + vec_mapper: VecMapper, } -impl StorageMapper for UniqueIdMapper +impl StorageMapper for UniqueIdMapper where SA: StorageMapperApi, { fn new(base_key: StorageKey) -> Self { Self { + _address: CurrentStorage, base_key: base_key.clone(), vec_mapper: VecMapper::new(base_key), } } } -impl UniqueIdMapper +impl StorageMapperFromAddress for UniqueIdMapper> where SA: StorageMapperApi, { - /// Initializes the mapper's length. This may not be set again afterwards. - pub fn set_initial_len(&mut self, len: usize) { - if !self.vec_mapper.is_empty() { - SA::error_api_impl().signal_error(b"len already set"); + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + Self { + _address: address.clone(), + base_key: base_key.clone(), + vec_mapper: VecMapper::new_from_address(address, base_key), } - - self.set_internal_mapper_len(len); } +} +impl UniqueIdMapper +where + SA: StorageMapperApi, + A: StorageAddress, +{ #[inline] pub fn len(&self) -> usize { self.vec_mapper.len() @@ -71,6 +85,25 @@ where } } + /// Provides a forward iterator. + pub fn iter(&self) -> Iter { + Iter::new(self) + } +} + +impl UniqueIdMapper +where + SA: StorageMapperApi, +{ + /// Initializes the mapper's length. This may not be set again afterwards. + pub fn set_initial_len(&mut self, len: usize) { + if !self.vec_mapper.is_empty() { + SA::error_api_impl().signal_error(b"len already set"); + } + + self.set_internal_mapper_len(len); + } + /// Gets the value from the index and removes it. /// The value is replaced by the last item, and length is decremented. pub fn swap_remove(&mut self, index: usize) -> UniqueId { @@ -107,40 +140,38 @@ where len_key.append_bytes(&b".len"[..]); storage_set(len_key.as_ref(), &new_len); } - - /// Provides a forward iterator. - pub fn iter(&self) -> Iter { - Iter::new(self) - } } -impl<'a, SA> IntoIterator for &'a UniqueIdMapper +impl<'a, SA, A> IntoIterator for &'a UniqueIdMapper where SA: StorageMapperApi, + A: StorageAddress, { type Item = usize; - type IntoIter = Iter<'a, SA>; + type IntoIter = Iter<'a, SA, A>; fn into_iter(self) -> Self::IntoIter { self.iter() } } -pub struct Iter<'a, SA> +pub struct Iter<'a, SA, A> where SA: StorageMapperApi, + A: StorageAddress, { index: usize, len: usize, - id_mapper: &'a UniqueIdMapper, + id_mapper: &'a UniqueIdMapper, } -impl<'a, SA> Iter<'a, SA> +impl<'a, SA, A> Iter<'a, SA, A> where SA: StorageMapperApi, + A: StorageAddress, { - fn new(id_mapper: &'a UniqueIdMapper) -> Iter<'a, SA> { + fn new(id_mapper: &'a UniqueIdMapper) -> Iter<'a, SA, A> { Iter { index: 1, len: id_mapper.len(), @@ -149,9 +180,10 @@ where } } -impl<'a, SA> Iterator for Iter<'a, SA> +impl<'a, SA, A> Iterator for Iter<'a, SA, A> where SA: StorageMapperApi, + A: StorageAddress, { type Item = usize; @@ -168,7 +200,7 @@ where } /// Behaves like a MultiResultVec when an endpoint result. -impl TopEncodeMulti for UniqueIdMapper +impl TopEncodeMulti for UniqueIdMapper where SA: StorageMapperApi, { @@ -181,17 +213,28 @@ where } } -impl CodecFrom> for MultiValueEncoded where SA: StorageMapperApi {} +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 +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 6e52d62662..7b59a31897 100644 --- a/framework/base/src/storage/mappers/unordered_set_mapper.rs +++ b/framework/base/src/storage/mappers/unordered_set_mapper.rs @@ -1,33 +1,38 @@ use core::marker::PhantomData; pub use super::vec_mapper::Iter; -use super::{StorageClearable, StorageMapper, VecMapper}; +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + StorageClearable, StorageMapper, StorageMapperFromAddress, 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::{storage_get_from_address, StorageKey}, - storage_clear, storage_get, storage_set, + storage::StorageKey, + storage_clear, storage_set, types::{ManagedAddress, ManagedType, MultiValueEncoded}, }; const ITEM_INDEX: &[u8] = b".index"; const NULL_ENTRY: usize = 0; -pub struct UnorderedSetMapper +pub struct UnorderedSetMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, { _phantom_api: PhantomData, + address: A, base_key: StorageKey, - vec_mapper: VecMapper, + vec_mapper: VecMapper, } -impl StorageMapper for UnorderedSetMapper +impl StorageMapper for UnorderedSetMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode, @@ -35,13 +40,29 @@ where fn new(base_key: StorageKey) -> Self { UnorderedSetMapper { _phantom_api: PhantomData, + address: CurrentStorage, base_key: base_key.clone(), vec_mapper: VecMapper::::new(base_key), } } } -impl StorageClearable for UnorderedSetMapper +impl StorageMapperFromAddress for UnorderedSetMapper> +where + SA: StorageMapperApi, + T: TopEncode + TopDecode + NestedEncode + NestedDecode, +{ + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + UnorderedSetMapper { + _phantom_api: PhantomData, + address: address.clone(), + base_key: base_key.clone(), + vec_mapper: VecMapper::new_from_address(address, base_key), + } + } +} + +impl StorageClearable for UnorderedSetMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + NestedEncode + NestedDecode, @@ -54,9 +75,10 @@ where } } -impl UnorderedSetMapper +impl UnorderedSetMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode, { fn item_index_key(&self, value: &T) -> StorageKey { @@ -66,64 +88,52 @@ where item_key } - pub fn get_index(&self, value: &T) -> usize { - storage_get(self.item_index_key(value).as_ref()) - } - /// Gets the item's index at the given address' mapper. /// Returns `0` if the item is not in the list. - pub fn get_index_at_address(&self, address: &ManagedAddress, value: &T) -> usize { - storage_get_from_address(address.as_ref(), self.item_index_key(value).as_ref()) + pub fn get_index(&self, value: &T) -> usize { + self.address + .address_storage_get(self.item_index_key(value).as_ref()) } - /// Get item at index from storage. + /// Get item at index from the given address. /// Index must be valid (1 <= index <= count). pub fn get_by_index(&self, index: usize) -> T { self.vec_mapper.get(index) } - /// Gets the item by index from the given address. - /// Index must be valid (1 <= index <= count). - pub fn get_by_index_at_address(&self, address: &ManagedAddress, index: usize) -> T { - self.vec_mapper.get_at_address(address, index) - } - - fn set_index(&self, value: &T, index: usize) { - storage_set(self.item_index_key(value).as_ref(), &index); - } - - fn clear_index(&self, value: &T) { - storage_clear(self.item_index_key(value).as_ref()); - } - /// Returns `true` if the set contains no elements. pub fn is_empty(&self) -> bool { self.vec_mapper.is_empty() } - /// Returns `true` if the address' mapper contains no elements. - pub fn is_empty_at_address(&self, address: &ManagedAddress) -> bool { - self.vec_mapper.is_empty_at_address(address) - } - /// Returns the number of elements in the set. pub fn len(&self) -> usize { self.vec_mapper.len() } - /// Returns the number of elements contained in the given address' mapper. - pub fn len_at_address(&self, address: &ManagedAddress) -> usize { - self.vec_mapper.len_at_address(address) - } - /// Returns `true` if the set contains a value. pub fn contains(&self, value: &T) -> bool { self.get_index(value) != NULL_ENTRY } - /// Returns `true` if the mapper at the given address contains the value. - pub fn contains_at_address(&self, address: &ManagedAddress, value: &T) -> bool { - self.get_index_at_address(address, value) != NULL_ENTRY + /// An iterator visiting all elements in arbitrary order. + /// The iterator element type is `&'a T`. + pub fn iter(&self) -> Iter { + self.vec_mapper.iter() + } +} + +impl UnorderedSetMapper +where + SA: StorageMapperApi, + T: TopEncode + TopDecode + NestedEncode + NestedDecode, +{ + fn set_index(&self, value: &T, index: usize) { + storage_set(self.item_index_key(value).as_ref(), &index); + } + + fn clear_index(&self, value: &T) { + storage_clear(self.item_index_key(value).as_ref()); } /// Adds a value to the set. @@ -168,22 +178,17 @@ where self.set_index(&value2, index1); true } - - /// An iterator visiting all elements in arbitrary order. - /// The iterator element type is `&'a T`. - pub fn iter(&self) -> Iter { - self.vec_mapper.iter() - } } -impl<'a, SA, T> IntoIterator for &'a UnorderedSetMapper +impl<'a, SA, T, A> IntoIterator for &'a UnorderedSetMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + NestedEncode + NestedDecode + 'static, { type Item = T; - type IntoIter = Iter<'a, SA, T>; + type IntoIter = Iter<'a, SA, T, A>; fn into_iter(self) -> Self::IntoIter { self.iter() @@ -220,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, @@ -233,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 d088f94604..8ed0db5fec 100644 --- a/framework/base/src/storage/mappers/user_mapper.rs +++ b/framework/base/src/storage/mappers/user_mapper.rs @@ -1,15 +1,20 @@ 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::StorageMapper; +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + StorageMapper, StorageMapperFromAddress, +}; use crate::{ abi::{TypeAbi, TypeName}, api::StorageMapperApi, - storage::{storage_get, storage_get_len, storage_set, StorageKey}, + storage::{storage_set, StorageKey}, types::{ManagedAddress, ManagedType, ManagedVec, MultiValueEncoded}, }; @@ -26,11 +31,13 @@ const COUNT_SUFFIX: &[u8] = b"_count"; /// user data other than address/id. /// /// It also doesn't allow removing users. Once in, their ids are reserved forever. -pub struct UserMapper +pub struct UserMapper where SA: StorageMapperApi, + A: StorageAddress, { _phantom_api: PhantomData, + address: A, base_key: StorageKey, } @@ -41,14 +48,29 @@ where fn new(base_key: StorageKey) -> Self { UserMapper { _phantom_api: PhantomData, + address: CurrentStorage, + base_key, + } + } +} + +impl StorageMapperFromAddress for UserMapper> +where + SA: StorageMapperApi, +{ + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + UserMapper { + _phantom_api: PhantomData, + address, base_key, } } } -impl UserMapper +impl UserMapper where SA: StorageMapperApi, + A: StorageAddress, { fn get_user_id_key(&self, address: &ManagedAddress) -> StorageKey { let mut user_id_key = self.base_key.clone(); @@ -73,11 +95,8 @@ where /// Yields the user id for a given address. /// Will return 0 if the address is not known to the contract. pub fn get_user_id(&self, address: &ManagedAddress) -> usize { - storage_get(self.get_user_id_key(address).as_ref()) - } - - fn set_user_id(&self, address: &ManagedAddress, id: usize) { - storage_set(self.get_user_id_key(address).as_ref(), &id); + self.address + .address_storage_get(self.get_user_id_key(address).as_ref()) } /// Yields the user address for a given id, if the id is valid. @@ -85,8 +104,8 @@ where let key = self.get_user_address_key(id); // TODO: optimize, storage_load_managed_buffer_len is currently called twice - if storage_get_len(key.as_ref()) > 0 { - Some(storage_get(key.as_ref())) + if self.address.address_storage_get_len(key.as_ref()) > 0 { + Some(self.address.address_storage_get(key.as_ref())) } else { None } @@ -95,7 +114,8 @@ where /// Yields the user address for a given id. /// Will cause a deserialization error if the id is invalid. pub fn get_user_address_unchecked(&self, id: usize) -> ManagedAddress { - storage_get(self.get_user_address_key(id).as_ref()) + self.address + .address_storage_get(self.get_user_address_key(id).as_ref()) } /// Yields the user address for a given id, if the id is valid. @@ -103,38 +123,45 @@ where pub fn get_user_address_or_zero(&self, id: usize) -> ManagedAddress { let key = self.get_user_address_key(id); // TODO: optimize, storage_load_managed_buffer_len is currently called twice - if storage_get_len(key.as_ref()) > 0 { - storage_get(key.as_ref()) + if self.address.address_storage_get_len(key.as_ref()) > 0 { + self.address.address_storage_get(key.as_ref()) } else { ManagedAddress::zero() } } - fn set_user_address(&self, id: usize, address: &ManagedAddress) { - storage_set(self.get_user_address_key(id).as_ref(), address); - } - /// Number of users. pub fn get_user_count(&self) -> usize { - storage_get(self.get_user_count_key().as_ref()) + self.address + .address_storage_get(self.get_user_count_key().as_ref()) } - fn set_user_count(&self, user_count: usize) { - storage_set(self.get_user_count_key().as_ref(), &user_count); + /// Loads all addresses from storage and places them in a ManagedVec. + /// Can easily consume a lot of gas. + pub fn get_all_addresses(&self) -> ManagedVec> { + let user_count = self.get_user_count(); + let mut result = ManagedVec::new(); + for i in 1..=user_count { + result.push(self.get_user_address_or_zero(i)); + } + result } +} - /// Yields the user id for a given address, or creates a new user id if there isn't one. - /// Will safely keep the user count in sync. - pub fn get_or_create_user(&self, address: &ManagedAddress) -> usize { - let mut user_id = self.get_user_id(address); - if user_id == 0 { - let next_user_count = self.get_user_count() + 1; - self.set_user_count(next_user_count); - user_id = next_user_count; - self.set_user_id(address, user_id); - self.set_user_address(user_id, address); - } - user_id +impl UserMapper +where + SA: StorageMapperApi, +{ + fn set_user_id(&self, address: &ManagedAddress, id: usize) { + storage_set(self.get_user_id_key(address).as_ref(), &id); + } + + fn set_user_address(&self, id: usize, address: &ManagedAddress) { + storage_set(self.get_user_address_key(id).as_ref(), address); + } + + fn set_user_count(&self, user_count: usize) { + storage_set(self.get_user_count_key().as_ref(), &user_count); } /// Tries to insert a number of addresses. @@ -163,21 +190,24 @@ where self.set_user_count(user_count); } - /// Loads all addresses from storage and places them in a ManagedVec. - /// Can easily consume a lot of gas. - pub fn get_all_addresses(&self) -> ManagedVec> { - let user_count = self.get_user_count(); - let mut result = ManagedVec::new(); - for i in 1..=user_count { - result.push(self.get_user_address_or_zero(i)); + /// Yields the user id for a given address, or creates a new user id if there isn't one. + /// Will safely keep the user count in sync. + pub fn get_or_create_user(&self, address: &ManagedAddress) -> usize { + let mut user_id = self.get_user_id(address); + if user_id == 0 { + let next_user_count = self.get_user_count() + 1; + self.set_user_count(next_user_count); + user_id = next_user_count; + self.set_user_id(address, user_id); + self.set_user_address(user_id, address); } - result + user_id } } /// Behaves like a MultiResultVec
when an endpoint result, /// and lists all users addresses. -impl TopEncodeMulti for UserMapper +impl TopEncodeMulti for UserMapper where SA: StorageMapperApi, { @@ -191,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 +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 f0c761067f..22b8763ece 100644 --- a/framework/base/src/storage/mappers/vec_mapper.rs +++ b/framework/base/src/storage/mappers/vec_mapper.rs @@ -1,19 +1,18 @@ -use super::{StorageClearable, StorageMapper}; +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + StorageClearable, StorageMapper, StorageMapperFromAddress, +}; 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, - }, - storage::{ - storage_clear, storage_get, storage_get_from_address, storage_get_len, storage_set, - StorageKey, + multi_encode_iter_or_handle_err, EncodeErrorHandler, TopDecode, TopEncode, TopEncodeMulti, + TopEncodeMultiOutput, }, + storage::{storage_clear, storage_set, StorageKey}, types::{ManagedAddress, ManagedType, MultiValueEncoded}, }; -use core::{marker::PhantomData, usize}; -use storage_get_from_address::storage_get_len_from_address; +use core::marker::PhantomData; const ITEM_SUFFIX: &[u8] = b".item"; const LEN_SUFFIX: &[u8] = b".len"; @@ -26,18 +25,19 @@ static INDEX_OUT_OF_RANGE_ERR_MSG: &[u8] = b"index out of range"; /// Indexes start from 1, instead of 0. (We avoid 0-value indexes to prevent confusion between an uninitialized variable and zero.) /// It also stores the count separately, at what would be index 0. /// The count is always kept in sync automatically. -pub struct VecMapper +pub struct VecMapper where SA: StorageMapperApi, T: TopEncode + TopDecode + 'static, { _phantom_api: PhantomData, + address: A, base_key: StorageKey, len_key: StorageKey, _phantom_item: PhantomData, } -impl StorageMapper for VecMapper +impl StorageMapper for VecMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -48,6 +48,7 @@ where VecMapper { _phantom_api: PhantomData, + address: CurrentStorage, base_key, len_key, _phantom_item: PhantomData, @@ -55,7 +56,26 @@ where } } -impl StorageClearable for VecMapper +impl StorageMapperFromAddress for VecMapper> +where + SA: StorageMapperApi, + T: TopEncode + TopDecode, +{ + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + let mut len_key = base_key.clone(); + len_key.append_bytes(LEN_SUFFIX); + + VecMapper { + _phantom_api: PhantomData, + address, + base_key, + len_key, + _phantom_item: PhantomData, + } + } +} + +impl StorageClearable for VecMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -65,9 +85,10 @@ where } } -impl VecMapper +impl VecMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode, { fn item_key(&self, index: usize) -> StorageKey { @@ -77,18 +98,9 @@ where item_key } - fn save_count(&self, new_len: usize) { - storage_set(self.len_key.as_ref(), &new_len); - } - /// Number of items managed by the mapper. pub fn len(&self) -> usize { - storage_get(self.len_key.as_ref()) - } - - /// Number of items in the mapper at the given address. - pub fn len_at_address(&self, address: &ManagedAddress) -> usize { - storage_get_from_address(address.as_ref(), self.len_key.as_ref()) + self.address.address_storage_get(self.len_key.as_ref()) } /// True if no items present in the mapper. @@ -96,33 +108,6 @@ where self.len() == 0 } - pub fn is_empty_at_address(&self, address: &ManagedAddress) -> bool { - self.len_at_address(address) == 0 - } - - /// Add one item at the end of the list. - /// Returns the index of the newly inserted item, which is also equal to the new number of elements. - pub fn push(&mut self, item: &T) -> usize { - let mut len = self.len(); - len += 1; - storage_set(self.item_key(len).as_ref(), item); - self.save_count(len); - len - } - - /// Adds multiple items at the end of the list. - /// Cheaper than multiple `push`-es because the count only gets updated once at the end. - /// Returns the index of the last inserted item, which is also equal to the new number of elements. - pub fn extend_from_slice(&mut self, items: &[T]) -> usize { - let mut len = self.len(); - for item in items { - len += 1; - storage_set(self.item_key(len).as_ref(), item); - } - self.save_count(len); - len - } - /// Get item at index from storage. /// Index must be valid (1 <= index <= count). pub fn get(&self, index: usize) -> T { @@ -132,26 +117,12 @@ where self.get_unchecked(index) } - /// Get the item at index from the target's storage. - /// Index must be valid (1 <= index <= count). - pub fn get_at_address(&self, address: &ManagedAddress, index: usize) -> T { - if index == 0 || index > self.len_at_address(address) { - SA::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_ERR_MSG); - } - self.get_unchecked_at_address(address, index) - } - /// Get item at index from storage. /// There are no restrictions on the index, /// calling for an invalid index will simply return the zero-value. pub fn get_unchecked(&self, index: usize) -> T { - storage_get(self.item_key(index).as_ref()) - } - - /// Gets the item without checking index bounds. - /// Prefer using `get_at_address` instead. - pub fn get_unchecked_at_address(&self, address: &ManagedAddress, index: usize) -> T { - storage_get_from_address(address.as_ref(), self.item_key(index).as_ref()) + self.address + .address_storage_get(self.item_key(index).as_ref()) } /// Get item at index from storage. @@ -166,52 +137,88 @@ where } } + /// Checks whether or not there is anything ins storage at index. + /// Index must be valid (1 <= index <= count). + pub fn item_is_empty(&self, index: usize) -> bool { + if index == 0 || index > self.len() { + SA::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_ERR_MSG); + } + self.item_is_empty_unchecked(index) + } + /// Checks whether or not there is anything in storage at index. /// There are no restrictions on the index, /// calling for an invalid index will simply return `true`. pub fn item_is_empty_unchecked(&self, index: usize) -> bool { - storage_get_len(self.item_key(index).as_ref()) == 0 + self.address + .address_storage_get_len(self.item_key(index).as_ref()) + == 0 + } + + /// Loads all items from storage and places them in a Vec. + /// Can easily consume a lot of gas. + #[cfg(feature = "alloc")] + pub fn load_as_vec(&self) -> alloc::vec::Vec { + self.iter().collect() } - /// Checks if the mapper at the given address stores anything at this index. - /// Does not check index bounds. - /// Prefer using `item_is_empty` instead. - pub fn item_is_empty_unchecked_at_address( - &self, - address: &ManagedAddress, - index: usize, - ) -> bool { - let len = storage_get_len_from_address(address.as_ref(), self.item_key(index).as_ref()); - len == 0 + /// Provides a forward iterator. + pub fn iter(&self) -> Iter { + Iter::new(self) } +} - /// Checks whether or not there is anything ins storage at index. - /// Index must be valid (1 <= index <= count). - pub fn item_is_empty(&self, index: usize) -> bool { - if index == 0 || index > self.len() { - SA::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_ERR_MSG); - } - self.item_is_empty_unchecked(index) +impl VecMapper +where + SA: StorageMapperApi, + T: TopEncode + TopDecode, +{ + fn save_count(&self, new_len: usize) { + storage_set(self.len_key.as_ref(), &new_len); } - /// Checks if the mapper at the given address stores anything at this index. - /// Index must be valid (1 <= index <= count). - pub fn item_is_empty_at_address(&self, address: &ManagedAddress, index: usize) -> bool { - if index == 0 || index > self.len_at_address(address) { - SA::error_api_impl().signal_error(INDEX_OUT_OF_RANGE_ERR_MSG); + /// Add one item at the end of the list. + /// Returns the index of the newly inserted item, which is also equal to the new number of elements. + pub fn push(&mut self, item: &T) -> usize { + let mut len = self.len(); + len += 1; + storage_set(self.item_key(len).as_ref(), item); + self.save_count(len); + len + } + + /// Adds multiple items at the end of the list. + /// Cheaper than multiple `push`-es because the count only gets updated once at the end. + /// Returns the index of the last inserted item, which is also equal to the new number of elements. + pub fn extend_from_slice(&mut self, items: &[T]) -> usize { + let mut len = self.len(); + for item in items { + len += 1; + storage_set(self.item_key(len).as_ref(), item); } - self.item_is_empty_unchecked_at_address(address, index) + self.save_count(len); + len } /// 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"[..]); } self.set_unchecked(index, item); } + /// Syntactic sugar, to more compactly express a get, update and set in one line. + /// Takes whatever lies in storage, apples the given closure and saves the final value back to storage. + /// Propagates the return value of the given function. + pub fn update R>(&mut self, index: usize, f: F) -> R { + let mut value = self.get(index); + let result = f(&mut value); + self.set(index, &value); + result + } + /// Keeping `set_unchecked` private on purpose, so developers don't write out of index limits by accident. fn set_unchecked(&self, index: usize, item: &T) { storage_set(self.item_key(index).as_ref(), item); @@ -257,13 +264,6 @@ where last_item_as_option } - /// Loads all items from storage and places them in a Vec. - /// Can easily consume a lot of gas. - #[cfg(feature = "alloc")] - pub fn load_as_vec(&self) -> alloc::vec::Vec { - self.iter().collect() - } - /// Deletes all contents form storage and sets count to 0. /// Can easily consume a lot of gas. pub fn clear(&mut self) { @@ -273,21 +273,17 @@ where } self.save_count(0); } - - /// Provides a forward iterator. - pub fn iter(&self) -> Iter { - Iter::new(self) - } } -impl<'a, SA, T> IntoIterator for &'a VecMapper +impl<'a, SA, T, A> IntoIterator for &'a VecMapper where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { type Item = T; - type IntoIter = Iter<'a, SA, T>; + type IntoIter = Iter<'a, SA, T, A>; fn into_iter(self) -> Self::IntoIter { self.iter() @@ -298,22 +294,24 @@ where /// /// This `struct` is created by [`VecMapper::iter()`]. See its /// documentation for more. -pub struct Iter<'a, SA, T> +pub struct Iter<'a, SA, T, A> where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { index: usize, len: usize, - vec: &'a VecMapper, + vec: &'a VecMapper, } -impl<'a, SA, T> Iter<'a, SA, T> +impl<'a, SA, T, A> Iter<'a, SA, T, A> where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { - fn new(vec: &'a VecMapper) -> Iter<'a, SA, T> { + fn new(vec: &'a VecMapper) -> Iter<'a, SA, T, A> { Iter { index: 1, len: vec.len(), @@ -322,9 +320,10 @@ where } } -impl<'a, SA, T> Iterator for Iter<'a, SA, T> +impl<'a, SA, T, A> Iterator for Iter<'a, SA, T, A> where SA: StorageMapperApi, + A: StorageAddress, T: TopEncode + TopDecode + 'static, { type Item = T; @@ -341,7 +340,7 @@ where } /// Behaves like a MultiResultVec when an endpoint result. -impl TopEncodeMulti for VecMapper +impl TopEncodeMulti for VecMapper where SA: StorageMapperApi, T: TopEncode + TopDecode, @@ -355,7 +354,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, @@ -363,15 +369,21 @@ where } /// Behaves like a MultiResultVec when an endpoint result. -impl TypeAbi for VecMapper +impl TypeAbi for VecMapper 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/whitelist_mapper.rs b/framework/base/src/storage/mappers/whitelist_mapper.rs index 339929a468..62111d2020 100644 --- a/framework/base/src/storage/mappers/whitelist_mapper.rs +++ b/framework/base/src/storage/mappers/whitelist_mapper.rs @@ -1,6 +1,11 @@ use core::marker::PhantomData; -use super::{SingleValueMapper, StorageMapper}; +use multiversx_sc_codec::{TopDecode, TopEncode}; + +use super::{ + set_mapper::{CurrentStorage, StorageAddress}, + SingleValueMapper, StorageMapper, StorageMapperFromAddress, +}; use crate::{ api::{ErrorApiImpl, StorageMapperApi}, codec::NestedEncode, @@ -8,58 +13,84 @@ use crate::{ types::ManagedAddress, }; -type FlagMapper = SingleValueMapper; +type FlagMapper = SingleValueMapper; static ITEM_NOT_WHITELISTED_ERR_MSG: &[u8] = b"Item not whitelisted"; /// A non-iterable whitelist mapper. /// Very efficient for storing a whitelist, as each item requires only one storage key. /// If you need to iterate over the keys, use UnorderedSetMapper or SetMapper instead. -pub struct WhitelistMapper +pub struct WhitelistMapper where SA: StorageMapperApi, + A: StorageAddress, T: NestedEncode + 'static, { + address: A, base_key: StorageKey, _phantom: PhantomData, } -impl StorageMapper for WhitelistMapper +impl StorageMapper for WhitelistMapper where SA: StorageMapperApi, T: NestedEncode + 'static, { fn new(base_key: StorageKey) -> Self { Self { + address: CurrentStorage, base_key, _phantom: PhantomData, } } } -impl WhitelistMapper +impl StorageMapperFromAddress for WhitelistMapper> where SA: StorageMapperApi, T: NestedEncode + 'static, { - pub fn add(&self, item: &T) { - let mapper = self.build_mapper_for_item(item); - mapper.set(true); - } - - pub fn remove(&self, item: &T) { - let mapper = self.build_mapper_for_item(item); - mapper.clear(); + fn new_from_address(address: ManagedAddress, base_key: StorageKey) -> Self { + Self { + address, + base_key, + _phantom: PhantomData, + } } +} +impl WhitelistMapper> +where + SA: StorageMapperApi, + T: TopDecode + TopEncode + NestedEncode + 'static, +{ pub fn contains(&self, item: &T) -> bool { let mapper = self.build_mapper_for_item(item); !mapper.is_empty() } - pub fn contains_at_address(&self, address: &ManagedAddress, item: &T) -> bool { + pub fn require_whitelisted(&self, item: &T) { + if !self.contains(item) { + SA::error_api_impl().signal_error(ITEM_NOT_WHITELISTED_ERR_MSG); + } + } + + fn build_mapper_for_item(&self, item: &T) -> FlagMapper> { + let mut key = self.base_key.clone(); + key.append_item(item); + + FlagMapper::>::new_from_address(self.address.clone(), key) + } +} + +impl WhitelistMapper +where + SA: StorageMapperApi, + T: TopDecode + TopEncode + NestedEncode + 'static, +{ + pub fn contains(&self, item: &T) -> bool { let mapper = self.build_mapper_for_item(item); - !mapper.is_empty_at_address(address) + !mapper.is_empty() } pub fn require_whitelisted(&self, item: &T) { @@ -68,16 +99,20 @@ where } } - pub fn require_whitelisted_at_address(&self, address: &ManagedAddress, item: &T) { - if !self.contains_at_address(address, item) { - SA::error_api_impl().signal_error(ITEM_NOT_WHITELISTED_ERR_MSG); - } + pub fn add(&self, item: &T) { + let mapper = self.build_mapper_for_item(item); + mapper.set(true); + } + + pub fn remove(&self, item: &T) { + let mapper = self.build_mapper_for_item(item); + mapper.clear(); } - fn build_mapper_for_item(&self, item: &T) -> FlagMapper { + fn build_mapper_for_item(&self, item: &T) -> FlagMapper { let mut key = self.base_key.clone(); key.append_item(item); - FlagMapper::::new(key) + FlagMapper::::new(key) } } diff --git a/framework/base/src/storage/storage_get.rs b/framework/base/src/storage/storage_get.rs index c4504df70f..85107896dd 100644 --- a/framework/base/src/storage/storage_get.rs +++ b/framework/base/src/storage/storage_get.rs @@ -1,9 +1,9 @@ -use core::marker::PhantomData; +use core::{convert::Infallible, marker::PhantomData}; use crate::{ api::{ - const_handles, use_raw_handle, ErrorApi, ErrorApiImpl, ManagedBufferApiImpl, - ManagedTypeApi, StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, + const_handles, use_raw_handle, ErrorApi, ErrorApiImpl, HandleConstraints, + ManagedBufferApiImpl, ManagedTypeApi, StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, }, codec::*, err_msg, @@ -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,12 @@ where T: TopDecode, A: StorageReadApi + ManagedTypeApi + ErrorApi, { - let Ok(value) = T::top_decode_or_handle_err( + let handle = key.get_handle().get_raw_handle_unchecked(); + T::top_decode_or_handle_err( StorageGetInput::new(key), - StorageGetErrorHandler::::default(), - ); - value + StorageGetErrorHandler::::new(handle), + ) + .unwrap_infallible() } /// Useful for storage mappers. @@ -139,17 +162,20 @@ where M: ManagedTypeApi + ErrorApi, { _phantom: PhantomData, + key: i32, } impl Copy for StorageGetErrorHandler where M: ManagedTypeApi + ErrorApi {} -impl Default for StorageGetErrorHandler +impl StorageGetErrorHandler where M: ManagedTypeApi + ErrorApi, { - fn default() -> Self { - Self { + #[inline] + pub fn new(key: i32) -> Self { + StorageGetErrorHandler { _phantom: PhantomData, + key, } } } @@ -158,10 +184,13 @@ 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_1.as_bytes()); + M::managed_type_impl().mb_append(message_buffer.get_handle(), self.key.into()); + message_buffer.append_bytes(err_msg::STORAGE_DECODE_ERROR_2.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..2b40987bd3 100644 --- a/framework/base/src/storage/storage_get_from_address.rs +++ b/framework/base/src/storage/storage_get_from_address.rs @@ -1,7 +1,7 @@ use crate::{ api::{ - const_handles, use_raw_handle, ErrorApi, ManagedBufferApiImpl, ManagedTypeApi, - StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, + const_handles, use_raw_handle, ErrorApi, HandleConstraints, ManagedBufferApiImpl, + ManagedTypeApi, StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, }, codec::*, types::{ @@ -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,12 @@ where T: TopDecode, A: StorageReadApi + ManagedTypeApi + ErrorApi, { - let Ok(value) = T::top_decode_or_handle_err( + let handle = key.get_handle().get_raw_handle_unchecked(); + T::top_decode_or_handle_err( StorageGetFromAddressInput::new(addr, key), - StorageGetErrorHandler::::default(), - ); - value + StorageGetErrorHandler::::new(handle), + ) + .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.rs b/framework/base/src/types.rs index caa4a5a2d3..23d94214ba 100644 --- a/framework/base/src/types.rs +++ b/framework/base/src/types.rs @@ -4,6 +4,7 @@ pub mod heap; mod interaction; mod io; mod managed; +pub(crate) mod math_util; mod static_buffer; pub use crypto::*; 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 d18895d11a..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}, }; @@ -14,7 +14,7 @@ const PAYABLE_BY_SC_STRING: &[u8] = b"PayableBySC"; const DEFAULT_STRING: &[u8] = b"Default"; bitflags! { - #[derive(Default)] + #[derive(Default, PartialEq, Debug, Clone, Copy)] pub struct CodeMetadata: u16 { const DEFAULT = 0; const UPGRADEABLE = 0b0000_0001_0000_0000; // LSB of first byte @@ -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_local_role_flags.rs b/framework/base/src/types/flags/esdt_local_role_flags.rs index 7be536e349..29be64aba2 100644 --- a/framework/base/src/types/flags/esdt_local_role_flags.rs +++ b/framework/base/src/types/flags/esdt_local_role_flags.rs @@ -4,6 +4,7 @@ use super::EsdtLocalRole; use bitflags::bitflags; bitflags! { + #[derive(PartialEq, Clone, Copy)] pub struct EsdtLocalRoleFlags: u64 { const NONE = 0b00000000; const MINT = 0b00000001; 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 f374d1801b..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,19 +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) } +} - #[cfg(feature = "promises")] - 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, @@ -216,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 cc84493962..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,14 +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] - #[cfg(feature = "promises")] - 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. @@ -98,10 +107,9 @@ where /// Executes immediately, synchronously, and returns contract call result. /// Only works if the target contract is in the same shard. #[inline] - #[cfg(feature = "back-transfers")] 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..01d1dc819d --- /dev/null +++ b/framework/base/src/types/interaction/expr/test_address.rs @@ -0,0 +1,153 @@ +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, + }, +}; + +use super::TestSCAddress; + +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 + } + + pub fn to_address(&self) -> Address { + self.eval_to_array().into() + } + + pub fn to_managed_address(&self) -> ManagedAddress { + self.eval_to_array().into() + } + + #[cfg(feature = "alloc")] + pub fn eval_to_expr(&self) -> alloc::string::String { + alloc::format!("{ADDRESS_PREFIX}{}", self.name) + } +} + +impl<'a, 'b> PartialEq> for TestAddress<'a> { + fn eq(&self, other: &TestSCAddress) -> bool { + self.to_address() == other.to_address() + } +} + +impl<'a> PartialEq
for TestAddress<'a> { + fn eq(&self, other: &Address) -> bool { + &self.to_address() == other + } +} + +impl<'a> PartialEq> for Address { + fn eq(&self, other: &TestAddress<'a>) -> bool { + self == &other.to_address() + } +} + +impl<'a, Api: ManagedTypeApi> PartialEq> for TestAddress<'a> { + fn eq(&self, other: &ManagedAddress) -> bool { + self.to_address() == other.to_address() + } +} + +impl<'a, Api: ManagedTypeApi> PartialEq> for ManagedAddress { + fn eq(&self, other: &TestAddress<'a>) -> bool { + self.to_address() == other.to_address() + } +} + +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..564157fb94 --- /dev/null +++ b/framework/base/src/types/interaction/expr/test_sc_address.rs @@ -0,0 +1,168 @@ +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, + }, +}; + +use super::TestAddress; + +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 { + self.eval_to_array().into() + } + + pub fn to_managed_address(&self) -> ManagedAddress { + self.eval_to_array().into() + } +} + +impl<'a, 'b> PartialEq> for TestSCAddress<'a> { + fn eq(&self, other: &TestAddress) -> bool { + self.to_address() == other.to_address() + } +} + +impl<'a> PartialEq
for TestSCAddress<'a> { + fn eq(&self, other: &Address) -> bool { + &self.to_address() == other + } +} + +impl<'a> PartialEq> for Address { + fn eq(&self, other: &TestSCAddress<'a>) -> bool { + self == &other.to_address() + } +} + +impl<'a, Api: ManagedTypeApi> PartialEq> for TestSCAddress<'a> { + fn eq(&self, other: &ManagedAddress) -> bool { + self.to_address() == other.to_address() + } +} + +impl<'a, Api: ManagedTypeApi> PartialEq> for ManagedAddress { + fn eq(&self, other: &TestSCAddress<'a>) -> bool { + self.to_address() == other.to_address() + } +} + +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..68865d8fbc --- /dev/null +++ b/framework/base/src/types/interaction/expr/test_token_identifier.rs @@ -0,0 +1,78 @@ +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) + } + + pub fn to_token_identifier(&self) -> TokenIdentifier { + self.name.into() + } + + pub fn as_str(&self) -> &str { + self.name + } + + pub fn as_bytes(&self) -> &[u8] { + self.name.as_bytes() + } +} + +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..e422553ca4 --- /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::ManagedTypeApi, + types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, 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> for ESDTSystemSCAddress +where + Env: TxEnv, +{ + fn annotation(&self, _env: &Env) -> ManagedBuffer { + ManagedBuffer::from(SYSTEM_SC_ADDRESS_ANNOTATION) + } + + fn to_value(&self, _env: &Env) -> ManagedAddress { + ESDTSystemSCAddress.to_managed_address() + } +} + +impl TxTo for ESDTSystemSCAddress where Env: TxEnv {} +impl TxToSpecified for ESDTSystemSCAddress where Env: TxEnv {} + +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..6e4978980a --- /dev/null +++ b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs @@ -0,0 +1,217 @@ +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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token: &Arg0, + nonce: u64, + amount: &Arg1, + ) -> 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token: &Arg0, + nonce: u64, + amount: &Arg1, + ) -> 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: &Arg0, + 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: &Arg0, + 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< + T: TopEncode, + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + Arg3: ProxyArg>, + Arg4: ProxyArg>, + >( + self, + token: &Arg0, + amount: &Arg1, + name: &Arg2, + royalties: &Arg3, + hash: &Arg4, + 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..10730ff0fc --- /dev/null +++ b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs @@ -0,0 +1,650 @@ +use super::token_properties::*; + +use crate::{ + api::CallTypeApi, + types::{ + BigUint, EgldPayment, EsdtLocalRole, EsdtTokenType, FunctionCall, ManagedAddress, + ManagedBuffer, NotPayable, OriginalResultMarker, ProxyArg, 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + issue_cost: BigUint, + token_display_name: &Arg0, + token_ticker: &Arg1, + initial_supply: &Arg2, + 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + issue_cost: BigUint, + token_display_name: &Arg0, + token_ticker: &Arg1, + properties: NonFungibleTokenProperties, + ) -> IssueCall { + let zero = &BigUint::zero(); + 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + issue_cost: BigUint, + token_display_name: &Arg0, + token_ticker: &Arg1, + 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + issue_cost: BigUint, + token_display_name: &Arg0, + token_ticker: &Arg1, + 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + issue_cost: BigUint, + token_display_name: Arg0, + token_ticker: Arg1, + 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + Arg2: ProxyArg>, + >( + self, + issue_cost: BigUint, + token_type: EsdtTokenType, + token_display_name: &Arg0, + token_ticker: &Arg1, + initial_supply: &Arg2, + 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>, Arg1: ProxyArg>>( + self, + token_identifier: &Arg0, + amount: &Arg1, + ) -> 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>, Arg1: ProxyArg>>( + self, + token_identifier: &Arg0, + amount: &Arg1, + ) -> 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: &Arg0, + ) -> 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: &Arg0, + ) -> 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: &Arg0, + address: &Arg1, + ) -> 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: &Arg0, + address: &Arg1, + ) -> 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: &Arg0, + address: &Arg1, + ) -> 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: &Arg0, + nft_nonce: u64, + address: &Arg1, + ) -> 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: &Arg0, + nft_nonce: u64, + address: &Arg1, + ) -> 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: &Arg0, + nft_nonce: u64, + address: &Arg1, + ) -> 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: &Arg0, + 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< + RoleIter: Iterator, + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + address: &Arg0, + token_identifier: &Arg1, + 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< + RoleIter: Iterator, + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + address: &Arg0, + token_identifier: &Arg1, + 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< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: &Arg0, + new_owner: &Arg1, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("transferOwnership") + .argument(token_identifier) + .argument(new_owner) + .original_result() + } + + pub fn transfer_nft_create_role< + Arg0: ProxyArg>, + Arg1: ProxyArg>, + >( + self, + token_identifier: &Arg0, + old_creator: &Arg1, + new_creator: &Arg1, + ) -> 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: &Arg0, + 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..5059a424aa --- /dev/null +++ b/framework/base/src/types/interaction/tx_exec/tx_exec_sync.rs @@ -0,0 +1,166 @@ +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, TxNoPayment, 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, Payment, Gas, FC, RH> +where + Api: CallTypeApi, + To: TxToSpecified>, + Payment: TxNoPayment>, + 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..bed41cc775 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment.rs @@ -0,0 +1,134 @@ +mod test_esdt_transfer; +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 test_esdt_transfer::TestEsdtTransfer; +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/test_esdt_transfer.rs b/framework/base/src/types/interaction/tx_payment/test_esdt_transfer.rs new file mode 100644 index 0000000000..99d00a219e --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/test_esdt_transfer.rs @@ -0,0 +1,69 @@ +use crate::{ + api::ManagedTypeApi, + types::{ + BigUint, EsdtTokenPayment, FullPaymentData, FunctionCall, ManagedAddress, + TestTokenIdentifier, TxEnv, TxFrom, TxPayment, TxToSpecified, + }, +}; + +/// Syntactic sugar for quickly writing ESDT transfers in tests. +/// +/// The fields are: +/// 1. token identifier, as TestTokenIdentifier +/// 2. nonce +/// 3. amount +/// +/// The amount is represented as u64, since for most tests it is enough. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct TestEsdtTransfer<'a>(pub TestTokenIdentifier<'a>, pub u64, pub u64); + +impl<'a, Api> From> for EsdtTokenPayment +where + Api: ManagedTypeApi, +{ + fn from(value: TestEsdtTransfer<'a>) -> Self { + EsdtTokenPayment::new(value.0.to_token_identifier(), value.1, value.2.into()) + } +} + +impl<'a, Env> TxPayment for TestEsdtTransfer<'a> +where + Env: TxEnv, +{ + #[inline] + fn is_no_payment(&self, _env: &Env) -> bool { + self.2 == 0 + } + + #[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) + } + + 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_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 c602723127..de000fa1e1 100644 --- a/framework/base/src/types/io/sc_result.rs +++ b/framework/base/src/types/io/sc_result.rs @@ -1,17 +1,22 @@ -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}; /// Default way to optionally return an error from a smart contract endpoint. +#[deprecated( + since = "0.48.0", + note = "Use in-place error handling instead, such as `require!` or `sc_panic!`" +)] #[must_use] #[derive(Debug, PartialEq, Eq, Clone)] pub enum SCResult { @@ -72,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, @@ -123,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 83ef5613e3..54850a1672 100644 --- a/framework/base/src/types/managed/basic/big_float.rs +++ b/framework/base/src/types/managed/basic/big_float.rs @@ -1,19 +1,23 @@ use super::ManagedBuffer; use crate::{ + abi::{TypeAbi, TypeAbiFrom}, api::{ use_raw_handle, BigFloatApiImpl, ManagedTypeApi, ManagedTypeApiImpl, Sign, StaticVarApiImpl, }, - types::{BigInt, BigUint, ManagedType}, + contract_base::ErrorHelper, + types::{BigInt, BigUint, Decimals, ManagedDecimalSigned, ManagedType}, }; 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, }; +/// Denomiator used for initializing BigFloats from constants. +const DENOMINATOR: i64 = 1_000_000_000; + #[derive(Debug)] #[repr(transparent)] pub struct BigFloat { @@ -92,10 +96,7 @@ 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 { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); @@ -103,15 +104,20 @@ impl BigFloat { BigFloat::from_handle(new_bf_handle) } - #[inline] + pub fn abs(&self) -> Self { + let new_bf_handle: M::BigFloatHandle = + use_raw_handle(M::static_var_api_impl().next_handle()); + M::managed_type_impl().bf_abs(new_bf_handle.clone(), self.handle.clone()); + BigFloat::from_handle(new_bf_handle) + } + pub fn from_big_uint(big_uint: &BigUint) -> Self { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bf_set_bi(new_bf_handle.clone(), big_uint.handle.clone()); + M::managed_type_impl().bf_set_bi(new_bf_handle.clone(), big_uint.value.handle.clone()); BigFloat::from_handle(new_bf_handle) } - #[inline] pub fn from_big_int(big_int: &BigInt) -> Self { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); @@ -169,9 +175,79 @@ impl BigFloat { pub fn to_fixed_point(&self, denominator: &BigFloat) -> BigInt { (self * denominator).trunc() } -} -impl BigFloat { + pub fn to_managed_decimal_signed( + &self, + decimals: T, + ) -> ManagedDecimalSigned { + ManagedDecimalSigned::::from_big_float(self, decimals) + } + + /// Computes the natural logarithm of the current number. + /// + /// The error is around +/- 0.00006, for all inputs. + /// + /// Will return `None` for zero or negative numbers. + pub fn ln(&self) -> Option { + if self <= &0i64 { + return None; + } + + let one = BigFloat::from(1i64); + match self.cmp(&one) { + core::cmp::Ordering::Less => { + let inv = &one / self; + debug_assert!(inv > one); + Some(inv.ln_gt_one().neg()) + }, + core::cmp::Ordering::Equal => Some(BigFloat::from(0i64)), + core::cmp::Ordering::Greater => Some(self.ln_gt_one()), + } + } + + /// Computes the natural logarithm for values between 1 and 2. Performs very poorly outside of this interval. + fn ln_between_one_and_two(&self) -> Self { + let mut result = BigFloat::from_frac(-56570851, DENOMINATOR); // -0.056570851 + result *= self; + result += BigFloat::from_frac(447179550, DENOMINATOR); // 0.44717955 + result *= self; + result += BigFloat::from_frac(-1469956800, DENOMINATOR); // -1.4699568 + result *= self; + result += BigFloat::from_frac(2821202600, DENOMINATOR); // 2.8212026 + result *= self; + result += BigFloat::from_frac(-1741793900, DENOMINATOR); // -1.7417939 + + result + } + + /// Computes the natural logarithm for values > 1. + fn ln_gt_one(&self) -> Self { + // find the highest power of 2 less than or equal to self + let trunc_val = self.trunc(); + let trunc_val_unsigned = trunc_val + .into_big_uint() + .unwrap_or_sc_panic("log argument must be positive"); + + // start with aproximation, based on position of the most significant bit + let Some(log2_floor) = trunc_val_unsigned.log2_floor() else { + // means the input was zero, practically unreachable + return BigFloat::from(0i64); + }; + + let divisor = BigFloat::from(1 << log2_floor); + let x = self / &divisor; // normalize to [1.0, 2.0] + + debug_assert!(x >= 1); + debug_assert!(x <= 2); + + let mut result = x.ln_between_one_and_two(); + + let ln_of_2 = BigFloat::from_frac(693147180, DENOMINATOR); // 0.69314718 + result += BigFloat::from(log2_floor as i32) * ln_of_2; + + result + } + #[inline] pub fn zero() -> Self { BigFloat::from_handle(M::managed_type_impl().bf_new_zero()) @@ -231,6 +307,34 @@ impl BigFloat { } } +impl From for BigFloat { + fn from(x: f64) -> Self { + const PREC: i64 = 1_000_000_000; + Self::from_frac((x * PREC as f64) as i64, PREC) + } +} + +impl From for BigFloat { + fn from(x: f32) -> Self { + Self::from(x as f64) + } +} + +impl BigFloat { + /// Warning: cannot be used in contracts. It is only meant to simplify certain tests. + /// + /// It might also not be optimal with respect to precision. + pub fn to_f64(&self) -> f64 { + const PREC: i64 = 1_000_000_000; + let mut rescaled = Self::from(PREC); + rescaled *= self; + let ln_units = rescaled.trunc().to_i64().unwrap_or_else(|| { + ErrorHelper::::signal_error_with_message("BigFloat out of precision range") + }); + ln_units as f64 / PREC as f64 + } +} + impl Clone for BigFloat { fn clone(&self) -> Self { let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); @@ -285,7 +389,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_float_cmp.rs b/framework/base/src/types/managed/basic/big_float_cmp.rs index d3958667e6..2b342bdb76 100644 --- a/framework/base/src/types/managed/basic/big_float_cmp.rs +++ b/framework/base/src/types/managed/basic/big_float_cmp.rs @@ -4,6 +4,13 @@ use crate::api::{use_raw_handle, BigFloatApiImpl, ManagedTypeApi, StaticVarApiIm use super::{BigFloat, BigInt}; +impl BigFloat { + pub fn is_close(&self, other: &Self, abs_tolerance: &Self) -> bool { + // TODO: temp handles + &(self - other).abs() <= abs_tolerance + } +} + impl PartialEq for BigFloat { #[inline] fn eq(&self, other: &Self) -> bool { diff --git a/framework/base/src/types/managed/basic/big_int.rs b/framework/base/src/types/managed/basic/big_int.rs index 227a298d02..c705511f56 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 { @@ -200,9 +217,9 @@ impl BigInt { pub fn from_biguint(sign: Sign, unsigned: BigUint) -> Self { let api = M::managed_type_impl(); if sign.is_minus() { - api.bi_neg(unsigned.handle.clone(), unsigned.handle.clone()); + api.bi_neg(unsigned.value.handle.clone(), unsigned.value.handle.clone()); } - BigInt::from_handle(unsigned.handle) + BigInt::from_handle(unsigned.value.handle) } /// Returns the sign of the `BigInt` as a `Sign`. @@ -229,12 +246,21 @@ impl BigInt { (self.sign(), self.magnitude()) } + /// Converts to an unsigned `BigUint`, without performing any checks. + /// + /// # Safety + /// + /// If the number is negative, undefined behavior might occur further down the execution. + pub unsafe fn into_big_uint_unchecked(self) -> BigUint { + BigUint::from_handle(self.handle) + } + /// Converts this `BigInt` into a `BigUint`, if it's not negative. pub fn into_big_uint(self) -> ManagedOption> { if let Sign::Minus = self.sign() { ManagedOption::none() } else { - ManagedOption::some(BigUint::from_handle(self.handle)) + ManagedOption::some(unsafe { self.into_big_uint_unchecked() }) } } } @@ -298,12 +324,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_cmp.rs b/framework/base/src/types/managed/basic/big_int_cmp.rs index 094bc4bc26..3cad2af277 100644 --- a/framework/base/src/types/managed/basic/big_int_cmp.rs +++ b/framework/base/src/types/managed/basic/big_int_cmp.rs @@ -29,16 +29,25 @@ impl Ord for BigInt { } } -impl PartialEq for BigInt { - #[inline] - fn eq(&self, other: &i64) -> bool { - cmp_i64(self, *other).is_eq() - } +macro_rules! partial_eq_and_ord { + ($small_int_type:ident) => { + impl PartialEq<$small_int_type> for BigInt { + #[inline] + fn eq(&self, other: &$small_int_type) -> bool { + cmp_i64(self, *other as i64).is_eq() + } + } + + impl PartialOrd<$small_int_type> for BigInt { + #[inline] + fn partial_cmp(&self, other: &$small_int_type) -> Option { + Some(cmp_i64(self, *other as i64)) + } + } + }; } -impl PartialOrd for BigInt { - #[inline] - fn partial_cmp(&self, other: &i64) -> Option { - Some(cmp_i64(self, *other)) - } -} +partial_eq_and_ord! {i32} +partial_eq_and_ord! {i64} +partial_eq_and_ord! {u32} +partial_eq_and_ord! {u64} 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_num_cmp.rs b/framework/base/src/types/managed/basic/big_num_cmp.rs index 346b6cca6d..7793ea3e00 100644 --- a/framework/base/src/types/managed/basic/big_num_cmp.rs +++ b/framework/base/src/types/managed/basic/big_num_cmp.rs @@ -1,11 +1,11 @@ -use core::{cmp::Ordering, convert::TryInto}; +use core::cmp::Ordering; use crate::{ api::{const_handles, BigIntApiImpl, ManagedTypeApi}, types::ManagedType, }; -use super::{cast_to_i64::cast_to_i64, BigInt}; +use super::BigInt; pub(crate) fn cmp_i64(bi: &B, other: i64) -> Ordering where @@ -24,12 +24,3 @@ where api.bi_cmp(bi.get_handle(), big_int_temp_1) } } - -pub(crate) fn cmp_conv_i64(bi: &B, other: T) -> Ordering -where - M: ManagedTypeApi, - B: ManagedType, - T: TryInto, -{ - cmp_i64(bi, cast_to_i64::(other)) -} 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 7c40ff1256..b05c7e3a5c 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}, }; @@ -118,10 +118,10 @@ impl EllipticCurve { x_result_handle.clone(), y_result_handle.clone(), self.handle.clone(), - x_first_point.handle, - y_first_point.handle, - x_second_point.handle, - y_second_point.handle, + x_first_point.value.handle, + y_first_point.value.handle, + x_second_point.value.handle, + y_second_point.value.handle, ); ( BigUint::from_handle(x_result_handle), @@ -137,8 +137,8 @@ impl EllipticCurve { x_result_handle.clone(), y_result_handle.clone(), self.handle.clone(), - x_point.handle, - y_point.handle, + x_point.value.handle, + y_point.value.handle, ); ( BigUint::from_handle(x_result_handle), @@ -148,7 +148,11 @@ impl EllipticCurve { pub fn is_on_curve(&self, x_point: BigUint, y_point: BigUint) -> bool { let api = M::managed_type_impl(); - api.ec_is_on_curve(self.handle.clone(), x_point.handle, y_point.handle) + api.ec_is_on_curve( + self.handle.clone(), + x_point.value.handle, + y_point.value.handle, + ) } #[deprecated(since = "0.44.0", note = "Please use method `scalar_mult` instead.")] @@ -165,8 +169,8 @@ impl EllipticCurve { x_result_handle.clone(), y_result_handle.clone(), self.handle.clone(), - x_point.handle, - y_point.handle, + x_point.value.handle, + y_point.value.handle, data, ); ( @@ -188,8 +192,8 @@ impl EllipticCurve { x_result_handle.clone(), y_result_handle.clone(), self.handle.clone(), - x_point.handle, - y_point.handle, + x_point.value.handle, + y_point.value.handle, data.get_handle(), ); ( @@ -242,7 +246,11 @@ impl EllipticCurve { y_pair: BigUint, ) -> crate::types::heap::BoxedBytes { let api = M::managed_type_impl(); - api.ec_marshal_legacy(self.handle.clone(), x_pair.handle, y_pair.handle) + api.ec_marshal_legacy( + self.handle.clone(), + x_pair.value.handle, + y_pair.value.handle, + ) } pub fn marshal(&self, x_pair: BigUint, y_pair: BigUint) -> ManagedBuffer { @@ -250,8 +258,8 @@ impl EllipticCurve { use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().ec_marshal( self.handle.clone(), - x_pair.handle, - y_pair.handle, + x_pair.value.handle, + y_pair.value.handle, result_handle.clone(), ); ManagedBuffer::from_handle(result_handle) @@ -268,7 +276,11 @@ impl EllipticCurve { y_pair: BigUint, ) -> crate::types::heap::BoxedBytes { let api = M::managed_type_impl(); - api.ec_marshal_compressed_legacy(self.handle.clone(), x_pair.handle, y_pair.handle) + api.ec_marshal_compressed_legacy( + self.handle.clone(), + x_pair.value.handle, + y_pair.value.handle, + ) } pub fn marshal_compressed(&self, x_pair: BigUint, y_pair: BigUint) -> ManagedBuffer { @@ -276,8 +288,8 @@ impl EllipticCurve { use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().ec_marshal_compressed( self.handle.clone(), - x_pair.handle, - y_pair.handle, + x_pair.value.handle, + y_pair.value.handle, result_handle.clone(), ); ManagedBuffer::from_handle(result_handle) @@ -418,8 +430,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..de2dc63bb8 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 { @@ -478,7 +514,6 @@ impl core::fmt::Debug for ManagedBuffer { } } -#[cfg(feature = "alloc")] impl core::fmt::Display for ManagedBuffer { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { use crate::contract_base::ErrorHelper; diff --git a/framework/base/src/types/managed/basic/mod.rs b/framework/base/src/types/managed/basic/mod.rs index 71b45b0478..ef10f15b5e 100644 --- a/framework/base/src/types/managed/basic/mod.rs +++ b/framework/base/src/types/managed/basic/mod.rs @@ -6,21 +6,14 @@ mod big_int_cmp; mod big_int_operators; mod big_int_sign; mod big_num_cmp; -mod big_uint; -mod big_uint_cmp; -mod big_uint_operators; -mod cast_to_i64; +pub(crate) mod cast_to_i64; mod elliptic_curve; mod managed_buffer; +mod managed_map; pub use big_float::BigFloat; pub use big_int::BigInt; pub use big_int_sign::Sign; -pub use big_uint::BigUint; pub use elliptic_curve::{EllipticCurve, EllipticCurveComponents}; pub use managed_buffer::ManagedBuffer; - -#[cfg(feature = "managed-map")] -mod managed_map; -#[cfg(feature = "managed-map")] pub use managed_map::ManagedMap; diff --git a/framework/base/src/types/managed/codec_util/managed_buffer_nested_de_input.rs b/framework/base/src/types/managed/codec_util/managed_buffer_nested_de_input.rs index 982100dcc8..7752e6f5f0 100644 --- a/framework/base/src/types/managed/codec_util/managed_buffer_nested_de_input.rs +++ b/framework/base/src/types/managed/codec_util/managed_buffer_nested_de_input.rs @@ -9,7 +9,7 @@ use crate::{ api::ManagedTypeApi, types::{ managed::{preloaded_managed_buffer::PreloadedManagedBuffer, ManagedBufferSizeContext}, - BigInt, BigUint, ManagedBuffer, + BigInt, BigUint, ManagedBuffer, ManagedBufferReadToEnd, }, }; @@ -77,6 +77,18 @@ where &self.read_managed_buffer(h)?, )) } + + fn read_managed_buffer_to_end( + &mut self, + h: H, + ) -> Result, H::HandledErr> + where + H: DecodeErrorHandler, + { + Ok(ManagedBufferReadToEnd::from( + self.read_managed_buffer_of_size(self.remaining_len(), h)?, + )) + } } impl NestedDecodeInput for ManagedBufferNestedDecodeInput @@ -106,7 +118,10 @@ where } fn supports_specialized_type() -> bool { - T::type_eq::>() || T::type_eq::>() || T::type_eq::>() + T::type_eq::>() + || T::type_eq::>() + || T::type_eq::>() + || T::type_eq::>() } fn read_specialized(&mut self, context: C, h: H) -> Result @@ -123,6 +138,8 @@ where } }) { result + } else if let Some(result) = try_execute_then_cast(|| self.read_managed_buffer_to_end(h)) { + result } else if let Some(result) = try_execute_then_cast(|| self.read_big_uint(h)) { result } else if let Some(result) = try_execute_then_cast(|| self.read_big_int(h)) { diff --git a/framework/base/src/types/managed/codec_util/managed_buffer_nested_en_output.rs b/framework/base/src/types/managed/codec_util/managed_buffer_nested_en_output.rs index 3bf8345f2d..57e2349a78 100644 --- a/framework/base/src/types/managed/codec_util/managed_buffer_nested_en_output.rs +++ b/framework/base/src/types/managed/codec_util/managed_buffer_nested_en_output.rs @@ -1,9 +1,6 @@ use crate::codec::{EncodeError, EncodeErrorHandler, NestedEncodeOutput, TryStaticCast}; -use crate::{ - api::ManagedTypeApi, - types::{BigInt, BigUint, ManagedBuffer}, -}; +use crate::{api::ManagedTypeApi, types::ManagedBuffer}; impl NestedEncodeOutput for ManagedBuffer { fn write(&mut self, bytes: &[u8]) { @@ -12,7 +9,7 @@ impl NestedEncodeOutput for ManagedBuffer { #[inline] fn supports_specialized_type() -> bool { - T::type_eq::>() || T::type_eq::>() || T::type_eq::>() + T::type_eq::>() } #[inline] 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..04dbde9357 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,11 @@ +use unwrap_infallible::UnwrapInfallible; + +use crate::codec::multi_types::MultiValueVec; 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 +71,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 +226,35 @@ 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, { + type Unmanaged = MultiValueVec; + 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 +264,19 @@ where } } -impl CodecFromSelf for MultiValueEncoded where M: ManagedTypeApi {} - -#[cfg(feature = "alloc")] -use crate::codec::{multi_types::MultiValueVec, CodecFrom}; - -#[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..a168711af1 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,7 @@ +use multiversx_sc_codec::multi_types::MultiValueVec; + use crate::{ - abi::{TypeAbi, TypeDescriptionContainer, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeDescriptionContainer, TypeName}, api::ManagedTypeApi, codec::{ DecodeErrorHandler, EncodeErrorHandler, TopDecodeMulti, TopDecodeMultiInput, @@ -210,16 +212,26 @@ where } } +impl TypeAbiFrom for MultiValueManagedVec +where + M: ManagedTypeApi, + T: ManagedVecItem, +{ +} + impl TypeAbi for MultiValueManagedVec where M: ManagedTypeApi, T: ManagedVecItem, { + type Unmanaged = MultiValueVec; + 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/basic/big_uint.rs b/framework/base/src/types/managed/wrapped/big_uint.rs similarity index 64% rename from framework/base/src/types/managed/basic/big_uint.rs rename to framework/base/src/types/managed/wrapped/big_uint.rs index b139f823dc..615d790480 100644 --- a/framework/base/src/types/managed/basic/big_uint.rs +++ b/framework/base/src/types/managed/wrapped/big_uint.rs @@ -1,36 +1,39 @@ 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, + }, + contract_base::ErrorHelper, + formatter::{hex_util::encode_bytes_as_hex, FormatBuffer, FormatByteReceiver, SCDisplay}, + types::{ + heap::BoxedBytes, BigInt, ConstDecimals, Decimals, ManagedBuffer, + ManagedBufferCachedBuilder, ManagedDecimal, ManagedRef, ManagedType, }, - formatter::{hex_util::encode_bytes_as_hex, FormatByteReceiver, SCDisplay}, - types::{heap::BoxedBytes, ManagedBuffer, ManagedType}, }; -use super::cast_to_i64::cast_to_i64; - #[repr(transparent)] pub struct BigUint { - pub(crate) handle: M::BigIntHandle, + pub(crate) value: BigInt, } impl ManagedType for BigUint { type OwnHandle = M::BigIntHandle; fn from_handle(handle: M::BigIntHandle) -> Self { - BigUint { handle } + BigUint { + value: BigInt::from_handle(handle), + } } fn get_handle(&self) -> M::BigIntHandle { - self.handle.clone() + self.value.handle.clone() } fn transmute_from_handle_ref(handle_ref: &M::BigIntHandle) -> &Self { @@ -63,7 +66,7 @@ impl BigUint { where T: TryInto + num_traits::Unsigned, { - M::managed_type_impl().bi_set_int64(handle, cast_to_i64::(value)); + BigInt::::set_value(handle, value); } pub(crate) fn new_from_num(value: T) -> Self @@ -83,6 +86,14 @@ impl BigUint { Self::set_value(temp.clone(), value); temp } + + pub fn as_big_int(&self) -> &BigInt { + &self.value + } + + pub fn into_big_int(self) -> BigInt { + self.value + } } macro_rules! big_uint_conv_num { @@ -94,7 +105,7 @@ macro_rules! big_uint_conv_num { } } - impl CodecFrom<$num_ty> for BigUint {} + impl TypeAbiFrom<$num_ty> for BigUint {} }; } @@ -104,12 +115,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,15 +174,21 @@ 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(); - api.bi_to_i64(self.handle.clone()).map(|bi| bi as u64) + api.bi_to_i64(self.value.handle.clone()).map(|bi| bi as u64) } #[inline] - pub fn overwrite_u64(&self, value: u64) { - Self::set_value(self.handle.clone(), value); + pub fn overwrite_u64(&mut self, value: u64) { + Self::set_value(self.value.handle.clone(), value); } #[inline] @@ -169,7 +203,8 @@ impl BigUint { #[inline] pub fn to_bytes_be(&self) -> BoxedBytes { let mb_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); - M::managed_type_impl().mb_from_big_int_unsigned(self.handle.clone(), mb_handle.clone()); + M::managed_type_impl() + .mb_from_big_int_unsigned(self.value.handle.clone(), mb_handle.clone()); M::managed_type_impl().mb_to_boxed_bytes(mb_handle) } @@ -185,7 +220,8 @@ impl BigUint { pub fn to_bytes_be_buffer(&self) -> ManagedBuffer { let mb_handle: M::ManagedBufferHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_from_big_int_unsigned(self.handle.clone(), mb_handle.clone()); + M::managed_type_impl() + .mb_from_big_int_unsigned(self.value.handle.clone(), mb_handle.clone()); ManagedBuffer::from_handle(mb_handle) } } @@ -196,7 +232,7 @@ impl BigUint { pub fn sqrt(&self) -> Self { let api = M::managed_type_impl(); let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - api.bi_sqrt(result_handle.clone(), self.handle.clone()); + api.bi_sqrt(result_handle.clone(), self.value.handle.clone()); BigUint::from_handle(result_handle) } @@ -204,14 +240,59 @@ impl BigUint { pub fn pow(&self, exp: u32) -> Self { let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let big_int_temp_1 = BigUint::::make_temp(const_handles::BIG_INT_TEMPORARY_1, exp); - M::managed_type_impl().bi_pow(result_handle.clone(), self.handle.clone(), big_int_temp_1); + M::managed_type_impl().bi_pow( + result_handle.clone(), + self.value.handle.clone(), + big_int_temp_1, + ); BigUint::from_handle(result_handle) } + /// The whole part of the base-2 logarithm. + /// + /// Obtained by counting the significant bits. + /// More specifically, the log2 floor is the position of the most significant bit minus one. + /// + /// Will return `None` for the number zero (the logarithm in this case would approach -inf). #[inline] - pub fn log2(&self) -> u32 { + pub fn log2_floor(&self) -> Option { let api = M::managed_type_impl(); - api.bi_log2(self.handle.clone()) + let result = api.bi_log2(self.value.handle.clone()); + if result < 0 { + None + } else { + Some(result as u32) + } + } + + /// Natural logarithm of a number. + /// + /// Returns `None` for 0. + pub fn ln(&self) -> Option>> { + // start with aproximation, based on position of the most significant bit + let Some(log2_floor) = self.log2_floor() else { + // means the input was zero + return None; + }; + + let scaling_factor_9 = ConstDecimals::<9>.scaling_factor(); + let divisor = BigUint::from(1u64) << log2_floor as usize; + let normalized = self * &*scaling_factor_9 / divisor; + + let x = normalized + .to_u64() + .unwrap_or_else(|| ErrorHelper::::signal_error_with_message("ln internal error")) + as i64; + + let mut result = crate::types::math_util::logarithm_i64::ln_polynomial(x); + crate::types::math_util::logarithm_i64::ln_add_bit_log2(&mut result, log2_floor); + + debug_assert!(result > 0); + + let mut result_bi = normalized; // reuse handle + result_bi.overwrite_u64(result as u64); + + Some(ManagedDecimal::const_decimals_from_raw(result_bi)) } } @@ -223,7 +304,7 @@ impl Clone for BigUint { api.bi_add( clone_handle.clone(), clone_handle.clone(), - self.handle.clone(), + self.value.handle.clone(), ); BigUint::from_handle(clone_handle) } @@ -287,26 +368,29 @@ 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); - M::managed_type_impl().bi_to_string(self.handle.clone(), str_handle.clone()); + M::managed_type_impl().bi_to_string(self.value.handle.clone(), str_handle.clone()); f.append_managed_buffer(&ManagedBuffer::from_handle( str_handle.cast_or_signal_error::(), )); } } +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") - .field("handle", &self.handle.clone()) + .field("handle", &self.value.handle.clone()) .field( "hex-value-be", &encode_bytes_as_hex(self.to_bytes_be().as_slice()), diff --git a/framework/base/src/types/managed/basic/big_uint_cmp.rs b/framework/base/src/types/managed/wrapped/big_uint_cmp.rs similarity index 77% rename from framework/base/src/types/managed/basic/big_uint_cmp.rs rename to framework/base/src/types/managed/wrapped/big_uint_cmp.rs index 14441221bf..45e9e5ed95 100644 --- a/framework/base/src/types/managed/basic/big_uint_cmp.rs +++ b/framework/base/src/types/managed/wrapped/big_uint_cmp.rs @@ -1,15 +1,16 @@ -use crate::types::managed::basic::big_num_cmp::cmp_conv_i64; use core::cmp::Ordering; use crate::api::{BigIntApiImpl, ManagedTypeApi}; +use crate::types::cast_to_i64::cast_to_i64; + use super::BigUint; impl PartialEq for BigUint { #[inline] fn eq(&self, other: &Self) -> bool { M::managed_type_impl() - .bi_cmp(self.handle.clone(), other.handle.clone()) + .bi_cmp(self.value.handle.clone(), other.value.handle.clone()) .is_eq() } } @@ -26,7 +27,7 @@ impl PartialOrd for BigUint { impl Ord for BigUint { #[inline] fn cmp(&self, other: &Self) -> Ordering { - M::managed_type_impl().bi_cmp(self.handle.clone(), other.handle.clone()) + M::managed_type_impl().bi_cmp(self.value.handle.clone(), other.value.handle.clone()) } } @@ -35,14 +36,14 @@ macro_rules! partial_eq_and_ord { impl PartialEq<$small_int_type> for BigUint { #[inline] fn eq(&self, other: &$small_int_type) -> bool { - cmp_conv_i64(self, *other).is_eq() + self.value.eq(&cast_to_i64::(*other)) } } impl PartialOrd<$small_int_type> for BigUint { #[inline] fn partial_cmp(&self, other: &$small_int_type) -> Option { - Some(cmp_conv_i64(self, *other)) + self.value.partial_cmp(&cast_to_i64::(*other)) } } }; diff --git a/framework/base/src/types/managed/basic/big_uint_operators.rs b/framework/base/src/types/managed/wrapped/big_uint_operators.rs similarity index 77% rename from framework/base/src/types/managed/basic/big_uint_operators.rs rename to framework/base/src/types/managed/wrapped/big_uint_operators.rs index 885ccb4588..934079eef7 100644 --- a/framework/base/src/types/managed/basic/big_uint_operators.rs +++ b/framework/base/src/types/managed/wrapped/big_uint_operators.rs @@ -14,11 +14,11 @@ macro_rules! binary_operator { fn $method(self, other: BigUint) -> BigUint { M::managed_type_impl().$api_func( - self.handle.clone(), - self.handle.clone(), - other.handle.clone(), + self.value.handle.clone(), + self.value.handle.clone(), + other.value.handle.clone(), ); - BigUint::from_handle(self.handle.clone()) + BigUint::from_handle(self.value.handle.clone()) } } @@ -30,8 +30,8 @@ macro_rules! binary_operator { use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().$api_func( result_handle.clone(), - self.handle.clone(), - other.handle.clone(), + self.value.handle.clone(), + other.value.handle.clone(), ); BigUint::from_handle(result_handle) } @@ -42,11 +42,11 @@ macro_rules! binary_operator { fn $method(self, other: &BigUint) -> BigUint { M::managed_type_impl().$api_func( - self.handle.clone(), - self.handle.clone(), - other.handle.clone(), + self.value.handle.clone(), + self.value.handle.clone(), + other.value.handle.clone(), ); - BigUint::from_handle(self.handle.clone()) + BigUint::from_handle(self.value.handle.clone()) } } @@ -56,11 +56,11 @@ macro_rules! binary_operator { fn $method(self, other: u32) -> BigUint { let big_int_temp_1 = Self::make_temp(const_handles::BIG_INT_TEMPORARY_1, other); M::managed_type_impl().$api_func( - self.handle.clone(), - self.handle.clone(), + self.value.handle.clone(), + self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(self.handle.clone()) + BigUint::from_handle(self.value.handle.clone()) } } @@ -74,7 +74,7 @@ macro_rules! binary_operator { use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().$api_func( result_handle.clone(), - self.handle.clone(), + self.value.handle.clone(), big_int_temp_1, ); BigUint::from_handle(result_handle) @@ -87,11 +87,11 @@ macro_rules! binary_operator { fn $method(self, other: u64) -> BigUint { let big_int_temp_1 = Self::make_temp(const_handles::BIG_INT_TEMPORARY_1, other); M::managed_type_impl().$api_func( - self.handle.clone(), - self.handle.clone(), + self.value.handle.clone(), + self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(self.handle.clone()) + BigUint::from_handle(self.value.handle.clone()) } } @@ -105,7 +105,7 @@ macro_rules! binary_operator { use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().$api_func( result_handle.clone(), - self.handle.clone(), + self.value.handle.clone(), big_int_temp_1, ); BigUint::from_handle(result_handle) @@ -129,9 +129,9 @@ macro_rules! binary_assign_operator { #[inline] fn $method(&mut self, other: Self) { M::managed_type_impl().$api_func( - self.handle.clone(), - self.handle.clone(), - other.handle.clone(), + self.value.handle.clone(), + self.value.handle.clone(), + other.value.handle.clone(), ); } } @@ -140,9 +140,9 @@ macro_rules! binary_assign_operator { #[inline] fn $method(&mut self, other: &BigUint) { M::managed_type_impl().$api_func( - self.handle.clone(), - self.handle.clone(), - other.handle.clone(), + self.value.handle.clone(), + self.value.handle.clone(), + other.value.handle.clone(), ); } } @@ -151,8 +151,8 @@ macro_rules! binary_assign_operator { fn $method(&mut self, other: u32) { let big_int_temp_1 = Self::make_temp(const_handles::BIG_INT_TEMPORARY_1, other); M::managed_type_impl().$api_func( - self.handle.clone(), - self.handle.clone(), + self.value.handle.clone(), + self.value.handle.clone(), big_int_temp_1, ); } @@ -162,8 +162,8 @@ macro_rules! binary_assign_operator { fn $method(&mut self, other: u64) { let big_int_temp_1 = Self::make_temp(const_handles::BIG_INT_TEMPORARY_1, other); M::managed_type_impl().$api_func( - self.handle.clone(), - self.handle.clone(), + self.value.handle.clone(), + self.value.handle.clone(), big_int_temp_1, ); } @@ -187,7 +187,11 @@ macro_rules! shift_traits { #[inline] fn $method(self, rhs: usize) -> BigUint { - M::managed_type_impl().$api_func(self.handle.clone(), self.handle.clone(), rhs); + M::managed_type_impl().$api_func( + self.value.handle.clone(), + self.value.handle.clone(), + rhs, + ); self } } @@ -198,7 +202,11 @@ macro_rules! shift_traits { fn $method(self, rhs: usize) -> BigUint { let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().$api_func(result_handle.clone(), self.handle.clone(), rhs); + M::managed_type_impl().$api_func( + result_handle.clone(), + self.value.handle.clone(), + rhs, + ); BigUint::from_handle(result_handle) } } @@ -213,7 +221,11 @@ macro_rules! shift_assign_traits { impl $shift_assign_trait for BigUint { #[inline] fn $method(&mut self, rhs: usize) { - M::managed_type_impl().$api_func(self.handle.clone(), self.handle.clone(), rhs); + M::managed_type_impl().$api_func( + self.value.handle.clone(), + self.value.handle.clone(), + rhs, + ); } } }; 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 3e7ae8afb5..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,9 +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}, }; @@ -26,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 { @@ -81,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(), ) } @@ -91,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 { @@ -142,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, ) } } @@ -202,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 { @@ -247,7 +268,6 @@ where M: ManagedTypeApi, { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - use crate::alloc::string::ToString; if let Some(token_identifier) = self.data.as_option() { let token_id_str = token_identifier.to_string(); f.debug_tuple("EgldOrEsdtTokenIdentifier::Esdt") 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 c71aa249d7..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, }; @@ -16,11 +15,57 @@ use crate::derive::TypeAbi; /// - EGLD (can be zero in case of no payment whatsoever); /// - Multi-ESDT (one or more ESDT transfers). #[derive( - TopDecode, TopEncode, NestedDecode, NestedEncode, TypeAbi, Clone, PartialEq, Eq, Debug, + TopDecode, TopEncode, TypeAbi, NestedDecode, NestedEncode, Clone, PartialEq, Eq, Debug, )] pub enum EgldOrMultiEsdtPayment { Egld(BigUint), 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..a90482fb04 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,23 @@ where } } +impl TypeAbiFrom for ManagedAddress where M: ManagedTypeApi {} +impl TypeAbiFrom<&Self> for ManagedAddress where M: ManagedTypeApi {} + impl TypeAbi for ManagedAddress where M: ManagedTypeApi, { + type Unmanaged = crate::types::heap::Address; + /// `"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 +253,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 +268,9 @@ impl core::fmt::Debug for ManagedAddress { } } -impl CodecFromSelf for ManagedAddress where M: ManagedTypeApi {} - -impl CodecFrom<[u8; 32]> for ManagedAddress where M: ManagedTypeApi {} - -#[cfg(feature = "alloc")] -impl CodecFrom
for ManagedAddress where M: ManagedTypeApi {} - -#[cfg(feature = "alloc")] -impl CodecFrom<&Address> for ManagedAddress where M: ManagedTypeApi {} - -#[cfg(feature = "alloc")] -impl CodecFrom> for Address where M: ManagedTypeApi {} +impl TypeAbiFrom<[u8; 32]> for ManagedAddress where M: ManagedTypeApi {} -#[cfg(feature = "alloc")] -impl CodecFrom<&ManagedAddress> for Address where M: ManagedTypeApi {} +impl TypeAbiFrom
for ManagedAddress where M: ManagedTypeApi {} +impl TypeAbiFrom<&Address> for ManagedAddress where M: ManagedTypeApi {} +impl TypeAbiFrom> for Address where M: ManagedTypeApi {} +impl TypeAbiFrom<&ManagedAddress> for Address where M: ManagedTypeApi {} diff --git a/framework/base/src/types/managed/wrapped/managed_buffer_read_to_end.rs b/framework/base/src/types/managed/wrapped/managed_buffer_read_to_end.rs new file mode 100644 index 0000000000..e722d9e9f6 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_buffer_read_to_end.rs @@ -0,0 +1,92 @@ +use crate::abi::{TypeAbi, TypeName}; +use crate::types::ManagedBuffer; +use crate::{abi::TypeAbiFrom, api::ManagedTypeApi}; +use multiversx_sc_codec::{ + DecodeError, DecodeErrorHandler, EncodeError, EncodeErrorHandler, NestedDecode, + NestedDecodeInput, NestedEncode, NestedEncodeOutput, TryStaticCast, +}; + +/// A wrapper over a ManagedBuffer with different decode properties. It reads until the end of the buffer. +#[repr(transparent)] +#[derive(Clone, Debug)] +pub struct ManagedBufferReadToEnd { + pub(crate) buffer: ManagedBuffer, +} + +impl ManagedBufferReadToEnd { + #[inline] + pub fn new_from_buf(buf: ManagedBuffer) -> Self { + Self { buffer: buf } + } + + #[inline] + pub fn as_managed_buffer(&self) -> &ManagedBuffer { + &self.buffer + } + + #[inline] + pub fn into_managed_buffer(self) -> ManagedBuffer { + self.buffer + } +} + +impl PartialEq for ManagedBufferReadToEnd { + fn eq(&self, other: &Self) -> bool { + self.buffer == other.buffer + } +} + +impl From> for ManagedBufferReadToEnd +where + M: ManagedTypeApi, +{ + #[inline] + fn from(buf: ManagedBuffer) -> Self { + Self::new_from_buf(buf) + } +} + +impl TypeAbiFrom for ManagedBufferReadToEnd where M: ManagedTypeApi {} +impl TypeAbiFrom<&Self> for ManagedBufferReadToEnd where M: ManagedTypeApi {} + +impl TypeAbi for ManagedBufferReadToEnd { + type Unmanaged = multiversx_sc_codec::Vec; + + fn type_name() -> TypeName { + "bytes-read-to-end".into() + } + + fn type_name_rust() -> TypeName { + "ManagedBufferReadToEnd<$API>".into() + } +} + +impl TryStaticCast for ManagedBufferReadToEnd {} + +impl NestedDecode for ManagedBufferReadToEnd { + fn dep_decode_or_handle_err(input: &mut I, h: H) -> Result + where + I: NestedDecodeInput, + H: DecodeErrorHandler, + { + if I::supports_specialized_type::() { + input.read_specialized((), h) + } else { + Err(h.handle_error(DecodeError::UNSUPPORTED_OPERATION)) + } + } +} + +impl NestedEncode for ManagedBufferReadToEnd { + fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> + where + O: NestedEncodeOutput, + H: EncodeErrorHandler, + { + if O::supports_specialized_type::>() { + dest.push_specialized((), &self.buffer, h) + } else { + Err(h.handle_error(EncodeError::UNSUPPORTED_OPERATION)) + } + } +} 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 new file mode 100644 index 0000000000..d5811031d9 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal.rs @@ -0,0 +1,310 @@ +mod decimals; +mod managed_decimal_cmp; +mod managed_decimal_cmp_signed; +mod managed_decimal_logarithm; +mod managed_decimal_macros; +mod managed_decimal_op_add; +mod managed_decimal_op_add_signed; +mod managed_decimal_op_div; +mod managed_decimal_op_div_signed; +mod managed_decimal_op_mul; +mod managed_decimal_op_mul_signed; +mod managed_decimal_op_sub; +mod managed_decimal_op_sub_signed; +mod managed_decimal_signed; + +pub use decimals::{ConstDecimals, Decimals, NumDecimals}; +pub use managed_decimal_signed::ManagedDecimalSigned; + +use crate::{ + abi::{TypeAbi, TypeAbiFrom, TypeName}, + api::ManagedTypeApi, + formatter::{FormatBuffer, FormatByteReceiver, SCDisplay}, + types::BigUint, +}; + +use alloc::string::ToString; +use multiversx_sc_codec::{ + DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, + NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, +}; + +use core::{cmp::Ordering, ops::Deref}; + +use super::{ManagedBufferCachedBuilder, ManagedRef}; + +/// Fixed-point decimal numbers that accept either a constant or variable number of decimals. +/// +/// Negative numbers are not allowed. It is especially designed for denominated token amounts. +/// If negative numbers are needed, use `ManagedDecimalSigned` instead. +#[derive(Clone)] +pub struct ManagedDecimal { + pub(crate) data: BigUint, + pub(crate) decimals: D, +} + +impl ManagedDecimal { + pub fn trunc(&self) -> BigUint { + &self.data / self.decimals.scaling_factor().deref() + } + + pub fn into_raw_units(&self) -> &BigUint { + &self.data + } + + pub fn from_raw_units(data: BigUint, decimals: D) -> Self { + ManagedDecimal { data, decimals } + } + + pub fn scale(&self) -> usize { + self.decimals.num_decimals() + } + + pub fn scaling_factor(&self) -> ManagedRef<'static, M, BigUint> { + self.decimals.scaling_factor() + } + + pub(crate) fn rescale_data(&self, scale_to_num_decimals: NumDecimals) -> BigUint { + let from_num_decimals = self.decimals.num_decimals(); + + match from_num_decimals.cmp(&scale_to_num_decimals) { + Ordering::Less => { + let delta_decimals = scale_to_num_decimals - from_num_decimals; + let scaling_factor: &BigUint = &delta_decimals.scaling_factor(); + &self.data * scaling_factor + }, + Ordering::Equal => self.data.clone(), + Ordering::Greater => { + let delta_decimals = from_num_decimals - scale_to_num_decimals; + let scaling_factor: &BigUint = &delta_decimals.scaling_factor(); + &self.data * scaling_factor + }, + } + } + + pub fn rescale(&self, scale_to: T) -> ManagedDecimal + where + M: ManagedTypeApi, + { + let scale_to_num_decimals = scale_to.num_decimals(); + ManagedDecimal::from_raw_units(self.rescale_data(scale_to_num_decimals), scale_to) + } + + pub fn into_signed(self) -> ManagedDecimalSigned { + ManagedDecimalSigned { + data: self.data.into_big_int(), + decimals: self.decimals, + } + } +} + +impl From> + for ManagedDecimal> +{ + fn from(mut value: BigUint) -> Self { + let decimals = ConstDecimals; + value *= decimals.scaling_factor().deref(); + ManagedDecimal { + data: value, + decimals, + } + } +} + +impl ManagedDecimal> { + pub fn const_decimals_from_raw(data: BigUint) -> Self { + ManagedDecimal { + data, + decimals: ConstDecimals, + } + } + + /// Converts from constant (compile-time) number of decimals to a variable number of decimals. + pub fn into_var_decimals(self) -> ManagedDecimal { + ManagedDecimal { + data: self.data, + decimals: DECIMALS, + } + } +} + +impl TopEncode + for ManagedDecimal> +{ + #[inline] + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + self.data.top_encode_or_handle_err(output, h) + } +} + +impl TopDecode + for ManagedDecimal> +{ + fn top_decode_or_handle_err(input: I, h: H) -> Result + where + I: TopDecodeInput, + H: DecodeErrorHandler, + { + Ok(ManagedDecimal::const_decimals_from_raw( + BigUint::top_decode_or_handle_err(input, h)?, + )) + } +} + +impl NestedEncode + for ManagedDecimal> +{ + fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> + where + O: NestedEncodeOutput, + H: EncodeErrorHandler, + { + NestedEncode::dep_encode_or_handle_err(&self.data, dest, h)?; + + Result::Ok(()) + } +} + +impl NestedDecode + for ManagedDecimal> +{ + fn dep_decode_or_handle_err(input: &mut I, h: H) -> Result + where + I: NestedDecodeInput, + H: DecodeErrorHandler, + { + Result::Ok(ManagedDecimal::const_decimals_from_raw( + as NestedDecode>::dep_decode_or_handle_err(input, h)?, + )) + } +} + +impl NestedEncode for ManagedDecimal { + fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> + where + O: NestedEncodeOutput, + H: EncodeErrorHandler, + { + NestedEncode::dep_encode_or_handle_err(&self.data, dest, h)?; + NestedEncode::dep_encode_or_handle_err(&self.decimals, dest, h)?; + + Result::Ok(()) + } +} + +impl TopEncode for ManagedDecimal { + 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 dest = &mut buffer; + NestedEncode::dep_encode_or_handle_err(&self.data, dest, h)?; + NestedEncode::dep_encode_or_handle_err(&self.decimals, dest, h)?; + + output.finalize_nested_encode(buffer); + Result::Ok(()) + } +} + +impl NestedDecode for ManagedDecimal { + fn dep_decode_or_handle_err(input: &mut I, h: H) -> Result + where + I: NestedDecodeInput, + H: DecodeErrorHandler, + { + Result::Ok(ManagedDecimal::from_raw_units( + as NestedDecode>::dep_decode_or_handle_err(input, h)?, + ::dep_decode_or_handle_err(input, h)?, + )) + } +} + +impl TopDecode for ManagedDecimal { + fn top_decode_or_handle_err(top_input: I, h: H) -> Result + where + I: TopDecodeInput, + H: DecodeErrorHandler, + { + let mut nested_buffer = top_input.into_nested_buffer(); + let result = ManagedDecimal::from_raw_units( + as NestedDecode>::dep_decode_or_handle_err(&mut nested_buffer, h)?, + ::dep_decode_or_handle_err(&mut nested_buffer, h)?, + ); + if !NestedDecodeInput::is_depleted(&nested_buffer) { + return Result::Err(h.handle_error(DecodeError::INPUT_TOO_LONG)); + } + Result::Ok(result) + } +} + +impl TypeAbiFrom for ManagedDecimal {} + +impl TypeAbi for ManagedDecimal { + type Unmanaged = Self; + + fn type_name() -> TypeName { + TypeName::from("ManagedDecimal") + } + + fn is_variadic() -> bool { + false + } +} + +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 + } +} +impl SCDisplay for ManagedDecimal { + fn fmt(&self, f: &mut F) { + managed_decimal_signed::managed_decimal_fmt( + &self.data.value, + self.decimals.num_decimals(), + f, + ); + } +} + +impl core::fmt::Display for ManagedDecimal { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut result = ManagedBufferCachedBuilder::::new_from_slice(&[]); + result.append_display(self); + core::fmt::Display::fmt(&result.into_managed_buffer(), f) + } +} + +impl core::fmt::Debug for ManagedDecimal { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("ManagedDecimal") + .field("handle", &self.data.value.handle.clone()) + .field("number", &self.to_string()) + .finish() + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/decimals.rs b/framework/base/src/types/managed/wrapped/managed_decimal/decimals.rs new file mode 100644 index 0000000000..9b6fba216d --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/decimals.rs @@ -0,0 +1,63 @@ +use crate::{ + api::{const_handles, use_raw_handle, BigIntApiImpl, ManagedTypeApi, StaticVarApiImpl}, + types::{BigUint, ManagedRef}, +}; + +/// Decimals are represented as usize. This type is also used as variable decimals. +pub type NumDecimals = usize; + +/// Implemented by all decimal types usable in `ManagedDecimal`. +pub trait Decimals { + /// Number of decimals as variable. + fn num_decimals(&self) -> NumDecimals; + + /// 10^num_decimals, represented as a `BigUint`. + fn scaling_factor(&self) -> ManagedRef<'static, M, BigUint> { + scaling_factor(self.num_decimals()) + } +} + +impl Decimals for NumDecimals { + fn num_decimals(&self) -> NumDecimals { + *self + } +} + +/// Zero-sized constant number of decimals. +/// +/// Ideal if the number of decimals is known at compile time. +#[derive(Clone, Debug)] +pub struct ConstDecimals; + +impl Decimals for ConstDecimals { + fn num_decimals(&self) -> NumDecimals { + DECIMALS + } + + fn scaling_factor(&self) -> ManagedRef<'static, M, BigUint> { + scaling_factor(self.num_decimals()) + } +} + +fn scaling_factor( + num_decimals: NumDecimals, +) -> ManagedRef<'static, M, BigUint> { + let handle: M::BigIntHandle = + use_raw_handle(const_handles::get_scaling_factor_handle(num_decimals)); + + if !M::static_var_api_impl().is_scaling_factor_cached(num_decimals) { + cache_scaling_factor::(handle.clone(), num_decimals); + M::static_var_api_impl().set_scaling_factor_cached(num_decimals); + } + + unsafe { ManagedRef::<'static, M, BigUint>::wrap_handle(handle) } +} + +fn cache_scaling_factor(handle: M::BigIntHandle, num_decimals: NumDecimals) { + let temp1: M::BigIntHandle = use_raw_handle(const_handles::BIG_INT_TEMPORARY_1); + let temp2: M::BigIntHandle = use_raw_handle(const_handles::BIG_INT_TEMPORARY_2); + let api = M::managed_type_impl(); + api.bi_set_int64(temp1.clone(), 10); + api.bi_set_int64(temp2.clone(), num_decimals as i64); + api.bi_pow(handle, temp1, temp2); +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_cmp.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_cmp.rs new file mode 100644 index 0000000000..89a804aabd --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_cmp.rs @@ -0,0 +1,55 @@ +use core::cmp::Ordering; + +use crate::{ + api::ManagedTypeApi, + types::{BigUint, Decimals, ManagedDecimal}, +}; + +impl PartialEq> + for ManagedDecimal +{ + fn eq(&self, other: &ManagedDecimal) -> bool { + match self + .decimals + .num_decimals() + .cmp(&other.decimals.num_decimals()) + { + Ordering::Less => { + let diff_decimals = other.decimals.num_decimals() - self.decimals.num_decimals(); + let scaling_factor: &BigUint = &diff_decimals.scaling_factor(); + &self.data * scaling_factor == other.data + }, + Ordering::Equal => self.data == other.data, + Ordering::Greater => { + let diff_decimals = self.decimals.num_decimals() - other.decimals.num_decimals(); + let scaling_factor: &BigUint = &diff_decimals.scaling_factor(); + &other.data * scaling_factor == self.data + }, + } + } +} + +impl PartialOrd> + for ManagedDecimal +{ + fn partial_cmp(&self, other: &ManagedDecimal) -> Option { + match self + .decimals + .num_decimals() + .cmp(&other.decimals.num_decimals()) + { + Ordering::Less => { + let diff_decimals = other.decimals.num_decimals() - self.decimals.num_decimals(); + let scaling_factor: &BigUint = &diff_decimals.scaling_factor(); + + Some((&self.data * scaling_factor).cmp(&other.data)) + }, + Ordering::Equal => Some((self.data).cmp(&other.data)), + Ordering::Greater => { + let diff_decimals = self.decimals.num_decimals() - other.decimals.num_decimals(); + let scaling_factor: &BigUint = &diff_decimals.scaling_factor(); + Some((&other.data * scaling_factor).cmp(&self.data)) + }, + } + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_cmp_signed.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_cmp_signed.rs new file mode 100644 index 0000000000..9f407c5235 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_cmp_signed.rs @@ -0,0 +1,55 @@ +use core::cmp::Ordering; + +use crate::{ + api::ManagedTypeApi, + types::{BigUint, Decimals, ManagedDecimalSigned}, +}; + +impl PartialEq> + for ManagedDecimalSigned +{ + fn eq(&self, other: &ManagedDecimalSigned) -> bool { + match self + .decimals + .num_decimals() + .cmp(&other.decimals.num_decimals()) + { + Ordering::Less => { + let diff_decimals = other.decimals.num_decimals() - self.decimals.num_decimals(); + let scaling_factor: &BigUint = &diff_decimals.scaling_factor(); + &self.data * scaling_factor == other.data + }, + Ordering::Equal => self.data == other.data, + Ordering::Greater => { + let diff_decimals = self.decimals.num_decimals() - other.decimals.num_decimals(); + let scaling_factor: &BigUint = &diff_decimals.scaling_factor(); + &other.data * scaling_factor == self.data + }, + } + } +} + +impl PartialOrd> + for ManagedDecimalSigned +{ + fn partial_cmp(&self, other: &ManagedDecimalSigned) -> Option { + match self + .decimals + .num_decimals() + .cmp(&other.decimals.num_decimals()) + { + Ordering::Less => { + let diff_decimals = other.decimals.num_decimals() - self.decimals.num_decimals(); + let scaling_factor: &BigUint = &diff_decimals.scaling_factor(); + + Some((&self.data * scaling_factor).cmp(&other.data)) + }, + Ordering::Equal => Some((self.data).cmp(&other.data)), + Ordering::Greater => { + let diff_decimals = self.decimals.num_decimals() - other.decimals.num_decimals(); + let scaling_factor: &BigUint = &diff_decimals.scaling_factor(); + Some((&other.data * scaling_factor).cmp(&self.data)) + }, + } + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs new file mode 100644 index 0000000000..41f173a50a --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs @@ -0,0 +1,124 @@ +use super::decimals::{ConstDecimals, Decimals}; +use super::ManagedDecimalSigned; +use super::{ManagedDecimal, NumDecimals}; + +use crate::proxy_imports::ManagedType; +use crate::{ + api::ManagedTypeApi, + contract_base::ErrorHelper, + types::{BigInt, BigUint, Sign}, +}; + +fn compute_ln( + data: &BigUint, + num_decimals: NumDecimals, +) -> Option>> { + // start with aproximation, based on position of the most significant bit + let Some(log2_floor) = data.log2_floor() else { + // means the input was zero + return None; + }; + + let scaling_factor_9 = ConstDecimals::<9>.scaling_factor(); + let divisor = BigUint::from(1u64) << log2_floor as usize; + let normalized = data * &*scaling_factor_9 / divisor; + + let x = normalized + .to_u64() + .unwrap_or_else(|| ErrorHelper::::signal_error_with_message("ln internal error")) + as i64; + + let mut result = crate::types::math_util::logarithm_i64::ln_polynomial(x); + crate::types::math_util::logarithm_i64::ln_add_bit_log2(&mut result, log2_floor); + + debug_assert!(result > 0); + + crate::types::math_util::logarithm_i64::ln_sub_decimals(&mut result, num_decimals); + + Some(ManagedDecimalSigned::from_raw_units( + BigInt::from(result), + ConstDecimals, + )) +} + +fn compute_log2( + data: &BigUint, + num_decimals: NumDecimals, +) -> Option>> { + // start with aproximation, based on position of the most significant bit + let Some(log2_floor) = data.log2_floor() else { + // means the input was zero + return None; + }; + + let scaling_factor_9 = ConstDecimals::<9>.scaling_factor(); + let divisor = BigUint::from(1u64) << log2_floor as usize; + let normalized = data * &*scaling_factor_9 / divisor; + + let x = normalized + .to_u64() + .unwrap_or_else(|| ErrorHelper::::signal_error_with_message("log2 internal error")) + as i64; + + let mut result = crate::types::math_util::logarithm_i64::log2_polynomial(x); + crate::types::math_util::logarithm_i64::log2_add_bit_log2(&mut result, log2_floor); + + debug_assert!(result > 0); + + crate::types::math_util::logarithm_i64::log2_sub_decimals(&mut result, num_decimals); + + Some(ManagedDecimalSigned::from_raw_units( + BigInt::from(result), + ConstDecimals, + )) +} + +impl ManagedDecimal { + /// Natural logarithm of a number. + /// + /// Returns `None` for 0. + /// + /// Even though 9 decimals are returned, only around 6 decimals are actually useful. + pub fn ln(&self) -> Option>> { + compute_ln(&self.data, self.decimals.num_decimals()) + } + + /// Base 2 logarithm of a number. + /// + /// Returns `None` for 0. + /// + /// Even though 9 decimals are returned, only around 6 decimals are actually useful. + pub fn log2(&self) -> Option>> { + compute_log2(&self.data, self.decimals.num_decimals()) + } +} + +impl ManagedDecimalSigned { + /// Natural logarithm of a number. + /// + /// Returns `None` for 0. + /// + /// Even though 9 decimals are returned, only around 6 decimals are actually useful. + pub fn ln(&self) -> Option>> { + if self.sign() != Sign::Plus { + return None; + } + + let bu = BigUint::from_handle(self.data.handle.clone()); + compute_ln(&bu, self.decimals.num_decimals()) + } + + /// Base 2 logarithm of a number. + /// + /// Returns `None` for 0. + /// + /// Even though 9 decimals are returned, only around 6 decimals are actually useful. + pub fn log2(&self) -> Option>> { + if self.sign() != Sign::Plus { + return None; + } + + let bu = BigUint::from_handle(self.data.handle.clone()); + compute_log2(&bu, self.decimals.num_decimals()) + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_macros.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_macros.rs new file mode 100644 index 0000000000..ca6d8a3a3c --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_macros.rs @@ -0,0 +1,4246 @@ +use crate::types::ConstDecimals; +use core::ops::{Add, Sub}; + +macro_rules! add_sub_const_decimals { + ($dec1:expr, $dec2:expr, $result_add:expr, $result_sub:expr) => { + impl Add> for ConstDecimals<$dec1> { + type Output = ConstDecimals<$result_add>; + fn add(self, _rhs: ConstDecimals<$dec2>) -> Self::Output { + ConstDecimals::<$result_add> + } + } + impl Sub> for ConstDecimals<$dec1> { + type Output = ConstDecimals<$result_sub>; + fn sub(self, _rhs: ConstDecimals<$dec2>) -> Self::Output { + ConstDecimals::<$result_sub> + } + } + }; +} + +// Add and subtract macros for const decimals +add_sub_const_decimals!(64usize, 64usize, 128usize, 0usize); +add_sub_const_decimals!(64usize, 63usize, 127usize, 1usize); +add_sub_const_decimals!(64usize, 62usize, 126usize, 2usize); +add_sub_const_decimals!(64usize, 61usize, 125usize, 3usize); +add_sub_const_decimals!(64usize, 60usize, 124usize, 4usize); +add_sub_const_decimals!(64usize, 59usize, 123usize, 5usize); +add_sub_const_decimals!(64usize, 58usize, 122usize, 6usize); +add_sub_const_decimals!(64usize, 57usize, 121usize, 7usize); +add_sub_const_decimals!(64usize, 56usize, 120usize, 8usize); +add_sub_const_decimals!(64usize, 55usize, 119usize, 9usize); +add_sub_const_decimals!(64usize, 54usize, 118usize, 10usize); +add_sub_const_decimals!(64usize, 53usize, 117usize, 11usize); +add_sub_const_decimals!(64usize, 52usize, 116usize, 12usize); +add_sub_const_decimals!(64usize, 51usize, 115usize, 13usize); +add_sub_const_decimals!(64usize, 50usize, 114usize, 14usize); +add_sub_const_decimals!(64usize, 49usize, 113usize, 15usize); +add_sub_const_decimals!(64usize, 48usize, 112usize, 16usize); +add_sub_const_decimals!(64usize, 47usize, 111usize, 17usize); +add_sub_const_decimals!(64usize, 46usize, 110usize, 18usize); +add_sub_const_decimals!(64usize, 45usize, 109usize, 19usize); +add_sub_const_decimals!(64usize, 44usize, 108usize, 20usize); +add_sub_const_decimals!(64usize, 43usize, 107usize, 21usize); +add_sub_const_decimals!(64usize, 42usize, 106usize, 22usize); +add_sub_const_decimals!(64usize, 41usize, 105usize, 23usize); +add_sub_const_decimals!(64usize, 40usize, 104usize, 24usize); +add_sub_const_decimals!(64usize, 39usize, 103usize, 25usize); +add_sub_const_decimals!(64usize, 38usize, 102usize, 26usize); +add_sub_const_decimals!(64usize, 37usize, 101usize, 27usize); +add_sub_const_decimals!(64usize, 36usize, 100usize, 28usize); +add_sub_const_decimals!(64usize, 35usize, 99usize, 29usize); +add_sub_const_decimals!(64usize, 34usize, 98usize, 30usize); +add_sub_const_decimals!(64usize, 33usize, 97usize, 31usize); +add_sub_const_decimals!(64usize, 32usize, 96usize, 32usize); +add_sub_const_decimals!(64usize, 31usize, 95usize, 33usize); +add_sub_const_decimals!(64usize, 30usize, 94usize, 34usize); +add_sub_const_decimals!(64usize, 29usize, 93usize, 35usize); +add_sub_const_decimals!(64usize, 28usize, 92usize, 36usize); +add_sub_const_decimals!(64usize, 27usize, 91usize, 37usize); +add_sub_const_decimals!(64usize, 26usize, 90usize, 38usize); +add_sub_const_decimals!(64usize, 25usize, 89usize, 39usize); +add_sub_const_decimals!(64usize, 24usize, 88usize, 40usize); +add_sub_const_decimals!(64usize, 23usize, 87usize, 41usize); +add_sub_const_decimals!(64usize, 22usize, 86usize, 42usize); +add_sub_const_decimals!(64usize, 21usize, 85usize, 43usize); +add_sub_const_decimals!(64usize, 20usize, 84usize, 44usize); +add_sub_const_decimals!(64usize, 19usize, 83usize, 45usize); +add_sub_const_decimals!(64usize, 18usize, 82usize, 46usize); +add_sub_const_decimals!(64usize, 17usize, 81usize, 47usize); +add_sub_const_decimals!(64usize, 16usize, 80usize, 48usize); +add_sub_const_decimals!(64usize, 15usize, 79usize, 49usize); +add_sub_const_decimals!(64usize, 14usize, 78usize, 50usize); +add_sub_const_decimals!(64usize, 13usize, 77usize, 51usize); +add_sub_const_decimals!(64usize, 12usize, 76usize, 52usize); +add_sub_const_decimals!(64usize, 11usize, 75usize, 53usize); +add_sub_const_decimals!(64usize, 10usize, 74usize, 54usize); +add_sub_const_decimals!(64usize, 9usize, 73usize, 55usize); +add_sub_const_decimals!(64usize, 8usize, 72usize, 56usize); +add_sub_const_decimals!(64usize, 7usize, 71usize, 57usize); +add_sub_const_decimals!(64usize, 6usize, 70usize, 58usize); +add_sub_const_decimals!(64usize, 5usize, 69usize, 59usize); +add_sub_const_decimals!(64usize, 4usize, 68usize, 60usize); +add_sub_const_decimals!(64usize, 3usize, 67usize, 61usize); +add_sub_const_decimals!(64usize, 2usize, 66usize, 62usize); +add_sub_const_decimals!(64usize, 1usize, 65usize, 63usize); +add_sub_const_decimals!(64usize, 0usize, 64usize, 64usize); +add_sub_const_decimals!(63usize, 64usize, 127usize, 0usize); +add_sub_const_decimals!(63usize, 63usize, 126usize, 0usize); +add_sub_const_decimals!(63usize, 62usize, 125usize, 1usize); +add_sub_const_decimals!(63usize, 61usize, 124usize, 2usize); +add_sub_const_decimals!(63usize, 60usize, 123usize, 3usize); +add_sub_const_decimals!(63usize, 59usize, 122usize, 4usize); +add_sub_const_decimals!(63usize, 58usize, 121usize, 5usize); +add_sub_const_decimals!(63usize, 57usize, 120usize, 6usize); +add_sub_const_decimals!(63usize, 56usize, 119usize, 7usize); +add_sub_const_decimals!(63usize, 55usize, 118usize, 8usize); +add_sub_const_decimals!(63usize, 54usize, 117usize, 9usize); +add_sub_const_decimals!(63usize, 53usize, 116usize, 10usize); +add_sub_const_decimals!(63usize, 52usize, 115usize, 11usize); +add_sub_const_decimals!(63usize, 51usize, 114usize, 12usize); +add_sub_const_decimals!(63usize, 50usize, 113usize, 13usize); +add_sub_const_decimals!(63usize, 49usize, 112usize, 14usize); +add_sub_const_decimals!(63usize, 48usize, 111usize, 15usize); +add_sub_const_decimals!(63usize, 47usize, 110usize, 16usize); +add_sub_const_decimals!(63usize, 46usize, 109usize, 17usize); +add_sub_const_decimals!(63usize, 45usize, 108usize, 18usize); +add_sub_const_decimals!(63usize, 44usize, 107usize, 19usize); +add_sub_const_decimals!(63usize, 43usize, 106usize, 20usize); +add_sub_const_decimals!(63usize, 42usize, 105usize, 21usize); +add_sub_const_decimals!(63usize, 41usize, 104usize, 22usize); +add_sub_const_decimals!(63usize, 40usize, 103usize, 23usize); +add_sub_const_decimals!(63usize, 39usize, 102usize, 24usize); +add_sub_const_decimals!(63usize, 38usize, 101usize, 25usize); +add_sub_const_decimals!(63usize, 37usize, 100usize, 26usize); +add_sub_const_decimals!(63usize, 36usize, 99usize, 27usize); +add_sub_const_decimals!(63usize, 35usize, 98usize, 28usize); +add_sub_const_decimals!(63usize, 34usize, 97usize, 29usize); +add_sub_const_decimals!(63usize, 33usize, 96usize, 30usize); +add_sub_const_decimals!(63usize, 32usize, 95usize, 31usize); +add_sub_const_decimals!(63usize, 31usize, 94usize, 32usize); +add_sub_const_decimals!(63usize, 30usize, 93usize, 33usize); +add_sub_const_decimals!(63usize, 29usize, 92usize, 34usize); +add_sub_const_decimals!(63usize, 28usize, 91usize, 35usize); +add_sub_const_decimals!(63usize, 27usize, 90usize, 36usize); +add_sub_const_decimals!(63usize, 26usize, 89usize, 37usize); +add_sub_const_decimals!(63usize, 25usize, 88usize, 38usize); +add_sub_const_decimals!(63usize, 24usize, 87usize, 39usize); +add_sub_const_decimals!(63usize, 23usize, 86usize, 40usize); +add_sub_const_decimals!(63usize, 22usize, 85usize, 41usize); +add_sub_const_decimals!(63usize, 21usize, 84usize, 42usize); +add_sub_const_decimals!(63usize, 20usize, 83usize, 43usize); +add_sub_const_decimals!(63usize, 19usize, 82usize, 44usize); +add_sub_const_decimals!(63usize, 18usize, 81usize, 45usize); +add_sub_const_decimals!(63usize, 17usize, 80usize, 46usize); +add_sub_const_decimals!(63usize, 16usize, 79usize, 47usize); +add_sub_const_decimals!(63usize, 15usize, 78usize, 48usize); +add_sub_const_decimals!(63usize, 14usize, 77usize, 49usize); +add_sub_const_decimals!(63usize, 13usize, 76usize, 50usize); +add_sub_const_decimals!(63usize, 12usize, 75usize, 51usize); +add_sub_const_decimals!(63usize, 11usize, 74usize, 52usize); +add_sub_const_decimals!(63usize, 10usize, 73usize, 53usize); +add_sub_const_decimals!(63usize, 9usize, 72usize, 54usize); +add_sub_const_decimals!(63usize, 8usize, 71usize, 55usize); +add_sub_const_decimals!(63usize, 7usize, 70usize, 56usize); +add_sub_const_decimals!(63usize, 6usize, 69usize, 57usize); +add_sub_const_decimals!(63usize, 5usize, 68usize, 58usize); +add_sub_const_decimals!(63usize, 4usize, 67usize, 59usize); +add_sub_const_decimals!(63usize, 3usize, 66usize, 60usize); +add_sub_const_decimals!(63usize, 2usize, 65usize, 61usize); +add_sub_const_decimals!(63usize, 1usize, 64usize, 62usize); +add_sub_const_decimals!(63usize, 0usize, 63usize, 63usize); +add_sub_const_decimals!(62usize, 64usize, 126usize, 0usize); +add_sub_const_decimals!(62usize, 63usize, 125usize, 0usize); +add_sub_const_decimals!(62usize, 62usize, 124usize, 0usize); +add_sub_const_decimals!(62usize, 61usize, 123usize, 1usize); +add_sub_const_decimals!(62usize, 60usize, 122usize, 2usize); +add_sub_const_decimals!(62usize, 59usize, 121usize, 3usize); +add_sub_const_decimals!(62usize, 58usize, 120usize, 4usize); +add_sub_const_decimals!(62usize, 57usize, 119usize, 5usize); +add_sub_const_decimals!(62usize, 56usize, 118usize, 6usize); +add_sub_const_decimals!(62usize, 55usize, 117usize, 7usize); +add_sub_const_decimals!(62usize, 54usize, 116usize, 8usize); +add_sub_const_decimals!(62usize, 53usize, 115usize, 9usize); +add_sub_const_decimals!(62usize, 52usize, 114usize, 10usize); +add_sub_const_decimals!(62usize, 51usize, 113usize, 11usize); +add_sub_const_decimals!(62usize, 50usize, 112usize, 12usize); +add_sub_const_decimals!(62usize, 49usize, 111usize, 13usize); +add_sub_const_decimals!(62usize, 48usize, 110usize, 14usize); +add_sub_const_decimals!(62usize, 47usize, 109usize, 15usize); +add_sub_const_decimals!(62usize, 46usize, 108usize, 16usize); +add_sub_const_decimals!(62usize, 45usize, 107usize, 17usize); +add_sub_const_decimals!(62usize, 44usize, 106usize, 18usize); +add_sub_const_decimals!(62usize, 43usize, 105usize, 19usize); +add_sub_const_decimals!(62usize, 42usize, 104usize, 20usize); +add_sub_const_decimals!(62usize, 41usize, 103usize, 21usize); +add_sub_const_decimals!(62usize, 40usize, 102usize, 22usize); +add_sub_const_decimals!(62usize, 39usize, 101usize, 23usize); +add_sub_const_decimals!(62usize, 38usize, 100usize, 24usize); +add_sub_const_decimals!(62usize, 37usize, 99usize, 25usize); +add_sub_const_decimals!(62usize, 36usize, 98usize, 26usize); +add_sub_const_decimals!(62usize, 35usize, 97usize, 27usize); +add_sub_const_decimals!(62usize, 34usize, 96usize, 28usize); +add_sub_const_decimals!(62usize, 33usize, 95usize, 29usize); +add_sub_const_decimals!(62usize, 32usize, 94usize, 30usize); +add_sub_const_decimals!(62usize, 31usize, 93usize, 31usize); +add_sub_const_decimals!(62usize, 30usize, 92usize, 32usize); +add_sub_const_decimals!(62usize, 29usize, 91usize, 33usize); +add_sub_const_decimals!(62usize, 28usize, 90usize, 34usize); +add_sub_const_decimals!(62usize, 27usize, 89usize, 35usize); +add_sub_const_decimals!(62usize, 26usize, 88usize, 36usize); +add_sub_const_decimals!(62usize, 25usize, 87usize, 37usize); +add_sub_const_decimals!(62usize, 24usize, 86usize, 38usize); +add_sub_const_decimals!(62usize, 23usize, 85usize, 39usize); +add_sub_const_decimals!(62usize, 22usize, 84usize, 40usize); +add_sub_const_decimals!(62usize, 21usize, 83usize, 41usize); +add_sub_const_decimals!(62usize, 20usize, 82usize, 42usize); +add_sub_const_decimals!(62usize, 19usize, 81usize, 43usize); +add_sub_const_decimals!(62usize, 18usize, 80usize, 44usize); +add_sub_const_decimals!(62usize, 17usize, 79usize, 45usize); +add_sub_const_decimals!(62usize, 16usize, 78usize, 46usize); +add_sub_const_decimals!(62usize, 15usize, 77usize, 47usize); +add_sub_const_decimals!(62usize, 14usize, 76usize, 48usize); +add_sub_const_decimals!(62usize, 13usize, 75usize, 49usize); +add_sub_const_decimals!(62usize, 12usize, 74usize, 50usize); +add_sub_const_decimals!(62usize, 11usize, 73usize, 51usize); +add_sub_const_decimals!(62usize, 10usize, 72usize, 52usize); +add_sub_const_decimals!(62usize, 9usize, 71usize, 53usize); +add_sub_const_decimals!(62usize, 8usize, 70usize, 54usize); +add_sub_const_decimals!(62usize, 7usize, 69usize, 55usize); +add_sub_const_decimals!(62usize, 6usize, 68usize, 56usize); +add_sub_const_decimals!(62usize, 5usize, 67usize, 57usize); +add_sub_const_decimals!(62usize, 4usize, 66usize, 58usize); +add_sub_const_decimals!(62usize, 3usize, 65usize, 59usize); +add_sub_const_decimals!(62usize, 2usize, 64usize, 60usize); +add_sub_const_decimals!(62usize, 1usize, 63usize, 61usize); +add_sub_const_decimals!(62usize, 0usize, 62usize, 62usize); +add_sub_const_decimals!(61usize, 64usize, 125usize, 0usize); +add_sub_const_decimals!(61usize, 63usize, 124usize, 0usize); +add_sub_const_decimals!(61usize, 62usize, 123usize, 0usize); +add_sub_const_decimals!(61usize, 61usize, 122usize, 0usize); +add_sub_const_decimals!(61usize, 60usize, 121usize, 1usize); +add_sub_const_decimals!(61usize, 59usize, 120usize, 2usize); +add_sub_const_decimals!(61usize, 58usize, 119usize, 3usize); +add_sub_const_decimals!(61usize, 57usize, 118usize, 4usize); +add_sub_const_decimals!(61usize, 56usize, 117usize, 5usize); +add_sub_const_decimals!(61usize, 55usize, 116usize, 6usize); +add_sub_const_decimals!(61usize, 54usize, 115usize, 7usize); +add_sub_const_decimals!(61usize, 53usize, 114usize, 8usize); +add_sub_const_decimals!(61usize, 52usize, 113usize, 9usize); +add_sub_const_decimals!(61usize, 51usize, 112usize, 10usize); +add_sub_const_decimals!(61usize, 50usize, 111usize, 11usize); +add_sub_const_decimals!(61usize, 49usize, 110usize, 12usize); +add_sub_const_decimals!(61usize, 48usize, 109usize, 13usize); +add_sub_const_decimals!(61usize, 47usize, 108usize, 14usize); +add_sub_const_decimals!(61usize, 46usize, 107usize, 15usize); +add_sub_const_decimals!(61usize, 45usize, 106usize, 16usize); +add_sub_const_decimals!(61usize, 44usize, 105usize, 17usize); +add_sub_const_decimals!(61usize, 43usize, 104usize, 18usize); +add_sub_const_decimals!(61usize, 42usize, 103usize, 19usize); +add_sub_const_decimals!(61usize, 41usize, 102usize, 20usize); +add_sub_const_decimals!(61usize, 40usize, 101usize, 21usize); +add_sub_const_decimals!(61usize, 39usize, 100usize, 22usize); +add_sub_const_decimals!(61usize, 38usize, 99usize, 23usize); +add_sub_const_decimals!(61usize, 37usize, 98usize, 24usize); +add_sub_const_decimals!(61usize, 36usize, 97usize, 25usize); +add_sub_const_decimals!(61usize, 35usize, 96usize, 26usize); +add_sub_const_decimals!(61usize, 34usize, 95usize, 27usize); +add_sub_const_decimals!(61usize, 33usize, 94usize, 28usize); +add_sub_const_decimals!(61usize, 32usize, 93usize, 29usize); +add_sub_const_decimals!(61usize, 31usize, 92usize, 30usize); +add_sub_const_decimals!(61usize, 30usize, 91usize, 31usize); +add_sub_const_decimals!(61usize, 29usize, 90usize, 32usize); +add_sub_const_decimals!(61usize, 28usize, 89usize, 33usize); +add_sub_const_decimals!(61usize, 27usize, 88usize, 34usize); +add_sub_const_decimals!(61usize, 26usize, 87usize, 35usize); +add_sub_const_decimals!(61usize, 25usize, 86usize, 36usize); +add_sub_const_decimals!(61usize, 24usize, 85usize, 37usize); +add_sub_const_decimals!(61usize, 23usize, 84usize, 38usize); +add_sub_const_decimals!(61usize, 22usize, 83usize, 39usize); +add_sub_const_decimals!(61usize, 21usize, 82usize, 40usize); +add_sub_const_decimals!(61usize, 20usize, 81usize, 41usize); +add_sub_const_decimals!(61usize, 19usize, 80usize, 42usize); +add_sub_const_decimals!(61usize, 18usize, 79usize, 43usize); +add_sub_const_decimals!(61usize, 17usize, 78usize, 44usize); +add_sub_const_decimals!(61usize, 16usize, 77usize, 45usize); +add_sub_const_decimals!(61usize, 15usize, 76usize, 46usize); +add_sub_const_decimals!(61usize, 14usize, 75usize, 47usize); +add_sub_const_decimals!(61usize, 13usize, 74usize, 48usize); +add_sub_const_decimals!(61usize, 12usize, 73usize, 49usize); +add_sub_const_decimals!(61usize, 11usize, 72usize, 50usize); +add_sub_const_decimals!(61usize, 10usize, 71usize, 51usize); +add_sub_const_decimals!(61usize, 9usize, 70usize, 52usize); +add_sub_const_decimals!(61usize, 8usize, 69usize, 53usize); +add_sub_const_decimals!(61usize, 7usize, 68usize, 54usize); +add_sub_const_decimals!(61usize, 6usize, 67usize, 55usize); +add_sub_const_decimals!(61usize, 5usize, 66usize, 56usize); +add_sub_const_decimals!(61usize, 4usize, 65usize, 57usize); +add_sub_const_decimals!(61usize, 3usize, 64usize, 58usize); +add_sub_const_decimals!(61usize, 2usize, 63usize, 59usize); +add_sub_const_decimals!(61usize, 1usize, 62usize, 60usize); +add_sub_const_decimals!(61usize, 0usize, 61usize, 61usize); +add_sub_const_decimals!(60usize, 64usize, 124usize, 0usize); +add_sub_const_decimals!(60usize, 63usize, 123usize, 0usize); +add_sub_const_decimals!(60usize, 62usize, 122usize, 0usize); +add_sub_const_decimals!(60usize, 61usize, 121usize, 0usize); +add_sub_const_decimals!(60usize, 60usize, 120usize, 0usize); +add_sub_const_decimals!(60usize, 59usize, 119usize, 1usize); +add_sub_const_decimals!(60usize, 58usize, 118usize, 2usize); +add_sub_const_decimals!(60usize, 57usize, 117usize, 3usize); +add_sub_const_decimals!(60usize, 56usize, 116usize, 4usize); +add_sub_const_decimals!(60usize, 55usize, 115usize, 5usize); +add_sub_const_decimals!(60usize, 54usize, 114usize, 6usize); +add_sub_const_decimals!(60usize, 53usize, 113usize, 7usize); +add_sub_const_decimals!(60usize, 52usize, 112usize, 8usize); +add_sub_const_decimals!(60usize, 51usize, 111usize, 9usize); +add_sub_const_decimals!(60usize, 50usize, 110usize, 10usize); +add_sub_const_decimals!(60usize, 49usize, 109usize, 11usize); +add_sub_const_decimals!(60usize, 48usize, 108usize, 12usize); +add_sub_const_decimals!(60usize, 47usize, 107usize, 13usize); +add_sub_const_decimals!(60usize, 46usize, 106usize, 14usize); +add_sub_const_decimals!(60usize, 45usize, 105usize, 15usize); +add_sub_const_decimals!(60usize, 44usize, 104usize, 16usize); +add_sub_const_decimals!(60usize, 43usize, 103usize, 17usize); +add_sub_const_decimals!(60usize, 42usize, 102usize, 18usize); +add_sub_const_decimals!(60usize, 41usize, 101usize, 19usize); +add_sub_const_decimals!(60usize, 40usize, 100usize, 20usize); +add_sub_const_decimals!(60usize, 39usize, 99usize, 21usize); +add_sub_const_decimals!(60usize, 38usize, 98usize, 22usize); +add_sub_const_decimals!(60usize, 37usize, 97usize, 23usize); +add_sub_const_decimals!(60usize, 36usize, 96usize, 24usize); +add_sub_const_decimals!(60usize, 35usize, 95usize, 25usize); +add_sub_const_decimals!(60usize, 34usize, 94usize, 26usize); +add_sub_const_decimals!(60usize, 33usize, 93usize, 27usize); +add_sub_const_decimals!(60usize, 32usize, 92usize, 28usize); +add_sub_const_decimals!(60usize, 31usize, 91usize, 29usize); +add_sub_const_decimals!(60usize, 30usize, 90usize, 30usize); +add_sub_const_decimals!(60usize, 29usize, 89usize, 31usize); +add_sub_const_decimals!(60usize, 28usize, 88usize, 32usize); +add_sub_const_decimals!(60usize, 27usize, 87usize, 33usize); +add_sub_const_decimals!(60usize, 26usize, 86usize, 34usize); +add_sub_const_decimals!(60usize, 25usize, 85usize, 35usize); +add_sub_const_decimals!(60usize, 24usize, 84usize, 36usize); +add_sub_const_decimals!(60usize, 23usize, 83usize, 37usize); +add_sub_const_decimals!(60usize, 22usize, 82usize, 38usize); +add_sub_const_decimals!(60usize, 21usize, 81usize, 39usize); +add_sub_const_decimals!(60usize, 20usize, 80usize, 40usize); +add_sub_const_decimals!(60usize, 19usize, 79usize, 41usize); +add_sub_const_decimals!(60usize, 18usize, 78usize, 42usize); +add_sub_const_decimals!(60usize, 17usize, 77usize, 43usize); +add_sub_const_decimals!(60usize, 16usize, 76usize, 44usize); +add_sub_const_decimals!(60usize, 15usize, 75usize, 45usize); +add_sub_const_decimals!(60usize, 14usize, 74usize, 46usize); +add_sub_const_decimals!(60usize, 13usize, 73usize, 47usize); +add_sub_const_decimals!(60usize, 12usize, 72usize, 48usize); +add_sub_const_decimals!(60usize, 11usize, 71usize, 49usize); +add_sub_const_decimals!(60usize, 10usize, 70usize, 50usize); +add_sub_const_decimals!(60usize, 9usize, 69usize, 51usize); +add_sub_const_decimals!(60usize, 8usize, 68usize, 52usize); +add_sub_const_decimals!(60usize, 7usize, 67usize, 53usize); +add_sub_const_decimals!(60usize, 6usize, 66usize, 54usize); +add_sub_const_decimals!(60usize, 5usize, 65usize, 55usize); +add_sub_const_decimals!(60usize, 4usize, 64usize, 56usize); +add_sub_const_decimals!(60usize, 3usize, 63usize, 57usize); +add_sub_const_decimals!(60usize, 2usize, 62usize, 58usize); +add_sub_const_decimals!(60usize, 1usize, 61usize, 59usize); +add_sub_const_decimals!(60usize, 0usize, 60usize, 60usize); +add_sub_const_decimals!(59usize, 64usize, 123usize, 0usize); +add_sub_const_decimals!(59usize, 63usize, 122usize, 0usize); +add_sub_const_decimals!(59usize, 62usize, 121usize, 0usize); +add_sub_const_decimals!(59usize, 61usize, 120usize, 0usize); +add_sub_const_decimals!(59usize, 60usize, 119usize, 0usize); +add_sub_const_decimals!(59usize, 59usize, 118usize, 0usize); +add_sub_const_decimals!(59usize, 58usize, 117usize, 1usize); +add_sub_const_decimals!(59usize, 57usize, 116usize, 2usize); +add_sub_const_decimals!(59usize, 56usize, 115usize, 3usize); +add_sub_const_decimals!(59usize, 55usize, 114usize, 4usize); +add_sub_const_decimals!(59usize, 54usize, 113usize, 5usize); +add_sub_const_decimals!(59usize, 53usize, 112usize, 6usize); +add_sub_const_decimals!(59usize, 52usize, 111usize, 7usize); +add_sub_const_decimals!(59usize, 51usize, 110usize, 8usize); +add_sub_const_decimals!(59usize, 50usize, 109usize, 9usize); +add_sub_const_decimals!(59usize, 49usize, 108usize, 10usize); +add_sub_const_decimals!(59usize, 48usize, 107usize, 11usize); +add_sub_const_decimals!(59usize, 47usize, 106usize, 12usize); +add_sub_const_decimals!(59usize, 46usize, 105usize, 13usize); +add_sub_const_decimals!(59usize, 45usize, 104usize, 14usize); +add_sub_const_decimals!(59usize, 44usize, 103usize, 15usize); +add_sub_const_decimals!(59usize, 43usize, 102usize, 16usize); +add_sub_const_decimals!(59usize, 42usize, 101usize, 17usize); +add_sub_const_decimals!(59usize, 41usize, 100usize, 18usize); +add_sub_const_decimals!(59usize, 40usize, 99usize, 19usize); +add_sub_const_decimals!(59usize, 39usize, 98usize, 20usize); +add_sub_const_decimals!(59usize, 38usize, 97usize, 21usize); +add_sub_const_decimals!(59usize, 37usize, 96usize, 22usize); +add_sub_const_decimals!(59usize, 36usize, 95usize, 23usize); +add_sub_const_decimals!(59usize, 35usize, 94usize, 24usize); +add_sub_const_decimals!(59usize, 34usize, 93usize, 25usize); +add_sub_const_decimals!(59usize, 33usize, 92usize, 26usize); +add_sub_const_decimals!(59usize, 32usize, 91usize, 27usize); +add_sub_const_decimals!(59usize, 31usize, 90usize, 28usize); +add_sub_const_decimals!(59usize, 30usize, 89usize, 29usize); +add_sub_const_decimals!(59usize, 29usize, 88usize, 30usize); +add_sub_const_decimals!(59usize, 28usize, 87usize, 31usize); +add_sub_const_decimals!(59usize, 27usize, 86usize, 32usize); +add_sub_const_decimals!(59usize, 26usize, 85usize, 33usize); +add_sub_const_decimals!(59usize, 25usize, 84usize, 34usize); +add_sub_const_decimals!(59usize, 24usize, 83usize, 35usize); +add_sub_const_decimals!(59usize, 23usize, 82usize, 36usize); +add_sub_const_decimals!(59usize, 22usize, 81usize, 37usize); +add_sub_const_decimals!(59usize, 21usize, 80usize, 38usize); +add_sub_const_decimals!(59usize, 20usize, 79usize, 39usize); +add_sub_const_decimals!(59usize, 19usize, 78usize, 40usize); +add_sub_const_decimals!(59usize, 18usize, 77usize, 41usize); +add_sub_const_decimals!(59usize, 17usize, 76usize, 42usize); +add_sub_const_decimals!(59usize, 16usize, 75usize, 43usize); +add_sub_const_decimals!(59usize, 15usize, 74usize, 44usize); +add_sub_const_decimals!(59usize, 14usize, 73usize, 45usize); +add_sub_const_decimals!(59usize, 13usize, 72usize, 46usize); +add_sub_const_decimals!(59usize, 12usize, 71usize, 47usize); +add_sub_const_decimals!(59usize, 11usize, 70usize, 48usize); +add_sub_const_decimals!(59usize, 10usize, 69usize, 49usize); +add_sub_const_decimals!(59usize, 9usize, 68usize, 50usize); +add_sub_const_decimals!(59usize, 8usize, 67usize, 51usize); +add_sub_const_decimals!(59usize, 7usize, 66usize, 52usize); +add_sub_const_decimals!(59usize, 6usize, 65usize, 53usize); +add_sub_const_decimals!(59usize, 5usize, 64usize, 54usize); +add_sub_const_decimals!(59usize, 4usize, 63usize, 55usize); +add_sub_const_decimals!(59usize, 3usize, 62usize, 56usize); +add_sub_const_decimals!(59usize, 2usize, 61usize, 57usize); +add_sub_const_decimals!(59usize, 1usize, 60usize, 58usize); +add_sub_const_decimals!(59usize, 0usize, 59usize, 59usize); +add_sub_const_decimals!(58usize, 64usize, 122usize, 0usize); +add_sub_const_decimals!(58usize, 63usize, 121usize, 0usize); +add_sub_const_decimals!(58usize, 62usize, 120usize, 0usize); +add_sub_const_decimals!(58usize, 61usize, 119usize, 0usize); +add_sub_const_decimals!(58usize, 60usize, 118usize, 0usize); +add_sub_const_decimals!(58usize, 59usize, 117usize, 0usize); +add_sub_const_decimals!(58usize, 58usize, 116usize, 0usize); +add_sub_const_decimals!(58usize, 57usize, 115usize, 1usize); +add_sub_const_decimals!(58usize, 56usize, 114usize, 2usize); +add_sub_const_decimals!(58usize, 55usize, 113usize, 3usize); +add_sub_const_decimals!(58usize, 54usize, 112usize, 4usize); +add_sub_const_decimals!(58usize, 53usize, 111usize, 5usize); +add_sub_const_decimals!(58usize, 52usize, 110usize, 6usize); +add_sub_const_decimals!(58usize, 51usize, 109usize, 7usize); +add_sub_const_decimals!(58usize, 50usize, 108usize, 8usize); +add_sub_const_decimals!(58usize, 49usize, 107usize, 9usize); +add_sub_const_decimals!(58usize, 48usize, 106usize, 10usize); +add_sub_const_decimals!(58usize, 47usize, 105usize, 11usize); +add_sub_const_decimals!(58usize, 46usize, 104usize, 12usize); +add_sub_const_decimals!(58usize, 45usize, 103usize, 13usize); +add_sub_const_decimals!(58usize, 44usize, 102usize, 14usize); +add_sub_const_decimals!(58usize, 43usize, 101usize, 15usize); +add_sub_const_decimals!(58usize, 42usize, 100usize, 16usize); +add_sub_const_decimals!(58usize, 41usize, 99usize, 17usize); +add_sub_const_decimals!(58usize, 40usize, 98usize, 18usize); +add_sub_const_decimals!(58usize, 39usize, 97usize, 19usize); +add_sub_const_decimals!(58usize, 38usize, 96usize, 20usize); +add_sub_const_decimals!(58usize, 37usize, 95usize, 21usize); +add_sub_const_decimals!(58usize, 36usize, 94usize, 22usize); +add_sub_const_decimals!(58usize, 35usize, 93usize, 23usize); +add_sub_const_decimals!(58usize, 34usize, 92usize, 24usize); +add_sub_const_decimals!(58usize, 33usize, 91usize, 25usize); +add_sub_const_decimals!(58usize, 32usize, 90usize, 26usize); +add_sub_const_decimals!(58usize, 31usize, 89usize, 27usize); +add_sub_const_decimals!(58usize, 30usize, 88usize, 28usize); +add_sub_const_decimals!(58usize, 29usize, 87usize, 29usize); +add_sub_const_decimals!(58usize, 28usize, 86usize, 30usize); +add_sub_const_decimals!(58usize, 27usize, 85usize, 31usize); +add_sub_const_decimals!(58usize, 26usize, 84usize, 32usize); +add_sub_const_decimals!(58usize, 25usize, 83usize, 33usize); +add_sub_const_decimals!(58usize, 24usize, 82usize, 34usize); +add_sub_const_decimals!(58usize, 23usize, 81usize, 35usize); +add_sub_const_decimals!(58usize, 22usize, 80usize, 36usize); +add_sub_const_decimals!(58usize, 21usize, 79usize, 37usize); +add_sub_const_decimals!(58usize, 20usize, 78usize, 38usize); +add_sub_const_decimals!(58usize, 19usize, 77usize, 39usize); +add_sub_const_decimals!(58usize, 18usize, 76usize, 40usize); +add_sub_const_decimals!(58usize, 17usize, 75usize, 41usize); +add_sub_const_decimals!(58usize, 16usize, 74usize, 42usize); +add_sub_const_decimals!(58usize, 15usize, 73usize, 43usize); +add_sub_const_decimals!(58usize, 14usize, 72usize, 44usize); +add_sub_const_decimals!(58usize, 13usize, 71usize, 45usize); +add_sub_const_decimals!(58usize, 12usize, 70usize, 46usize); +add_sub_const_decimals!(58usize, 11usize, 69usize, 47usize); +add_sub_const_decimals!(58usize, 10usize, 68usize, 48usize); +add_sub_const_decimals!(58usize, 9usize, 67usize, 49usize); +add_sub_const_decimals!(58usize, 8usize, 66usize, 50usize); +add_sub_const_decimals!(58usize, 7usize, 65usize, 51usize); +add_sub_const_decimals!(58usize, 6usize, 64usize, 52usize); +add_sub_const_decimals!(58usize, 5usize, 63usize, 53usize); +add_sub_const_decimals!(58usize, 4usize, 62usize, 54usize); +add_sub_const_decimals!(58usize, 3usize, 61usize, 55usize); +add_sub_const_decimals!(58usize, 2usize, 60usize, 56usize); +add_sub_const_decimals!(58usize, 1usize, 59usize, 57usize); +add_sub_const_decimals!(58usize, 0usize, 58usize, 58usize); +add_sub_const_decimals!(57usize, 64usize, 121usize, 0usize); +add_sub_const_decimals!(57usize, 63usize, 120usize, 0usize); +add_sub_const_decimals!(57usize, 62usize, 119usize, 0usize); +add_sub_const_decimals!(57usize, 61usize, 118usize, 0usize); +add_sub_const_decimals!(57usize, 60usize, 117usize, 0usize); +add_sub_const_decimals!(57usize, 59usize, 116usize, 0usize); +add_sub_const_decimals!(57usize, 58usize, 115usize, 0usize); +add_sub_const_decimals!(57usize, 57usize, 114usize, 0usize); +add_sub_const_decimals!(57usize, 56usize, 113usize, 1usize); +add_sub_const_decimals!(57usize, 55usize, 112usize, 2usize); +add_sub_const_decimals!(57usize, 54usize, 111usize, 3usize); +add_sub_const_decimals!(57usize, 53usize, 110usize, 4usize); +add_sub_const_decimals!(57usize, 52usize, 109usize, 5usize); +add_sub_const_decimals!(57usize, 51usize, 108usize, 6usize); +add_sub_const_decimals!(57usize, 50usize, 107usize, 7usize); +add_sub_const_decimals!(57usize, 49usize, 106usize, 8usize); +add_sub_const_decimals!(57usize, 48usize, 105usize, 9usize); +add_sub_const_decimals!(57usize, 47usize, 104usize, 10usize); +add_sub_const_decimals!(57usize, 46usize, 103usize, 11usize); +add_sub_const_decimals!(57usize, 45usize, 102usize, 12usize); +add_sub_const_decimals!(57usize, 44usize, 101usize, 13usize); +add_sub_const_decimals!(57usize, 43usize, 100usize, 14usize); +add_sub_const_decimals!(57usize, 42usize, 99usize, 15usize); +add_sub_const_decimals!(57usize, 41usize, 98usize, 16usize); +add_sub_const_decimals!(57usize, 40usize, 97usize, 17usize); +add_sub_const_decimals!(57usize, 39usize, 96usize, 18usize); +add_sub_const_decimals!(57usize, 38usize, 95usize, 19usize); +add_sub_const_decimals!(57usize, 37usize, 94usize, 20usize); +add_sub_const_decimals!(57usize, 36usize, 93usize, 21usize); +add_sub_const_decimals!(57usize, 35usize, 92usize, 22usize); +add_sub_const_decimals!(57usize, 34usize, 91usize, 23usize); +add_sub_const_decimals!(57usize, 33usize, 90usize, 24usize); +add_sub_const_decimals!(57usize, 32usize, 89usize, 25usize); +add_sub_const_decimals!(57usize, 31usize, 88usize, 26usize); +add_sub_const_decimals!(57usize, 30usize, 87usize, 27usize); +add_sub_const_decimals!(57usize, 29usize, 86usize, 28usize); +add_sub_const_decimals!(57usize, 28usize, 85usize, 29usize); +add_sub_const_decimals!(57usize, 27usize, 84usize, 30usize); +add_sub_const_decimals!(57usize, 26usize, 83usize, 31usize); +add_sub_const_decimals!(57usize, 25usize, 82usize, 32usize); +add_sub_const_decimals!(57usize, 24usize, 81usize, 33usize); +add_sub_const_decimals!(57usize, 23usize, 80usize, 34usize); +add_sub_const_decimals!(57usize, 22usize, 79usize, 35usize); +add_sub_const_decimals!(57usize, 21usize, 78usize, 36usize); +add_sub_const_decimals!(57usize, 20usize, 77usize, 37usize); +add_sub_const_decimals!(57usize, 19usize, 76usize, 38usize); +add_sub_const_decimals!(57usize, 18usize, 75usize, 39usize); +add_sub_const_decimals!(57usize, 17usize, 74usize, 40usize); +add_sub_const_decimals!(57usize, 16usize, 73usize, 41usize); +add_sub_const_decimals!(57usize, 15usize, 72usize, 42usize); +add_sub_const_decimals!(57usize, 14usize, 71usize, 43usize); +add_sub_const_decimals!(57usize, 13usize, 70usize, 44usize); +add_sub_const_decimals!(57usize, 12usize, 69usize, 45usize); +add_sub_const_decimals!(57usize, 11usize, 68usize, 46usize); +add_sub_const_decimals!(57usize, 10usize, 67usize, 47usize); +add_sub_const_decimals!(57usize, 9usize, 66usize, 48usize); +add_sub_const_decimals!(57usize, 8usize, 65usize, 49usize); +add_sub_const_decimals!(57usize, 7usize, 64usize, 50usize); +add_sub_const_decimals!(57usize, 6usize, 63usize, 51usize); +add_sub_const_decimals!(57usize, 5usize, 62usize, 52usize); +add_sub_const_decimals!(57usize, 4usize, 61usize, 53usize); +add_sub_const_decimals!(57usize, 3usize, 60usize, 54usize); +add_sub_const_decimals!(57usize, 2usize, 59usize, 55usize); +add_sub_const_decimals!(57usize, 1usize, 58usize, 56usize); +add_sub_const_decimals!(57usize, 0usize, 57usize, 57usize); +add_sub_const_decimals!(56usize, 64usize, 120usize, 0usize); +add_sub_const_decimals!(56usize, 63usize, 119usize, 0usize); +add_sub_const_decimals!(56usize, 62usize, 118usize, 0usize); +add_sub_const_decimals!(56usize, 61usize, 117usize, 0usize); +add_sub_const_decimals!(56usize, 60usize, 116usize, 0usize); +add_sub_const_decimals!(56usize, 59usize, 115usize, 0usize); +add_sub_const_decimals!(56usize, 58usize, 114usize, 0usize); +add_sub_const_decimals!(56usize, 57usize, 113usize, 0usize); +add_sub_const_decimals!(56usize, 56usize, 112usize, 0usize); +add_sub_const_decimals!(56usize, 55usize, 111usize, 1usize); +add_sub_const_decimals!(56usize, 54usize, 110usize, 2usize); +add_sub_const_decimals!(56usize, 53usize, 109usize, 3usize); +add_sub_const_decimals!(56usize, 52usize, 108usize, 4usize); +add_sub_const_decimals!(56usize, 51usize, 107usize, 5usize); +add_sub_const_decimals!(56usize, 50usize, 106usize, 6usize); +add_sub_const_decimals!(56usize, 49usize, 105usize, 7usize); +add_sub_const_decimals!(56usize, 48usize, 104usize, 8usize); +add_sub_const_decimals!(56usize, 47usize, 103usize, 9usize); +add_sub_const_decimals!(56usize, 46usize, 102usize, 10usize); +add_sub_const_decimals!(56usize, 45usize, 101usize, 11usize); +add_sub_const_decimals!(56usize, 44usize, 100usize, 12usize); +add_sub_const_decimals!(56usize, 43usize, 99usize, 13usize); +add_sub_const_decimals!(56usize, 42usize, 98usize, 14usize); +add_sub_const_decimals!(56usize, 41usize, 97usize, 15usize); +add_sub_const_decimals!(56usize, 40usize, 96usize, 16usize); +add_sub_const_decimals!(56usize, 39usize, 95usize, 17usize); +add_sub_const_decimals!(56usize, 38usize, 94usize, 18usize); +add_sub_const_decimals!(56usize, 37usize, 93usize, 19usize); +add_sub_const_decimals!(56usize, 36usize, 92usize, 20usize); +add_sub_const_decimals!(56usize, 35usize, 91usize, 21usize); +add_sub_const_decimals!(56usize, 34usize, 90usize, 22usize); +add_sub_const_decimals!(56usize, 33usize, 89usize, 23usize); +add_sub_const_decimals!(56usize, 32usize, 88usize, 24usize); +add_sub_const_decimals!(56usize, 31usize, 87usize, 25usize); +add_sub_const_decimals!(56usize, 30usize, 86usize, 26usize); +add_sub_const_decimals!(56usize, 29usize, 85usize, 27usize); +add_sub_const_decimals!(56usize, 28usize, 84usize, 28usize); +add_sub_const_decimals!(56usize, 27usize, 83usize, 29usize); +add_sub_const_decimals!(56usize, 26usize, 82usize, 30usize); +add_sub_const_decimals!(56usize, 25usize, 81usize, 31usize); +add_sub_const_decimals!(56usize, 24usize, 80usize, 32usize); +add_sub_const_decimals!(56usize, 23usize, 79usize, 33usize); +add_sub_const_decimals!(56usize, 22usize, 78usize, 34usize); +add_sub_const_decimals!(56usize, 21usize, 77usize, 35usize); +add_sub_const_decimals!(56usize, 20usize, 76usize, 36usize); +add_sub_const_decimals!(56usize, 19usize, 75usize, 37usize); +add_sub_const_decimals!(56usize, 18usize, 74usize, 38usize); +add_sub_const_decimals!(56usize, 17usize, 73usize, 39usize); +add_sub_const_decimals!(56usize, 16usize, 72usize, 40usize); +add_sub_const_decimals!(56usize, 15usize, 71usize, 41usize); +add_sub_const_decimals!(56usize, 14usize, 70usize, 42usize); +add_sub_const_decimals!(56usize, 13usize, 69usize, 43usize); +add_sub_const_decimals!(56usize, 12usize, 68usize, 44usize); +add_sub_const_decimals!(56usize, 11usize, 67usize, 45usize); +add_sub_const_decimals!(56usize, 10usize, 66usize, 46usize); +add_sub_const_decimals!(56usize, 9usize, 65usize, 47usize); +add_sub_const_decimals!(56usize, 8usize, 64usize, 48usize); +add_sub_const_decimals!(56usize, 7usize, 63usize, 49usize); +add_sub_const_decimals!(56usize, 6usize, 62usize, 50usize); +add_sub_const_decimals!(56usize, 5usize, 61usize, 51usize); +add_sub_const_decimals!(56usize, 4usize, 60usize, 52usize); +add_sub_const_decimals!(56usize, 3usize, 59usize, 53usize); +add_sub_const_decimals!(56usize, 2usize, 58usize, 54usize); +add_sub_const_decimals!(56usize, 1usize, 57usize, 55usize); +add_sub_const_decimals!(56usize, 0usize, 56usize, 56usize); +add_sub_const_decimals!(55usize, 64usize, 119usize, 0usize); +add_sub_const_decimals!(55usize, 63usize, 118usize, 0usize); +add_sub_const_decimals!(55usize, 62usize, 117usize, 0usize); +add_sub_const_decimals!(55usize, 61usize, 116usize, 0usize); +add_sub_const_decimals!(55usize, 60usize, 115usize, 0usize); +add_sub_const_decimals!(55usize, 59usize, 114usize, 0usize); +add_sub_const_decimals!(55usize, 58usize, 113usize, 0usize); +add_sub_const_decimals!(55usize, 57usize, 112usize, 0usize); +add_sub_const_decimals!(55usize, 56usize, 111usize, 0usize); +add_sub_const_decimals!(55usize, 55usize, 110usize, 0usize); +add_sub_const_decimals!(55usize, 54usize, 109usize, 1usize); +add_sub_const_decimals!(55usize, 53usize, 108usize, 2usize); +add_sub_const_decimals!(55usize, 52usize, 107usize, 3usize); +add_sub_const_decimals!(55usize, 51usize, 106usize, 4usize); +add_sub_const_decimals!(55usize, 50usize, 105usize, 5usize); +add_sub_const_decimals!(55usize, 49usize, 104usize, 6usize); +add_sub_const_decimals!(55usize, 48usize, 103usize, 7usize); +add_sub_const_decimals!(55usize, 47usize, 102usize, 8usize); +add_sub_const_decimals!(55usize, 46usize, 101usize, 9usize); +add_sub_const_decimals!(55usize, 45usize, 100usize, 10usize); +add_sub_const_decimals!(55usize, 44usize, 99usize, 11usize); +add_sub_const_decimals!(55usize, 43usize, 98usize, 12usize); +add_sub_const_decimals!(55usize, 42usize, 97usize, 13usize); +add_sub_const_decimals!(55usize, 41usize, 96usize, 14usize); +add_sub_const_decimals!(55usize, 40usize, 95usize, 15usize); +add_sub_const_decimals!(55usize, 39usize, 94usize, 16usize); +add_sub_const_decimals!(55usize, 38usize, 93usize, 17usize); +add_sub_const_decimals!(55usize, 37usize, 92usize, 18usize); +add_sub_const_decimals!(55usize, 36usize, 91usize, 19usize); +add_sub_const_decimals!(55usize, 35usize, 90usize, 20usize); +add_sub_const_decimals!(55usize, 34usize, 89usize, 21usize); +add_sub_const_decimals!(55usize, 33usize, 88usize, 22usize); +add_sub_const_decimals!(55usize, 32usize, 87usize, 23usize); +add_sub_const_decimals!(55usize, 31usize, 86usize, 24usize); +add_sub_const_decimals!(55usize, 30usize, 85usize, 25usize); +add_sub_const_decimals!(55usize, 29usize, 84usize, 26usize); +add_sub_const_decimals!(55usize, 28usize, 83usize, 27usize); +add_sub_const_decimals!(55usize, 27usize, 82usize, 28usize); +add_sub_const_decimals!(55usize, 26usize, 81usize, 29usize); +add_sub_const_decimals!(55usize, 25usize, 80usize, 30usize); +add_sub_const_decimals!(55usize, 24usize, 79usize, 31usize); +add_sub_const_decimals!(55usize, 23usize, 78usize, 32usize); +add_sub_const_decimals!(55usize, 22usize, 77usize, 33usize); +add_sub_const_decimals!(55usize, 21usize, 76usize, 34usize); +add_sub_const_decimals!(55usize, 20usize, 75usize, 35usize); +add_sub_const_decimals!(55usize, 19usize, 74usize, 36usize); +add_sub_const_decimals!(55usize, 18usize, 73usize, 37usize); +add_sub_const_decimals!(55usize, 17usize, 72usize, 38usize); +add_sub_const_decimals!(55usize, 16usize, 71usize, 39usize); +add_sub_const_decimals!(55usize, 15usize, 70usize, 40usize); +add_sub_const_decimals!(55usize, 14usize, 69usize, 41usize); +add_sub_const_decimals!(55usize, 13usize, 68usize, 42usize); +add_sub_const_decimals!(55usize, 12usize, 67usize, 43usize); +add_sub_const_decimals!(55usize, 11usize, 66usize, 44usize); +add_sub_const_decimals!(55usize, 10usize, 65usize, 45usize); +add_sub_const_decimals!(55usize, 9usize, 64usize, 46usize); +add_sub_const_decimals!(55usize, 8usize, 63usize, 47usize); +add_sub_const_decimals!(55usize, 7usize, 62usize, 48usize); +add_sub_const_decimals!(55usize, 6usize, 61usize, 49usize); +add_sub_const_decimals!(55usize, 5usize, 60usize, 50usize); +add_sub_const_decimals!(55usize, 4usize, 59usize, 51usize); +add_sub_const_decimals!(55usize, 3usize, 58usize, 52usize); +add_sub_const_decimals!(55usize, 2usize, 57usize, 53usize); +add_sub_const_decimals!(55usize, 1usize, 56usize, 54usize); +add_sub_const_decimals!(55usize, 0usize, 55usize, 55usize); +add_sub_const_decimals!(54usize, 64usize, 118usize, 0usize); +add_sub_const_decimals!(54usize, 63usize, 117usize, 0usize); +add_sub_const_decimals!(54usize, 62usize, 116usize, 0usize); +add_sub_const_decimals!(54usize, 61usize, 115usize, 0usize); +add_sub_const_decimals!(54usize, 60usize, 114usize, 0usize); +add_sub_const_decimals!(54usize, 59usize, 113usize, 0usize); +add_sub_const_decimals!(54usize, 58usize, 112usize, 0usize); +add_sub_const_decimals!(54usize, 57usize, 111usize, 0usize); +add_sub_const_decimals!(54usize, 56usize, 110usize, 0usize); +add_sub_const_decimals!(54usize, 55usize, 109usize, 0usize); +add_sub_const_decimals!(54usize, 54usize, 108usize, 0usize); +add_sub_const_decimals!(54usize, 53usize, 107usize, 1usize); +add_sub_const_decimals!(54usize, 52usize, 106usize, 2usize); +add_sub_const_decimals!(54usize, 51usize, 105usize, 3usize); +add_sub_const_decimals!(54usize, 50usize, 104usize, 4usize); +add_sub_const_decimals!(54usize, 49usize, 103usize, 5usize); +add_sub_const_decimals!(54usize, 48usize, 102usize, 6usize); +add_sub_const_decimals!(54usize, 47usize, 101usize, 7usize); +add_sub_const_decimals!(54usize, 46usize, 100usize, 8usize); +add_sub_const_decimals!(54usize, 45usize, 99usize, 9usize); +add_sub_const_decimals!(54usize, 44usize, 98usize, 10usize); +add_sub_const_decimals!(54usize, 43usize, 97usize, 11usize); +add_sub_const_decimals!(54usize, 42usize, 96usize, 12usize); +add_sub_const_decimals!(54usize, 41usize, 95usize, 13usize); +add_sub_const_decimals!(54usize, 40usize, 94usize, 14usize); +add_sub_const_decimals!(54usize, 39usize, 93usize, 15usize); +add_sub_const_decimals!(54usize, 38usize, 92usize, 16usize); +add_sub_const_decimals!(54usize, 37usize, 91usize, 17usize); +add_sub_const_decimals!(54usize, 36usize, 90usize, 18usize); +add_sub_const_decimals!(54usize, 35usize, 89usize, 19usize); +add_sub_const_decimals!(54usize, 34usize, 88usize, 20usize); +add_sub_const_decimals!(54usize, 33usize, 87usize, 21usize); +add_sub_const_decimals!(54usize, 32usize, 86usize, 22usize); +add_sub_const_decimals!(54usize, 31usize, 85usize, 23usize); +add_sub_const_decimals!(54usize, 30usize, 84usize, 24usize); +add_sub_const_decimals!(54usize, 29usize, 83usize, 25usize); +add_sub_const_decimals!(54usize, 28usize, 82usize, 26usize); +add_sub_const_decimals!(54usize, 27usize, 81usize, 27usize); +add_sub_const_decimals!(54usize, 26usize, 80usize, 28usize); +add_sub_const_decimals!(54usize, 25usize, 79usize, 29usize); +add_sub_const_decimals!(54usize, 24usize, 78usize, 30usize); +add_sub_const_decimals!(54usize, 23usize, 77usize, 31usize); +add_sub_const_decimals!(54usize, 22usize, 76usize, 32usize); +add_sub_const_decimals!(54usize, 21usize, 75usize, 33usize); +add_sub_const_decimals!(54usize, 20usize, 74usize, 34usize); +add_sub_const_decimals!(54usize, 19usize, 73usize, 35usize); +add_sub_const_decimals!(54usize, 18usize, 72usize, 36usize); +add_sub_const_decimals!(54usize, 17usize, 71usize, 37usize); +add_sub_const_decimals!(54usize, 16usize, 70usize, 38usize); +add_sub_const_decimals!(54usize, 15usize, 69usize, 39usize); +add_sub_const_decimals!(54usize, 14usize, 68usize, 40usize); +add_sub_const_decimals!(54usize, 13usize, 67usize, 41usize); +add_sub_const_decimals!(54usize, 12usize, 66usize, 42usize); +add_sub_const_decimals!(54usize, 11usize, 65usize, 43usize); +add_sub_const_decimals!(54usize, 10usize, 64usize, 44usize); +add_sub_const_decimals!(54usize, 9usize, 63usize, 45usize); +add_sub_const_decimals!(54usize, 8usize, 62usize, 46usize); +add_sub_const_decimals!(54usize, 7usize, 61usize, 47usize); +add_sub_const_decimals!(54usize, 6usize, 60usize, 48usize); +add_sub_const_decimals!(54usize, 5usize, 59usize, 49usize); +add_sub_const_decimals!(54usize, 4usize, 58usize, 50usize); +add_sub_const_decimals!(54usize, 3usize, 57usize, 51usize); +add_sub_const_decimals!(54usize, 2usize, 56usize, 52usize); +add_sub_const_decimals!(54usize, 1usize, 55usize, 53usize); +add_sub_const_decimals!(54usize, 0usize, 54usize, 54usize); +add_sub_const_decimals!(53usize, 64usize, 117usize, 0usize); +add_sub_const_decimals!(53usize, 63usize, 116usize, 0usize); +add_sub_const_decimals!(53usize, 62usize, 115usize, 0usize); +add_sub_const_decimals!(53usize, 61usize, 114usize, 0usize); +add_sub_const_decimals!(53usize, 60usize, 113usize, 0usize); +add_sub_const_decimals!(53usize, 59usize, 112usize, 0usize); +add_sub_const_decimals!(53usize, 58usize, 111usize, 0usize); +add_sub_const_decimals!(53usize, 57usize, 110usize, 0usize); +add_sub_const_decimals!(53usize, 56usize, 109usize, 0usize); +add_sub_const_decimals!(53usize, 55usize, 108usize, 0usize); +add_sub_const_decimals!(53usize, 54usize, 107usize, 0usize); +add_sub_const_decimals!(53usize, 53usize, 106usize, 0usize); +add_sub_const_decimals!(53usize, 52usize, 105usize, 1usize); +add_sub_const_decimals!(53usize, 51usize, 104usize, 2usize); +add_sub_const_decimals!(53usize, 50usize, 103usize, 3usize); +add_sub_const_decimals!(53usize, 49usize, 102usize, 4usize); +add_sub_const_decimals!(53usize, 48usize, 101usize, 5usize); +add_sub_const_decimals!(53usize, 47usize, 100usize, 6usize); +add_sub_const_decimals!(53usize, 46usize, 99usize, 7usize); +add_sub_const_decimals!(53usize, 45usize, 98usize, 8usize); +add_sub_const_decimals!(53usize, 44usize, 97usize, 9usize); +add_sub_const_decimals!(53usize, 43usize, 96usize, 10usize); +add_sub_const_decimals!(53usize, 42usize, 95usize, 11usize); +add_sub_const_decimals!(53usize, 41usize, 94usize, 12usize); +add_sub_const_decimals!(53usize, 40usize, 93usize, 13usize); +add_sub_const_decimals!(53usize, 39usize, 92usize, 14usize); +add_sub_const_decimals!(53usize, 38usize, 91usize, 15usize); +add_sub_const_decimals!(53usize, 37usize, 90usize, 16usize); +add_sub_const_decimals!(53usize, 36usize, 89usize, 17usize); +add_sub_const_decimals!(53usize, 35usize, 88usize, 18usize); +add_sub_const_decimals!(53usize, 34usize, 87usize, 19usize); +add_sub_const_decimals!(53usize, 33usize, 86usize, 20usize); +add_sub_const_decimals!(53usize, 32usize, 85usize, 21usize); +add_sub_const_decimals!(53usize, 31usize, 84usize, 22usize); +add_sub_const_decimals!(53usize, 30usize, 83usize, 23usize); +add_sub_const_decimals!(53usize, 29usize, 82usize, 24usize); +add_sub_const_decimals!(53usize, 28usize, 81usize, 25usize); +add_sub_const_decimals!(53usize, 27usize, 80usize, 26usize); +add_sub_const_decimals!(53usize, 26usize, 79usize, 27usize); +add_sub_const_decimals!(53usize, 25usize, 78usize, 28usize); +add_sub_const_decimals!(53usize, 24usize, 77usize, 29usize); +add_sub_const_decimals!(53usize, 23usize, 76usize, 30usize); +add_sub_const_decimals!(53usize, 22usize, 75usize, 31usize); +add_sub_const_decimals!(53usize, 21usize, 74usize, 32usize); +add_sub_const_decimals!(53usize, 20usize, 73usize, 33usize); +add_sub_const_decimals!(53usize, 19usize, 72usize, 34usize); +add_sub_const_decimals!(53usize, 18usize, 71usize, 35usize); +add_sub_const_decimals!(53usize, 17usize, 70usize, 36usize); +add_sub_const_decimals!(53usize, 16usize, 69usize, 37usize); +add_sub_const_decimals!(53usize, 15usize, 68usize, 38usize); +add_sub_const_decimals!(53usize, 14usize, 67usize, 39usize); +add_sub_const_decimals!(53usize, 13usize, 66usize, 40usize); +add_sub_const_decimals!(53usize, 12usize, 65usize, 41usize); +add_sub_const_decimals!(53usize, 11usize, 64usize, 42usize); +add_sub_const_decimals!(53usize, 10usize, 63usize, 43usize); +add_sub_const_decimals!(53usize, 9usize, 62usize, 44usize); +add_sub_const_decimals!(53usize, 8usize, 61usize, 45usize); +add_sub_const_decimals!(53usize, 7usize, 60usize, 46usize); +add_sub_const_decimals!(53usize, 6usize, 59usize, 47usize); +add_sub_const_decimals!(53usize, 5usize, 58usize, 48usize); +add_sub_const_decimals!(53usize, 4usize, 57usize, 49usize); +add_sub_const_decimals!(53usize, 3usize, 56usize, 50usize); +add_sub_const_decimals!(53usize, 2usize, 55usize, 51usize); +add_sub_const_decimals!(53usize, 1usize, 54usize, 52usize); +add_sub_const_decimals!(53usize, 0usize, 53usize, 53usize); +add_sub_const_decimals!(52usize, 64usize, 116usize, 0usize); +add_sub_const_decimals!(52usize, 63usize, 115usize, 0usize); +add_sub_const_decimals!(52usize, 62usize, 114usize, 0usize); +add_sub_const_decimals!(52usize, 61usize, 113usize, 0usize); +add_sub_const_decimals!(52usize, 60usize, 112usize, 0usize); +add_sub_const_decimals!(52usize, 59usize, 111usize, 0usize); +add_sub_const_decimals!(52usize, 58usize, 110usize, 0usize); +add_sub_const_decimals!(52usize, 57usize, 109usize, 0usize); +add_sub_const_decimals!(52usize, 56usize, 108usize, 0usize); +add_sub_const_decimals!(52usize, 55usize, 107usize, 0usize); +add_sub_const_decimals!(52usize, 54usize, 106usize, 0usize); +add_sub_const_decimals!(52usize, 53usize, 105usize, 0usize); +add_sub_const_decimals!(52usize, 52usize, 104usize, 0usize); +add_sub_const_decimals!(52usize, 51usize, 103usize, 1usize); +add_sub_const_decimals!(52usize, 50usize, 102usize, 2usize); +add_sub_const_decimals!(52usize, 49usize, 101usize, 3usize); +add_sub_const_decimals!(52usize, 48usize, 100usize, 4usize); +add_sub_const_decimals!(52usize, 47usize, 99usize, 5usize); +add_sub_const_decimals!(52usize, 46usize, 98usize, 6usize); +add_sub_const_decimals!(52usize, 45usize, 97usize, 7usize); +add_sub_const_decimals!(52usize, 44usize, 96usize, 8usize); +add_sub_const_decimals!(52usize, 43usize, 95usize, 9usize); +add_sub_const_decimals!(52usize, 42usize, 94usize, 10usize); +add_sub_const_decimals!(52usize, 41usize, 93usize, 11usize); +add_sub_const_decimals!(52usize, 40usize, 92usize, 12usize); +add_sub_const_decimals!(52usize, 39usize, 91usize, 13usize); +add_sub_const_decimals!(52usize, 38usize, 90usize, 14usize); +add_sub_const_decimals!(52usize, 37usize, 89usize, 15usize); +add_sub_const_decimals!(52usize, 36usize, 88usize, 16usize); +add_sub_const_decimals!(52usize, 35usize, 87usize, 17usize); +add_sub_const_decimals!(52usize, 34usize, 86usize, 18usize); +add_sub_const_decimals!(52usize, 33usize, 85usize, 19usize); +add_sub_const_decimals!(52usize, 32usize, 84usize, 20usize); +add_sub_const_decimals!(52usize, 31usize, 83usize, 21usize); +add_sub_const_decimals!(52usize, 30usize, 82usize, 22usize); +add_sub_const_decimals!(52usize, 29usize, 81usize, 23usize); +add_sub_const_decimals!(52usize, 28usize, 80usize, 24usize); +add_sub_const_decimals!(52usize, 27usize, 79usize, 25usize); +add_sub_const_decimals!(52usize, 26usize, 78usize, 26usize); +add_sub_const_decimals!(52usize, 25usize, 77usize, 27usize); +add_sub_const_decimals!(52usize, 24usize, 76usize, 28usize); +add_sub_const_decimals!(52usize, 23usize, 75usize, 29usize); +add_sub_const_decimals!(52usize, 22usize, 74usize, 30usize); +add_sub_const_decimals!(52usize, 21usize, 73usize, 31usize); +add_sub_const_decimals!(52usize, 20usize, 72usize, 32usize); +add_sub_const_decimals!(52usize, 19usize, 71usize, 33usize); +add_sub_const_decimals!(52usize, 18usize, 70usize, 34usize); +add_sub_const_decimals!(52usize, 17usize, 69usize, 35usize); +add_sub_const_decimals!(52usize, 16usize, 68usize, 36usize); +add_sub_const_decimals!(52usize, 15usize, 67usize, 37usize); +add_sub_const_decimals!(52usize, 14usize, 66usize, 38usize); +add_sub_const_decimals!(52usize, 13usize, 65usize, 39usize); +add_sub_const_decimals!(52usize, 12usize, 64usize, 40usize); +add_sub_const_decimals!(52usize, 11usize, 63usize, 41usize); +add_sub_const_decimals!(52usize, 10usize, 62usize, 42usize); +add_sub_const_decimals!(52usize, 9usize, 61usize, 43usize); +add_sub_const_decimals!(52usize, 8usize, 60usize, 44usize); +add_sub_const_decimals!(52usize, 7usize, 59usize, 45usize); +add_sub_const_decimals!(52usize, 6usize, 58usize, 46usize); +add_sub_const_decimals!(52usize, 5usize, 57usize, 47usize); +add_sub_const_decimals!(52usize, 4usize, 56usize, 48usize); +add_sub_const_decimals!(52usize, 3usize, 55usize, 49usize); +add_sub_const_decimals!(52usize, 2usize, 54usize, 50usize); +add_sub_const_decimals!(52usize, 1usize, 53usize, 51usize); +add_sub_const_decimals!(52usize, 0usize, 52usize, 52usize); +add_sub_const_decimals!(51usize, 64usize, 115usize, 0usize); +add_sub_const_decimals!(51usize, 63usize, 114usize, 0usize); +add_sub_const_decimals!(51usize, 62usize, 113usize, 0usize); +add_sub_const_decimals!(51usize, 61usize, 112usize, 0usize); +add_sub_const_decimals!(51usize, 60usize, 111usize, 0usize); +add_sub_const_decimals!(51usize, 59usize, 110usize, 0usize); +add_sub_const_decimals!(51usize, 58usize, 109usize, 0usize); +add_sub_const_decimals!(51usize, 57usize, 108usize, 0usize); +add_sub_const_decimals!(51usize, 56usize, 107usize, 0usize); +add_sub_const_decimals!(51usize, 55usize, 106usize, 0usize); +add_sub_const_decimals!(51usize, 54usize, 105usize, 0usize); +add_sub_const_decimals!(51usize, 53usize, 104usize, 0usize); +add_sub_const_decimals!(51usize, 52usize, 103usize, 0usize); +add_sub_const_decimals!(51usize, 51usize, 102usize, 0usize); +add_sub_const_decimals!(51usize, 50usize, 101usize, 1usize); +add_sub_const_decimals!(51usize, 49usize, 100usize, 2usize); +add_sub_const_decimals!(51usize, 48usize, 99usize, 3usize); +add_sub_const_decimals!(51usize, 47usize, 98usize, 4usize); +add_sub_const_decimals!(51usize, 46usize, 97usize, 5usize); +add_sub_const_decimals!(51usize, 45usize, 96usize, 6usize); +add_sub_const_decimals!(51usize, 44usize, 95usize, 7usize); +add_sub_const_decimals!(51usize, 43usize, 94usize, 8usize); +add_sub_const_decimals!(51usize, 42usize, 93usize, 9usize); +add_sub_const_decimals!(51usize, 41usize, 92usize, 10usize); +add_sub_const_decimals!(51usize, 40usize, 91usize, 11usize); +add_sub_const_decimals!(51usize, 39usize, 90usize, 12usize); +add_sub_const_decimals!(51usize, 38usize, 89usize, 13usize); +add_sub_const_decimals!(51usize, 37usize, 88usize, 14usize); +add_sub_const_decimals!(51usize, 36usize, 87usize, 15usize); +add_sub_const_decimals!(51usize, 35usize, 86usize, 16usize); +add_sub_const_decimals!(51usize, 34usize, 85usize, 17usize); +add_sub_const_decimals!(51usize, 33usize, 84usize, 18usize); +add_sub_const_decimals!(51usize, 32usize, 83usize, 19usize); +add_sub_const_decimals!(51usize, 31usize, 82usize, 20usize); +add_sub_const_decimals!(51usize, 30usize, 81usize, 21usize); +add_sub_const_decimals!(51usize, 29usize, 80usize, 22usize); +add_sub_const_decimals!(51usize, 28usize, 79usize, 23usize); +add_sub_const_decimals!(51usize, 27usize, 78usize, 24usize); +add_sub_const_decimals!(51usize, 26usize, 77usize, 25usize); +add_sub_const_decimals!(51usize, 25usize, 76usize, 26usize); +add_sub_const_decimals!(51usize, 24usize, 75usize, 27usize); +add_sub_const_decimals!(51usize, 23usize, 74usize, 28usize); +add_sub_const_decimals!(51usize, 22usize, 73usize, 29usize); +add_sub_const_decimals!(51usize, 21usize, 72usize, 30usize); +add_sub_const_decimals!(51usize, 20usize, 71usize, 31usize); +add_sub_const_decimals!(51usize, 19usize, 70usize, 32usize); +add_sub_const_decimals!(51usize, 18usize, 69usize, 33usize); +add_sub_const_decimals!(51usize, 17usize, 68usize, 34usize); +add_sub_const_decimals!(51usize, 16usize, 67usize, 35usize); +add_sub_const_decimals!(51usize, 15usize, 66usize, 36usize); +add_sub_const_decimals!(51usize, 14usize, 65usize, 37usize); +add_sub_const_decimals!(51usize, 13usize, 64usize, 38usize); +add_sub_const_decimals!(51usize, 12usize, 63usize, 39usize); +add_sub_const_decimals!(51usize, 11usize, 62usize, 40usize); +add_sub_const_decimals!(51usize, 10usize, 61usize, 41usize); +add_sub_const_decimals!(51usize, 9usize, 60usize, 42usize); +add_sub_const_decimals!(51usize, 8usize, 59usize, 43usize); +add_sub_const_decimals!(51usize, 7usize, 58usize, 44usize); +add_sub_const_decimals!(51usize, 6usize, 57usize, 45usize); +add_sub_const_decimals!(51usize, 5usize, 56usize, 46usize); +add_sub_const_decimals!(51usize, 4usize, 55usize, 47usize); +add_sub_const_decimals!(51usize, 3usize, 54usize, 48usize); +add_sub_const_decimals!(51usize, 2usize, 53usize, 49usize); +add_sub_const_decimals!(51usize, 1usize, 52usize, 50usize); +add_sub_const_decimals!(51usize, 0usize, 51usize, 51usize); +add_sub_const_decimals!(50usize, 64usize, 114usize, 0usize); +add_sub_const_decimals!(50usize, 63usize, 113usize, 0usize); +add_sub_const_decimals!(50usize, 62usize, 112usize, 0usize); +add_sub_const_decimals!(50usize, 61usize, 111usize, 0usize); +add_sub_const_decimals!(50usize, 60usize, 110usize, 0usize); +add_sub_const_decimals!(50usize, 59usize, 109usize, 0usize); +add_sub_const_decimals!(50usize, 58usize, 108usize, 0usize); +add_sub_const_decimals!(50usize, 57usize, 107usize, 0usize); +add_sub_const_decimals!(50usize, 56usize, 106usize, 0usize); +add_sub_const_decimals!(50usize, 55usize, 105usize, 0usize); +add_sub_const_decimals!(50usize, 54usize, 104usize, 0usize); +add_sub_const_decimals!(50usize, 53usize, 103usize, 0usize); +add_sub_const_decimals!(50usize, 52usize, 102usize, 0usize); +add_sub_const_decimals!(50usize, 51usize, 101usize, 0usize); +add_sub_const_decimals!(50usize, 50usize, 100usize, 0usize); +add_sub_const_decimals!(50usize, 49usize, 99usize, 1usize); +add_sub_const_decimals!(50usize, 48usize, 98usize, 2usize); +add_sub_const_decimals!(50usize, 47usize, 97usize, 3usize); +add_sub_const_decimals!(50usize, 46usize, 96usize, 4usize); +add_sub_const_decimals!(50usize, 45usize, 95usize, 5usize); +add_sub_const_decimals!(50usize, 44usize, 94usize, 6usize); +add_sub_const_decimals!(50usize, 43usize, 93usize, 7usize); +add_sub_const_decimals!(50usize, 42usize, 92usize, 8usize); +add_sub_const_decimals!(50usize, 41usize, 91usize, 9usize); +add_sub_const_decimals!(50usize, 40usize, 90usize, 10usize); +add_sub_const_decimals!(50usize, 39usize, 89usize, 11usize); +add_sub_const_decimals!(50usize, 38usize, 88usize, 12usize); +add_sub_const_decimals!(50usize, 37usize, 87usize, 13usize); +add_sub_const_decimals!(50usize, 36usize, 86usize, 14usize); +add_sub_const_decimals!(50usize, 35usize, 85usize, 15usize); +add_sub_const_decimals!(50usize, 34usize, 84usize, 16usize); +add_sub_const_decimals!(50usize, 33usize, 83usize, 17usize); +add_sub_const_decimals!(50usize, 32usize, 82usize, 18usize); +add_sub_const_decimals!(50usize, 31usize, 81usize, 19usize); +add_sub_const_decimals!(50usize, 30usize, 80usize, 20usize); +add_sub_const_decimals!(50usize, 29usize, 79usize, 21usize); +add_sub_const_decimals!(50usize, 28usize, 78usize, 22usize); +add_sub_const_decimals!(50usize, 27usize, 77usize, 23usize); +add_sub_const_decimals!(50usize, 26usize, 76usize, 24usize); +add_sub_const_decimals!(50usize, 25usize, 75usize, 25usize); +add_sub_const_decimals!(50usize, 24usize, 74usize, 26usize); +add_sub_const_decimals!(50usize, 23usize, 73usize, 27usize); +add_sub_const_decimals!(50usize, 22usize, 72usize, 28usize); +add_sub_const_decimals!(50usize, 21usize, 71usize, 29usize); +add_sub_const_decimals!(50usize, 20usize, 70usize, 30usize); +add_sub_const_decimals!(50usize, 19usize, 69usize, 31usize); +add_sub_const_decimals!(50usize, 18usize, 68usize, 32usize); +add_sub_const_decimals!(50usize, 17usize, 67usize, 33usize); +add_sub_const_decimals!(50usize, 16usize, 66usize, 34usize); +add_sub_const_decimals!(50usize, 15usize, 65usize, 35usize); +add_sub_const_decimals!(50usize, 14usize, 64usize, 36usize); +add_sub_const_decimals!(50usize, 13usize, 63usize, 37usize); +add_sub_const_decimals!(50usize, 12usize, 62usize, 38usize); +add_sub_const_decimals!(50usize, 11usize, 61usize, 39usize); +add_sub_const_decimals!(50usize, 10usize, 60usize, 40usize); +add_sub_const_decimals!(50usize, 9usize, 59usize, 41usize); +add_sub_const_decimals!(50usize, 8usize, 58usize, 42usize); +add_sub_const_decimals!(50usize, 7usize, 57usize, 43usize); +add_sub_const_decimals!(50usize, 6usize, 56usize, 44usize); +add_sub_const_decimals!(50usize, 5usize, 55usize, 45usize); +add_sub_const_decimals!(50usize, 4usize, 54usize, 46usize); +add_sub_const_decimals!(50usize, 3usize, 53usize, 47usize); +add_sub_const_decimals!(50usize, 2usize, 52usize, 48usize); +add_sub_const_decimals!(50usize, 1usize, 51usize, 49usize); +add_sub_const_decimals!(50usize, 0usize, 50usize, 50usize); +add_sub_const_decimals!(49usize, 64usize, 113usize, 0usize); +add_sub_const_decimals!(49usize, 63usize, 112usize, 0usize); +add_sub_const_decimals!(49usize, 62usize, 111usize, 0usize); +add_sub_const_decimals!(49usize, 61usize, 110usize, 0usize); +add_sub_const_decimals!(49usize, 60usize, 109usize, 0usize); +add_sub_const_decimals!(49usize, 59usize, 108usize, 0usize); +add_sub_const_decimals!(49usize, 58usize, 107usize, 0usize); +add_sub_const_decimals!(49usize, 57usize, 106usize, 0usize); +add_sub_const_decimals!(49usize, 56usize, 105usize, 0usize); +add_sub_const_decimals!(49usize, 55usize, 104usize, 0usize); +add_sub_const_decimals!(49usize, 54usize, 103usize, 0usize); +add_sub_const_decimals!(49usize, 53usize, 102usize, 0usize); +add_sub_const_decimals!(49usize, 52usize, 101usize, 0usize); +add_sub_const_decimals!(49usize, 51usize, 100usize, 0usize); +add_sub_const_decimals!(49usize, 50usize, 99usize, 0usize); +add_sub_const_decimals!(49usize, 49usize, 98usize, 0usize); +add_sub_const_decimals!(49usize, 48usize, 97usize, 1usize); +add_sub_const_decimals!(49usize, 47usize, 96usize, 2usize); +add_sub_const_decimals!(49usize, 46usize, 95usize, 3usize); +add_sub_const_decimals!(49usize, 45usize, 94usize, 4usize); +add_sub_const_decimals!(49usize, 44usize, 93usize, 5usize); +add_sub_const_decimals!(49usize, 43usize, 92usize, 6usize); +add_sub_const_decimals!(49usize, 42usize, 91usize, 7usize); +add_sub_const_decimals!(49usize, 41usize, 90usize, 8usize); +add_sub_const_decimals!(49usize, 40usize, 89usize, 9usize); +add_sub_const_decimals!(49usize, 39usize, 88usize, 10usize); +add_sub_const_decimals!(49usize, 38usize, 87usize, 11usize); +add_sub_const_decimals!(49usize, 37usize, 86usize, 12usize); +add_sub_const_decimals!(49usize, 36usize, 85usize, 13usize); +add_sub_const_decimals!(49usize, 35usize, 84usize, 14usize); +add_sub_const_decimals!(49usize, 34usize, 83usize, 15usize); +add_sub_const_decimals!(49usize, 33usize, 82usize, 16usize); +add_sub_const_decimals!(49usize, 32usize, 81usize, 17usize); +add_sub_const_decimals!(49usize, 31usize, 80usize, 18usize); +add_sub_const_decimals!(49usize, 30usize, 79usize, 19usize); +add_sub_const_decimals!(49usize, 29usize, 78usize, 20usize); +add_sub_const_decimals!(49usize, 28usize, 77usize, 21usize); +add_sub_const_decimals!(49usize, 27usize, 76usize, 22usize); +add_sub_const_decimals!(49usize, 26usize, 75usize, 23usize); +add_sub_const_decimals!(49usize, 25usize, 74usize, 24usize); +add_sub_const_decimals!(49usize, 24usize, 73usize, 25usize); +add_sub_const_decimals!(49usize, 23usize, 72usize, 26usize); +add_sub_const_decimals!(49usize, 22usize, 71usize, 27usize); +add_sub_const_decimals!(49usize, 21usize, 70usize, 28usize); +add_sub_const_decimals!(49usize, 20usize, 69usize, 29usize); +add_sub_const_decimals!(49usize, 19usize, 68usize, 30usize); +add_sub_const_decimals!(49usize, 18usize, 67usize, 31usize); +add_sub_const_decimals!(49usize, 17usize, 66usize, 32usize); +add_sub_const_decimals!(49usize, 16usize, 65usize, 33usize); +add_sub_const_decimals!(49usize, 15usize, 64usize, 34usize); +add_sub_const_decimals!(49usize, 14usize, 63usize, 35usize); +add_sub_const_decimals!(49usize, 13usize, 62usize, 36usize); +add_sub_const_decimals!(49usize, 12usize, 61usize, 37usize); +add_sub_const_decimals!(49usize, 11usize, 60usize, 38usize); +add_sub_const_decimals!(49usize, 10usize, 59usize, 39usize); +add_sub_const_decimals!(49usize, 9usize, 58usize, 40usize); +add_sub_const_decimals!(49usize, 8usize, 57usize, 41usize); +add_sub_const_decimals!(49usize, 7usize, 56usize, 42usize); +add_sub_const_decimals!(49usize, 6usize, 55usize, 43usize); +add_sub_const_decimals!(49usize, 5usize, 54usize, 44usize); +add_sub_const_decimals!(49usize, 4usize, 53usize, 45usize); +add_sub_const_decimals!(49usize, 3usize, 52usize, 46usize); +add_sub_const_decimals!(49usize, 2usize, 51usize, 47usize); +add_sub_const_decimals!(49usize, 1usize, 50usize, 48usize); +add_sub_const_decimals!(49usize, 0usize, 49usize, 49usize); +add_sub_const_decimals!(48usize, 64usize, 112usize, 0usize); +add_sub_const_decimals!(48usize, 63usize, 111usize, 0usize); +add_sub_const_decimals!(48usize, 62usize, 110usize, 0usize); +add_sub_const_decimals!(48usize, 61usize, 109usize, 0usize); +add_sub_const_decimals!(48usize, 60usize, 108usize, 0usize); +add_sub_const_decimals!(48usize, 59usize, 107usize, 0usize); +add_sub_const_decimals!(48usize, 58usize, 106usize, 0usize); +add_sub_const_decimals!(48usize, 57usize, 105usize, 0usize); +add_sub_const_decimals!(48usize, 56usize, 104usize, 0usize); +add_sub_const_decimals!(48usize, 55usize, 103usize, 0usize); +add_sub_const_decimals!(48usize, 54usize, 102usize, 0usize); +add_sub_const_decimals!(48usize, 53usize, 101usize, 0usize); +add_sub_const_decimals!(48usize, 52usize, 100usize, 0usize); +add_sub_const_decimals!(48usize, 51usize, 99usize, 0usize); +add_sub_const_decimals!(48usize, 50usize, 98usize, 0usize); +add_sub_const_decimals!(48usize, 49usize, 97usize, 0usize); +add_sub_const_decimals!(48usize, 48usize, 96usize, 0usize); +add_sub_const_decimals!(48usize, 47usize, 95usize, 1usize); +add_sub_const_decimals!(48usize, 46usize, 94usize, 2usize); +add_sub_const_decimals!(48usize, 45usize, 93usize, 3usize); +add_sub_const_decimals!(48usize, 44usize, 92usize, 4usize); +add_sub_const_decimals!(48usize, 43usize, 91usize, 5usize); +add_sub_const_decimals!(48usize, 42usize, 90usize, 6usize); +add_sub_const_decimals!(48usize, 41usize, 89usize, 7usize); +add_sub_const_decimals!(48usize, 40usize, 88usize, 8usize); +add_sub_const_decimals!(48usize, 39usize, 87usize, 9usize); +add_sub_const_decimals!(48usize, 38usize, 86usize, 10usize); +add_sub_const_decimals!(48usize, 37usize, 85usize, 11usize); +add_sub_const_decimals!(48usize, 36usize, 84usize, 12usize); +add_sub_const_decimals!(48usize, 35usize, 83usize, 13usize); +add_sub_const_decimals!(48usize, 34usize, 82usize, 14usize); +add_sub_const_decimals!(48usize, 33usize, 81usize, 15usize); +add_sub_const_decimals!(48usize, 32usize, 80usize, 16usize); +add_sub_const_decimals!(48usize, 31usize, 79usize, 17usize); +add_sub_const_decimals!(48usize, 30usize, 78usize, 18usize); +add_sub_const_decimals!(48usize, 29usize, 77usize, 19usize); +add_sub_const_decimals!(48usize, 28usize, 76usize, 20usize); +add_sub_const_decimals!(48usize, 27usize, 75usize, 21usize); +add_sub_const_decimals!(48usize, 26usize, 74usize, 22usize); +add_sub_const_decimals!(48usize, 25usize, 73usize, 23usize); +add_sub_const_decimals!(48usize, 24usize, 72usize, 24usize); +add_sub_const_decimals!(48usize, 23usize, 71usize, 25usize); +add_sub_const_decimals!(48usize, 22usize, 70usize, 26usize); +add_sub_const_decimals!(48usize, 21usize, 69usize, 27usize); +add_sub_const_decimals!(48usize, 20usize, 68usize, 28usize); +add_sub_const_decimals!(48usize, 19usize, 67usize, 29usize); +add_sub_const_decimals!(48usize, 18usize, 66usize, 30usize); +add_sub_const_decimals!(48usize, 17usize, 65usize, 31usize); +add_sub_const_decimals!(48usize, 16usize, 64usize, 32usize); +add_sub_const_decimals!(48usize, 15usize, 63usize, 33usize); +add_sub_const_decimals!(48usize, 14usize, 62usize, 34usize); +add_sub_const_decimals!(48usize, 13usize, 61usize, 35usize); +add_sub_const_decimals!(48usize, 12usize, 60usize, 36usize); +add_sub_const_decimals!(48usize, 11usize, 59usize, 37usize); +add_sub_const_decimals!(48usize, 10usize, 58usize, 38usize); +add_sub_const_decimals!(48usize, 9usize, 57usize, 39usize); +add_sub_const_decimals!(48usize, 8usize, 56usize, 40usize); +add_sub_const_decimals!(48usize, 7usize, 55usize, 41usize); +add_sub_const_decimals!(48usize, 6usize, 54usize, 42usize); +add_sub_const_decimals!(48usize, 5usize, 53usize, 43usize); +add_sub_const_decimals!(48usize, 4usize, 52usize, 44usize); +add_sub_const_decimals!(48usize, 3usize, 51usize, 45usize); +add_sub_const_decimals!(48usize, 2usize, 50usize, 46usize); +add_sub_const_decimals!(48usize, 1usize, 49usize, 47usize); +add_sub_const_decimals!(48usize, 0usize, 48usize, 48usize); +add_sub_const_decimals!(47usize, 64usize, 111usize, 0usize); +add_sub_const_decimals!(47usize, 63usize, 110usize, 0usize); +add_sub_const_decimals!(47usize, 62usize, 109usize, 0usize); +add_sub_const_decimals!(47usize, 61usize, 108usize, 0usize); +add_sub_const_decimals!(47usize, 60usize, 107usize, 0usize); +add_sub_const_decimals!(47usize, 59usize, 106usize, 0usize); +add_sub_const_decimals!(47usize, 58usize, 105usize, 0usize); +add_sub_const_decimals!(47usize, 57usize, 104usize, 0usize); +add_sub_const_decimals!(47usize, 56usize, 103usize, 0usize); +add_sub_const_decimals!(47usize, 55usize, 102usize, 0usize); +add_sub_const_decimals!(47usize, 54usize, 101usize, 0usize); +add_sub_const_decimals!(47usize, 53usize, 100usize, 0usize); +add_sub_const_decimals!(47usize, 52usize, 99usize, 0usize); +add_sub_const_decimals!(47usize, 51usize, 98usize, 0usize); +add_sub_const_decimals!(47usize, 50usize, 97usize, 0usize); +add_sub_const_decimals!(47usize, 49usize, 96usize, 0usize); +add_sub_const_decimals!(47usize, 48usize, 95usize, 0usize); +add_sub_const_decimals!(47usize, 47usize, 94usize, 0usize); +add_sub_const_decimals!(47usize, 46usize, 93usize, 1usize); +add_sub_const_decimals!(47usize, 45usize, 92usize, 2usize); +add_sub_const_decimals!(47usize, 44usize, 91usize, 3usize); +add_sub_const_decimals!(47usize, 43usize, 90usize, 4usize); +add_sub_const_decimals!(47usize, 42usize, 89usize, 5usize); +add_sub_const_decimals!(47usize, 41usize, 88usize, 6usize); +add_sub_const_decimals!(47usize, 40usize, 87usize, 7usize); +add_sub_const_decimals!(47usize, 39usize, 86usize, 8usize); +add_sub_const_decimals!(47usize, 38usize, 85usize, 9usize); +add_sub_const_decimals!(47usize, 37usize, 84usize, 10usize); +add_sub_const_decimals!(47usize, 36usize, 83usize, 11usize); +add_sub_const_decimals!(47usize, 35usize, 82usize, 12usize); +add_sub_const_decimals!(47usize, 34usize, 81usize, 13usize); +add_sub_const_decimals!(47usize, 33usize, 80usize, 14usize); +add_sub_const_decimals!(47usize, 32usize, 79usize, 15usize); +add_sub_const_decimals!(47usize, 31usize, 78usize, 16usize); +add_sub_const_decimals!(47usize, 30usize, 77usize, 17usize); +add_sub_const_decimals!(47usize, 29usize, 76usize, 18usize); +add_sub_const_decimals!(47usize, 28usize, 75usize, 19usize); +add_sub_const_decimals!(47usize, 27usize, 74usize, 20usize); +add_sub_const_decimals!(47usize, 26usize, 73usize, 21usize); +add_sub_const_decimals!(47usize, 25usize, 72usize, 22usize); +add_sub_const_decimals!(47usize, 24usize, 71usize, 23usize); +add_sub_const_decimals!(47usize, 23usize, 70usize, 24usize); +add_sub_const_decimals!(47usize, 22usize, 69usize, 25usize); +add_sub_const_decimals!(47usize, 21usize, 68usize, 26usize); +add_sub_const_decimals!(47usize, 20usize, 67usize, 27usize); +add_sub_const_decimals!(47usize, 19usize, 66usize, 28usize); +add_sub_const_decimals!(47usize, 18usize, 65usize, 29usize); +add_sub_const_decimals!(47usize, 17usize, 64usize, 30usize); +add_sub_const_decimals!(47usize, 16usize, 63usize, 31usize); +add_sub_const_decimals!(47usize, 15usize, 62usize, 32usize); +add_sub_const_decimals!(47usize, 14usize, 61usize, 33usize); +add_sub_const_decimals!(47usize, 13usize, 60usize, 34usize); +add_sub_const_decimals!(47usize, 12usize, 59usize, 35usize); +add_sub_const_decimals!(47usize, 11usize, 58usize, 36usize); +add_sub_const_decimals!(47usize, 10usize, 57usize, 37usize); +add_sub_const_decimals!(47usize, 9usize, 56usize, 38usize); +add_sub_const_decimals!(47usize, 8usize, 55usize, 39usize); +add_sub_const_decimals!(47usize, 7usize, 54usize, 40usize); +add_sub_const_decimals!(47usize, 6usize, 53usize, 41usize); +add_sub_const_decimals!(47usize, 5usize, 52usize, 42usize); +add_sub_const_decimals!(47usize, 4usize, 51usize, 43usize); +add_sub_const_decimals!(47usize, 3usize, 50usize, 44usize); +add_sub_const_decimals!(47usize, 2usize, 49usize, 45usize); +add_sub_const_decimals!(47usize, 1usize, 48usize, 46usize); +add_sub_const_decimals!(47usize, 0usize, 47usize, 47usize); +add_sub_const_decimals!(46usize, 64usize, 110usize, 0usize); +add_sub_const_decimals!(46usize, 63usize, 109usize, 0usize); +add_sub_const_decimals!(46usize, 62usize, 108usize, 0usize); +add_sub_const_decimals!(46usize, 61usize, 107usize, 0usize); +add_sub_const_decimals!(46usize, 60usize, 106usize, 0usize); +add_sub_const_decimals!(46usize, 59usize, 105usize, 0usize); +add_sub_const_decimals!(46usize, 58usize, 104usize, 0usize); +add_sub_const_decimals!(46usize, 57usize, 103usize, 0usize); +add_sub_const_decimals!(46usize, 56usize, 102usize, 0usize); +add_sub_const_decimals!(46usize, 55usize, 101usize, 0usize); +add_sub_const_decimals!(46usize, 54usize, 100usize, 0usize); +add_sub_const_decimals!(46usize, 53usize, 99usize, 0usize); +add_sub_const_decimals!(46usize, 52usize, 98usize, 0usize); +add_sub_const_decimals!(46usize, 51usize, 97usize, 0usize); +add_sub_const_decimals!(46usize, 50usize, 96usize, 0usize); +add_sub_const_decimals!(46usize, 49usize, 95usize, 0usize); +add_sub_const_decimals!(46usize, 48usize, 94usize, 0usize); +add_sub_const_decimals!(46usize, 47usize, 93usize, 0usize); +add_sub_const_decimals!(46usize, 46usize, 92usize, 0usize); +add_sub_const_decimals!(46usize, 45usize, 91usize, 1usize); +add_sub_const_decimals!(46usize, 44usize, 90usize, 2usize); +add_sub_const_decimals!(46usize, 43usize, 89usize, 3usize); +add_sub_const_decimals!(46usize, 42usize, 88usize, 4usize); +add_sub_const_decimals!(46usize, 41usize, 87usize, 5usize); +add_sub_const_decimals!(46usize, 40usize, 86usize, 6usize); +add_sub_const_decimals!(46usize, 39usize, 85usize, 7usize); +add_sub_const_decimals!(46usize, 38usize, 84usize, 8usize); +add_sub_const_decimals!(46usize, 37usize, 83usize, 9usize); +add_sub_const_decimals!(46usize, 36usize, 82usize, 10usize); +add_sub_const_decimals!(46usize, 35usize, 81usize, 11usize); +add_sub_const_decimals!(46usize, 34usize, 80usize, 12usize); +add_sub_const_decimals!(46usize, 33usize, 79usize, 13usize); +add_sub_const_decimals!(46usize, 32usize, 78usize, 14usize); +add_sub_const_decimals!(46usize, 31usize, 77usize, 15usize); +add_sub_const_decimals!(46usize, 30usize, 76usize, 16usize); +add_sub_const_decimals!(46usize, 29usize, 75usize, 17usize); +add_sub_const_decimals!(46usize, 28usize, 74usize, 18usize); +add_sub_const_decimals!(46usize, 27usize, 73usize, 19usize); +add_sub_const_decimals!(46usize, 26usize, 72usize, 20usize); +add_sub_const_decimals!(46usize, 25usize, 71usize, 21usize); +add_sub_const_decimals!(46usize, 24usize, 70usize, 22usize); +add_sub_const_decimals!(46usize, 23usize, 69usize, 23usize); +add_sub_const_decimals!(46usize, 22usize, 68usize, 24usize); +add_sub_const_decimals!(46usize, 21usize, 67usize, 25usize); +add_sub_const_decimals!(46usize, 20usize, 66usize, 26usize); +add_sub_const_decimals!(46usize, 19usize, 65usize, 27usize); +add_sub_const_decimals!(46usize, 18usize, 64usize, 28usize); +add_sub_const_decimals!(46usize, 17usize, 63usize, 29usize); +add_sub_const_decimals!(46usize, 16usize, 62usize, 30usize); +add_sub_const_decimals!(46usize, 15usize, 61usize, 31usize); +add_sub_const_decimals!(46usize, 14usize, 60usize, 32usize); +add_sub_const_decimals!(46usize, 13usize, 59usize, 33usize); +add_sub_const_decimals!(46usize, 12usize, 58usize, 34usize); +add_sub_const_decimals!(46usize, 11usize, 57usize, 35usize); +add_sub_const_decimals!(46usize, 10usize, 56usize, 36usize); +add_sub_const_decimals!(46usize, 9usize, 55usize, 37usize); +add_sub_const_decimals!(46usize, 8usize, 54usize, 38usize); +add_sub_const_decimals!(46usize, 7usize, 53usize, 39usize); +add_sub_const_decimals!(46usize, 6usize, 52usize, 40usize); +add_sub_const_decimals!(46usize, 5usize, 51usize, 41usize); +add_sub_const_decimals!(46usize, 4usize, 50usize, 42usize); +add_sub_const_decimals!(46usize, 3usize, 49usize, 43usize); +add_sub_const_decimals!(46usize, 2usize, 48usize, 44usize); +add_sub_const_decimals!(46usize, 1usize, 47usize, 45usize); +add_sub_const_decimals!(46usize, 0usize, 46usize, 46usize); +add_sub_const_decimals!(45usize, 64usize, 109usize, 0usize); +add_sub_const_decimals!(45usize, 63usize, 108usize, 0usize); +add_sub_const_decimals!(45usize, 62usize, 107usize, 0usize); +add_sub_const_decimals!(45usize, 61usize, 106usize, 0usize); +add_sub_const_decimals!(45usize, 60usize, 105usize, 0usize); +add_sub_const_decimals!(45usize, 59usize, 104usize, 0usize); +add_sub_const_decimals!(45usize, 58usize, 103usize, 0usize); +add_sub_const_decimals!(45usize, 57usize, 102usize, 0usize); +add_sub_const_decimals!(45usize, 56usize, 101usize, 0usize); +add_sub_const_decimals!(45usize, 55usize, 100usize, 0usize); +add_sub_const_decimals!(45usize, 54usize, 99usize, 0usize); +add_sub_const_decimals!(45usize, 53usize, 98usize, 0usize); +add_sub_const_decimals!(45usize, 52usize, 97usize, 0usize); +add_sub_const_decimals!(45usize, 51usize, 96usize, 0usize); +add_sub_const_decimals!(45usize, 50usize, 95usize, 0usize); +add_sub_const_decimals!(45usize, 49usize, 94usize, 0usize); +add_sub_const_decimals!(45usize, 48usize, 93usize, 0usize); +add_sub_const_decimals!(45usize, 47usize, 92usize, 0usize); +add_sub_const_decimals!(45usize, 46usize, 91usize, 0usize); +add_sub_const_decimals!(45usize, 45usize, 90usize, 0usize); +add_sub_const_decimals!(45usize, 44usize, 89usize, 1usize); +add_sub_const_decimals!(45usize, 43usize, 88usize, 2usize); +add_sub_const_decimals!(45usize, 42usize, 87usize, 3usize); +add_sub_const_decimals!(45usize, 41usize, 86usize, 4usize); +add_sub_const_decimals!(45usize, 40usize, 85usize, 5usize); +add_sub_const_decimals!(45usize, 39usize, 84usize, 6usize); +add_sub_const_decimals!(45usize, 38usize, 83usize, 7usize); +add_sub_const_decimals!(45usize, 37usize, 82usize, 8usize); +add_sub_const_decimals!(45usize, 36usize, 81usize, 9usize); +add_sub_const_decimals!(45usize, 35usize, 80usize, 10usize); +add_sub_const_decimals!(45usize, 34usize, 79usize, 11usize); +add_sub_const_decimals!(45usize, 33usize, 78usize, 12usize); +add_sub_const_decimals!(45usize, 32usize, 77usize, 13usize); +add_sub_const_decimals!(45usize, 31usize, 76usize, 14usize); +add_sub_const_decimals!(45usize, 30usize, 75usize, 15usize); +add_sub_const_decimals!(45usize, 29usize, 74usize, 16usize); +add_sub_const_decimals!(45usize, 28usize, 73usize, 17usize); +add_sub_const_decimals!(45usize, 27usize, 72usize, 18usize); +add_sub_const_decimals!(45usize, 26usize, 71usize, 19usize); +add_sub_const_decimals!(45usize, 25usize, 70usize, 20usize); +add_sub_const_decimals!(45usize, 24usize, 69usize, 21usize); +add_sub_const_decimals!(45usize, 23usize, 68usize, 22usize); +add_sub_const_decimals!(45usize, 22usize, 67usize, 23usize); +add_sub_const_decimals!(45usize, 21usize, 66usize, 24usize); +add_sub_const_decimals!(45usize, 20usize, 65usize, 25usize); +add_sub_const_decimals!(45usize, 19usize, 64usize, 26usize); +add_sub_const_decimals!(45usize, 18usize, 63usize, 27usize); +add_sub_const_decimals!(45usize, 17usize, 62usize, 28usize); +add_sub_const_decimals!(45usize, 16usize, 61usize, 29usize); +add_sub_const_decimals!(45usize, 15usize, 60usize, 30usize); +add_sub_const_decimals!(45usize, 14usize, 59usize, 31usize); +add_sub_const_decimals!(45usize, 13usize, 58usize, 32usize); +add_sub_const_decimals!(45usize, 12usize, 57usize, 33usize); +add_sub_const_decimals!(45usize, 11usize, 56usize, 34usize); +add_sub_const_decimals!(45usize, 10usize, 55usize, 35usize); +add_sub_const_decimals!(45usize, 9usize, 54usize, 36usize); +add_sub_const_decimals!(45usize, 8usize, 53usize, 37usize); +add_sub_const_decimals!(45usize, 7usize, 52usize, 38usize); +add_sub_const_decimals!(45usize, 6usize, 51usize, 39usize); +add_sub_const_decimals!(45usize, 5usize, 50usize, 40usize); +add_sub_const_decimals!(45usize, 4usize, 49usize, 41usize); +add_sub_const_decimals!(45usize, 3usize, 48usize, 42usize); +add_sub_const_decimals!(45usize, 2usize, 47usize, 43usize); +add_sub_const_decimals!(45usize, 1usize, 46usize, 44usize); +add_sub_const_decimals!(45usize, 0usize, 45usize, 45usize); +add_sub_const_decimals!(44usize, 64usize, 108usize, 0usize); +add_sub_const_decimals!(44usize, 63usize, 107usize, 0usize); +add_sub_const_decimals!(44usize, 62usize, 106usize, 0usize); +add_sub_const_decimals!(44usize, 61usize, 105usize, 0usize); +add_sub_const_decimals!(44usize, 60usize, 104usize, 0usize); +add_sub_const_decimals!(44usize, 59usize, 103usize, 0usize); +add_sub_const_decimals!(44usize, 58usize, 102usize, 0usize); +add_sub_const_decimals!(44usize, 57usize, 101usize, 0usize); +add_sub_const_decimals!(44usize, 56usize, 100usize, 0usize); +add_sub_const_decimals!(44usize, 55usize, 99usize, 0usize); +add_sub_const_decimals!(44usize, 54usize, 98usize, 0usize); +add_sub_const_decimals!(44usize, 53usize, 97usize, 0usize); +add_sub_const_decimals!(44usize, 52usize, 96usize, 0usize); +add_sub_const_decimals!(44usize, 51usize, 95usize, 0usize); +add_sub_const_decimals!(44usize, 50usize, 94usize, 0usize); +add_sub_const_decimals!(44usize, 49usize, 93usize, 0usize); +add_sub_const_decimals!(44usize, 48usize, 92usize, 0usize); +add_sub_const_decimals!(44usize, 47usize, 91usize, 0usize); +add_sub_const_decimals!(44usize, 46usize, 90usize, 0usize); +add_sub_const_decimals!(44usize, 45usize, 89usize, 0usize); +add_sub_const_decimals!(44usize, 44usize, 88usize, 0usize); +add_sub_const_decimals!(44usize, 43usize, 87usize, 1usize); +add_sub_const_decimals!(44usize, 42usize, 86usize, 2usize); +add_sub_const_decimals!(44usize, 41usize, 85usize, 3usize); +add_sub_const_decimals!(44usize, 40usize, 84usize, 4usize); +add_sub_const_decimals!(44usize, 39usize, 83usize, 5usize); +add_sub_const_decimals!(44usize, 38usize, 82usize, 6usize); +add_sub_const_decimals!(44usize, 37usize, 81usize, 7usize); +add_sub_const_decimals!(44usize, 36usize, 80usize, 8usize); +add_sub_const_decimals!(44usize, 35usize, 79usize, 9usize); +add_sub_const_decimals!(44usize, 34usize, 78usize, 10usize); +add_sub_const_decimals!(44usize, 33usize, 77usize, 11usize); +add_sub_const_decimals!(44usize, 32usize, 76usize, 12usize); +add_sub_const_decimals!(44usize, 31usize, 75usize, 13usize); +add_sub_const_decimals!(44usize, 30usize, 74usize, 14usize); +add_sub_const_decimals!(44usize, 29usize, 73usize, 15usize); +add_sub_const_decimals!(44usize, 28usize, 72usize, 16usize); +add_sub_const_decimals!(44usize, 27usize, 71usize, 17usize); +add_sub_const_decimals!(44usize, 26usize, 70usize, 18usize); +add_sub_const_decimals!(44usize, 25usize, 69usize, 19usize); +add_sub_const_decimals!(44usize, 24usize, 68usize, 20usize); +add_sub_const_decimals!(44usize, 23usize, 67usize, 21usize); +add_sub_const_decimals!(44usize, 22usize, 66usize, 22usize); +add_sub_const_decimals!(44usize, 21usize, 65usize, 23usize); +add_sub_const_decimals!(44usize, 20usize, 64usize, 24usize); +add_sub_const_decimals!(44usize, 19usize, 63usize, 25usize); +add_sub_const_decimals!(44usize, 18usize, 62usize, 26usize); +add_sub_const_decimals!(44usize, 17usize, 61usize, 27usize); +add_sub_const_decimals!(44usize, 16usize, 60usize, 28usize); +add_sub_const_decimals!(44usize, 15usize, 59usize, 29usize); +add_sub_const_decimals!(44usize, 14usize, 58usize, 30usize); +add_sub_const_decimals!(44usize, 13usize, 57usize, 31usize); +add_sub_const_decimals!(44usize, 12usize, 56usize, 32usize); +add_sub_const_decimals!(44usize, 11usize, 55usize, 33usize); +add_sub_const_decimals!(44usize, 10usize, 54usize, 34usize); +add_sub_const_decimals!(44usize, 9usize, 53usize, 35usize); +add_sub_const_decimals!(44usize, 8usize, 52usize, 36usize); +add_sub_const_decimals!(44usize, 7usize, 51usize, 37usize); +add_sub_const_decimals!(44usize, 6usize, 50usize, 38usize); +add_sub_const_decimals!(44usize, 5usize, 49usize, 39usize); +add_sub_const_decimals!(44usize, 4usize, 48usize, 40usize); +add_sub_const_decimals!(44usize, 3usize, 47usize, 41usize); +add_sub_const_decimals!(44usize, 2usize, 46usize, 42usize); +add_sub_const_decimals!(44usize, 1usize, 45usize, 43usize); +add_sub_const_decimals!(44usize, 0usize, 44usize, 44usize); +add_sub_const_decimals!(43usize, 64usize, 107usize, 0usize); +add_sub_const_decimals!(43usize, 63usize, 106usize, 0usize); +add_sub_const_decimals!(43usize, 62usize, 105usize, 0usize); +add_sub_const_decimals!(43usize, 61usize, 104usize, 0usize); +add_sub_const_decimals!(43usize, 60usize, 103usize, 0usize); +add_sub_const_decimals!(43usize, 59usize, 102usize, 0usize); +add_sub_const_decimals!(43usize, 58usize, 101usize, 0usize); +add_sub_const_decimals!(43usize, 57usize, 100usize, 0usize); +add_sub_const_decimals!(43usize, 56usize, 99usize, 0usize); +add_sub_const_decimals!(43usize, 55usize, 98usize, 0usize); +add_sub_const_decimals!(43usize, 54usize, 97usize, 0usize); +add_sub_const_decimals!(43usize, 53usize, 96usize, 0usize); +add_sub_const_decimals!(43usize, 52usize, 95usize, 0usize); +add_sub_const_decimals!(43usize, 51usize, 94usize, 0usize); +add_sub_const_decimals!(43usize, 50usize, 93usize, 0usize); +add_sub_const_decimals!(43usize, 49usize, 92usize, 0usize); +add_sub_const_decimals!(43usize, 48usize, 91usize, 0usize); +add_sub_const_decimals!(43usize, 47usize, 90usize, 0usize); +add_sub_const_decimals!(43usize, 46usize, 89usize, 0usize); +add_sub_const_decimals!(43usize, 45usize, 88usize, 0usize); +add_sub_const_decimals!(43usize, 44usize, 87usize, 0usize); +add_sub_const_decimals!(43usize, 43usize, 86usize, 0usize); +add_sub_const_decimals!(43usize, 42usize, 85usize, 1usize); +add_sub_const_decimals!(43usize, 41usize, 84usize, 2usize); +add_sub_const_decimals!(43usize, 40usize, 83usize, 3usize); +add_sub_const_decimals!(43usize, 39usize, 82usize, 4usize); +add_sub_const_decimals!(43usize, 38usize, 81usize, 5usize); +add_sub_const_decimals!(43usize, 37usize, 80usize, 6usize); +add_sub_const_decimals!(43usize, 36usize, 79usize, 7usize); +add_sub_const_decimals!(43usize, 35usize, 78usize, 8usize); +add_sub_const_decimals!(43usize, 34usize, 77usize, 9usize); +add_sub_const_decimals!(43usize, 33usize, 76usize, 10usize); +add_sub_const_decimals!(43usize, 32usize, 75usize, 11usize); +add_sub_const_decimals!(43usize, 31usize, 74usize, 12usize); +add_sub_const_decimals!(43usize, 30usize, 73usize, 13usize); +add_sub_const_decimals!(43usize, 29usize, 72usize, 14usize); +add_sub_const_decimals!(43usize, 28usize, 71usize, 15usize); +add_sub_const_decimals!(43usize, 27usize, 70usize, 16usize); +add_sub_const_decimals!(43usize, 26usize, 69usize, 17usize); +add_sub_const_decimals!(43usize, 25usize, 68usize, 18usize); +add_sub_const_decimals!(43usize, 24usize, 67usize, 19usize); +add_sub_const_decimals!(43usize, 23usize, 66usize, 20usize); +add_sub_const_decimals!(43usize, 22usize, 65usize, 21usize); +add_sub_const_decimals!(43usize, 21usize, 64usize, 22usize); +add_sub_const_decimals!(43usize, 20usize, 63usize, 23usize); +add_sub_const_decimals!(43usize, 19usize, 62usize, 24usize); +add_sub_const_decimals!(43usize, 18usize, 61usize, 25usize); +add_sub_const_decimals!(43usize, 17usize, 60usize, 26usize); +add_sub_const_decimals!(43usize, 16usize, 59usize, 27usize); +add_sub_const_decimals!(43usize, 15usize, 58usize, 28usize); +add_sub_const_decimals!(43usize, 14usize, 57usize, 29usize); +add_sub_const_decimals!(43usize, 13usize, 56usize, 30usize); +add_sub_const_decimals!(43usize, 12usize, 55usize, 31usize); +add_sub_const_decimals!(43usize, 11usize, 54usize, 32usize); +add_sub_const_decimals!(43usize, 10usize, 53usize, 33usize); +add_sub_const_decimals!(43usize, 9usize, 52usize, 34usize); +add_sub_const_decimals!(43usize, 8usize, 51usize, 35usize); +add_sub_const_decimals!(43usize, 7usize, 50usize, 36usize); +add_sub_const_decimals!(43usize, 6usize, 49usize, 37usize); +add_sub_const_decimals!(43usize, 5usize, 48usize, 38usize); +add_sub_const_decimals!(43usize, 4usize, 47usize, 39usize); +add_sub_const_decimals!(43usize, 3usize, 46usize, 40usize); +add_sub_const_decimals!(43usize, 2usize, 45usize, 41usize); +add_sub_const_decimals!(43usize, 1usize, 44usize, 42usize); +add_sub_const_decimals!(43usize, 0usize, 43usize, 43usize); +add_sub_const_decimals!(42usize, 64usize, 106usize, 0usize); +add_sub_const_decimals!(42usize, 63usize, 105usize, 0usize); +add_sub_const_decimals!(42usize, 62usize, 104usize, 0usize); +add_sub_const_decimals!(42usize, 61usize, 103usize, 0usize); +add_sub_const_decimals!(42usize, 60usize, 102usize, 0usize); +add_sub_const_decimals!(42usize, 59usize, 101usize, 0usize); +add_sub_const_decimals!(42usize, 58usize, 100usize, 0usize); +add_sub_const_decimals!(42usize, 57usize, 99usize, 0usize); +add_sub_const_decimals!(42usize, 56usize, 98usize, 0usize); +add_sub_const_decimals!(42usize, 55usize, 97usize, 0usize); +add_sub_const_decimals!(42usize, 54usize, 96usize, 0usize); +add_sub_const_decimals!(42usize, 53usize, 95usize, 0usize); +add_sub_const_decimals!(42usize, 52usize, 94usize, 0usize); +add_sub_const_decimals!(42usize, 51usize, 93usize, 0usize); +add_sub_const_decimals!(42usize, 50usize, 92usize, 0usize); +add_sub_const_decimals!(42usize, 49usize, 91usize, 0usize); +add_sub_const_decimals!(42usize, 48usize, 90usize, 0usize); +add_sub_const_decimals!(42usize, 47usize, 89usize, 0usize); +add_sub_const_decimals!(42usize, 46usize, 88usize, 0usize); +add_sub_const_decimals!(42usize, 45usize, 87usize, 0usize); +add_sub_const_decimals!(42usize, 44usize, 86usize, 0usize); +add_sub_const_decimals!(42usize, 43usize, 85usize, 0usize); +add_sub_const_decimals!(42usize, 42usize, 84usize, 0usize); +add_sub_const_decimals!(42usize, 41usize, 83usize, 1usize); +add_sub_const_decimals!(42usize, 40usize, 82usize, 2usize); +add_sub_const_decimals!(42usize, 39usize, 81usize, 3usize); +add_sub_const_decimals!(42usize, 38usize, 80usize, 4usize); +add_sub_const_decimals!(42usize, 37usize, 79usize, 5usize); +add_sub_const_decimals!(42usize, 36usize, 78usize, 6usize); +add_sub_const_decimals!(42usize, 35usize, 77usize, 7usize); +add_sub_const_decimals!(42usize, 34usize, 76usize, 8usize); +add_sub_const_decimals!(42usize, 33usize, 75usize, 9usize); +add_sub_const_decimals!(42usize, 32usize, 74usize, 10usize); +add_sub_const_decimals!(42usize, 31usize, 73usize, 11usize); +add_sub_const_decimals!(42usize, 30usize, 72usize, 12usize); +add_sub_const_decimals!(42usize, 29usize, 71usize, 13usize); +add_sub_const_decimals!(42usize, 28usize, 70usize, 14usize); +add_sub_const_decimals!(42usize, 27usize, 69usize, 15usize); +add_sub_const_decimals!(42usize, 26usize, 68usize, 16usize); +add_sub_const_decimals!(42usize, 25usize, 67usize, 17usize); +add_sub_const_decimals!(42usize, 24usize, 66usize, 18usize); +add_sub_const_decimals!(42usize, 23usize, 65usize, 19usize); +add_sub_const_decimals!(42usize, 22usize, 64usize, 20usize); +add_sub_const_decimals!(42usize, 21usize, 63usize, 21usize); +add_sub_const_decimals!(42usize, 20usize, 62usize, 22usize); +add_sub_const_decimals!(42usize, 19usize, 61usize, 23usize); +add_sub_const_decimals!(42usize, 18usize, 60usize, 24usize); +add_sub_const_decimals!(42usize, 17usize, 59usize, 25usize); +add_sub_const_decimals!(42usize, 16usize, 58usize, 26usize); +add_sub_const_decimals!(42usize, 15usize, 57usize, 27usize); +add_sub_const_decimals!(42usize, 14usize, 56usize, 28usize); +add_sub_const_decimals!(42usize, 13usize, 55usize, 29usize); +add_sub_const_decimals!(42usize, 12usize, 54usize, 30usize); +add_sub_const_decimals!(42usize, 11usize, 53usize, 31usize); +add_sub_const_decimals!(42usize, 10usize, 52usize, 32usize); +add_sub_const_decimals!(42usize, 9usize, 51usize, 33usize); +add_sub_const_decimals!(42usize, 8usize, 50usize, 34usize); +add_sub_const_decimals!(42usize, 7usize, 49usize, 35usize); +add_sub_const_decimals!(42usize, 6usize, 48usize, 36usize); +add_sub_const_decimals!(42usize, 5usize, 47usize, 37usize); +add_sub_const_decimals!(42usize, 4usize, 46usize, 38usize); +add_sub_const_decimals!(42usize, 3usize, 45usize, 39usize); +add_sub_const_decimals!(42usize, 2usize, 44usize, 40usize); +add_sub_const_decimals!(42usize, 1usize, 43usize, 41usize); +add_sub_const_decimals!(42usize, 0usize, 42usize, 42usize); +add_sub_const_decimals!(41usize, 64usize, 105usize, 0usize); +add_sub_const_decimals!(41usize, 63usize, 104usize, 0usize); +add_sub_const_decimals!(41usize, 62usize, 103usize, 0usize); +add_sub_const_decimals!(41usize, 61usize, 102usize, 0usize); +add_sub_const_decimals!(41usize, 60usize, 101usize, 0usize); +add_sub_const_decimals!(41usize, 59usize, 100usize, 0usize); +add_sub_const_decimals!(41usize, 58usize, 99usize, 0usize); +add_sub_const_decimals!(41usize, 57usize, 98usize, 0usize); +add_sub_const_decimals!(41usize, 56usize, 97usize, 0usize); +add_sub_const_decimals!(41usize, 55usize, 96usize, 0usize); +add_sub_const_decimals!(41usize, 54usize, 95usize, 0usize); +add_sub_const_decimals!(41usize, 53usize, 94usize, 0usize); +add_sub_const_decimals!(41usize, 52usize, 93usize, 0usize); +add_sub_const_decimals!(41usize, 51usize, 92usize, 0usize); +add_sub_const_decimals!(41usize, 50usize, 91usize, 0usize); +add_sub_const_decimals!(41usize, 49usize, 90usize, 0usize); +add_sub_const_decimals!(41usize, 48usize, 89usize, 0usize); +add_sub_const_decimals!(41usize, 47usize, 88usize, 0usize); +add_sub_const_decimals!(41usize, 46usize, 87usize, 0usize); +add_sub_const_decimals!(41usize, 45usize, 86usize, 0usize); +add_sub_const_decimals!(41usize, 44usize, 85usize, 0usize); +add_sub_const_decimals!(41usize, 43usize, 84usize, 0usize); +add_sub_const_decimals!(41usize, 42usize, 83usize, 0usize); +add_sub_const_decimals!(41usize, 41usize, 82usize, 0usize); +add_sub_const_decimals!(41usize, 40usize, 81usize, 1usize); +add_sub_const_decimals!(41usize, 39usize, 80usize, 2usize); +add_sub_const_decimals!(41usize, 38usize, 79usize, 3usize); +add_sub_const_decimals!(41usize, 37usize, 78usize, 4usize); +add_sub_const_decimals!(41usize, 36usize, 77usize, 5usize); +add_sub_const_decimals!(41usize, 35usize, 76usize, 6usize); +add_sub_const_decimals!(41usize, 34usize, 75usize, 7usize); +add_sub_const_decimals!(41usize, 33usize, 74usize, 8usize); +add_sub_const_decimals!(41usize, 32usize, 73usize, 9usize); +add_sub_const_decimals!(41usize, 31usize, 72usize, 10usize); +add_sub_const_decimals!(41usize, 30usize, 71usize, 11usize); +add_sub_const_decimals!(41usize, 29usize, 70usize, 12usize); +add_sub_const_decimals!(41usize, 28usize, 69usize, 13usize); +add_sub_const_decimals!(41usize, 27usize, 68usize, 14usize); +add_sub_const_decimals!(41usize, 26usize, 67usize, 15usize); +add_sub_const_decimals!(41usize, 25usize, 66usize, 16usize); +add_sub_const_decimals!(41usize, 24usize, 65usize, 17usize); +add_sub_const_decimals!(41usize, 23usize, 64usize, 18usize); +add_sub_const_decimals!(41usize, 22usize, 63usize, 19usize); +add_sub_const_decimals!(41usize, 21usize, 62usize, 20usize); +add_sub_const_decimals!(41usize, 20usize, 61usize, 21usize); +add_sub_const_decimals!(41usize, 19usize, 60usize, 22usize); +add_sub_const_decimals!(41usize, 18usize, 59usize, 23usize); +add_sub_const_decimals!(41usize, 17usize, 58usize, 24usize); +add_sub_const_decimals!(41usize, 16usize, 57usize, 25usize); +add_sub_const_decimals!(41usize, 15usize, 56usize, 26usize); +add_sub_const_decimals!(41usize, 14usize, 55usize, 27usize); +add_sub_const_decimals!(41usize, 13usize, 54usize, 28usize); +add_sub_const_decimals!(41usize, 12usize, 53usize, 29usize); +add_sub_const_decimals!(41usize, 11usize, 52usize, 30usize); +add_sub_const_decimals!(41usize, 10usize, 51usize, 31usize); +add_sub_const_decimals!(41usize, 9usize, 50usize, 32usize); +add_sub_const_decimals!(41usize, 8usize, 49usize, 33usize); +add_sub_const_decimals!(41usize, 7usize, 48usize, 34usize); +add_sub_const_decimals!(41usize, 6usize, 47usize, 35usize); +add_sub_const_decimals!(41usize, 5usize, 46usize, 36usize); +add_sub_const_decimals!(41usize, 4usize, 45usize, 37usize); +add_sub_const_decimals!(41usize, 3usize, 44usize, 38usize); +add_sub_const_decimals!(41usize, 2usize, 43usize, 39usize); +add_sub_const_decimals!(41usize, 1usize, 42usize, 40usize); +add_sub_const_decimals!(41usize, 0usize, 41usize, 41usize); +add_sub_const_decimals!(40usize, 64usize, 104usize, 0usize); +add_sub_const_decimals!(40usize, 63usize, 103usize, 0usize); +add_sub_const_decimals!(40usize, 62usize, 102usize, 0usize); +add_sub_const_decimals!(40usize, 61usize, 101usize, 0usize); +add_sub_const_decimals!(40usize, 60usize, 100usize, 0usize); +add_sub_const_decimals!(40usize, 59usize, 99usize, 0usize); +add_sub_const_decimals!(40usize, 58usize, 98usize, 0usize); +add_sub_const_decimals!(40usize, 57usize, 97usize, 0usize); +add_sub_const_decimals!(40usize, 56usize, 96usize, 0usize); +add_sub_const_decimals!(40usize, 55usize, 95usize, 0usize); +add_sub_const_decimals!(40usize, 54usize, 94usize, 0usize); +add_sub_const_decimals!(40usize, 53usize, 93usize, 0usize); +add_sub_const_decimals!(40usize, 52usize, 92usize, 0usize); +add_sub_const_decimals!(40usize, 51usize, 91usize, 0usize); +add_sub_const_decimals!(40usize, 50usize, 90usize, 0usize); +add_sub_const_decimals!(40usize, 49usize, 89usize, 0usize); +add_sub_const_decimals!(40usize, 48usize, 88usize, 0usize); +add_sub_const_decimals!(40usize, 47usize, 87usize, 0usize); +add_sub_const_decimals!(40usize, 46usize, 86usize, 0usize); +add_sub_const_decimals!(40usize, 45usize, 85usize, 0usize); +add_sub_const_decimals!(40usize, 44usize, 84usize, 0usize); +add_sub_const_decimals!(40usize, 43usize, 83usize, 0usize); +add_sub_const_decimals!(40usize, 42usize, 82usize, 0usize); +add_sub_const_decimals!(40usize, 41usize, 81usize, 0usize); +add_sub_const_decimals!(40usize, 40usize, 80usize, 0usize); +add_sub_const_decimals!(40usize, 39usize, 79usize, 1usize); +add_sub_const_decimals!(40usize, 38usize, 78usize, 2usize); +add_sub_const_decimals!(40usize, 37usize, 77usize, 3usize); +add_sub_const_decimals!(40usize, 36usize, 76usize, 4usize); +add_sub_const_decimals!(40usize, 35usize, 75usize, 5usize); +add_sub_const_decimals!(40usize, 34usize, 74usize, 6usize); +add_sub_const_decimals!(40usize, 33usize, 73usize, 7usize); +add_sub_const_decimals!(40usize, 32usize, 72usize, 8usize); +add_sub_const_decimals!(40usize, 31usize, 71usize, 9usize); +add_sub_const_decimals!(40usize, 30usize, 70usize, 10usize); +add_sub_const_decimals!(40usize, 29usize, 69usize, 11usize); +add_sub_const_decimals!(40usize, 28usize, 68usize, 12usize); +add_sub_const_decimals!(40usize, 27usize, 67usize, 13usize); +add_sub_const_decimals!(40usize, 26usize, 66usize, 14usize); +add_sub_const_decimals!(40usize, 25usize, 65usize, 15usize); +add_sub_const_decimals!(40usize, 24usize, 64usize, 16usize); +add_sub_const_decimals!(40usize, 23usize, 63usize, 17usize); +add_sub_const_decimals!(40usize, 22usize, 62usize, 18usize); +add_sub_const_decimals!(40usize, 21usize, 61usize, 19usize); +add_sub_const_decimals!(40usize, 20usize, 60usize, 20usize); +add_sub_const_decimals!(40usize, 19usize, 59usize, 21usize); +add_sub_const_decimals!(40usize, 18usize, 58usize, 22usize); +add_sub_const_decimals!(40usize, 17usize, 57usize, 23usize); +add_sub_const_decimals!(40usize, 16usize, 56usize, 24usize); +add_sub_const_decimals!(40usize, 15usize, 55usize, 25usize); +add_sub_const_decimals!(40usize, 14usize, 54usize, 26usize); +add_sub_const_decimals!(40usize, 13usize, 53usize, 27usize); +add_sub_const_decimals!(40usize, 12usize, 52usize, 28usize); +add_sub_const_decimals!(40usize, 11usize, 51usize, 29usize); +add_sub_const_decimals!(40usize, 10usize, 50usize, 30usize); +add_sub_const_decimals!(40usize, 9usize, 49usize, 31usize); +add_sub_const_decimals!(40usize, 8usize, 48usize, 32usize); +add_sub_const_decimals!(40usize, 7usize, 47usize, 33usize); +add_sub_const_decimals!(40usize, 6usize, 46usize, 34usize); +add_sub_const_decimals!(40usize, 5usize, 45usize, 35usize); +add_sub_const_decimals!(40usize, 4usize, 44usize, 36usize); +add_sub_const_decimals!(40usize, 3usize, 43usize, 37usize); +add_sub_const_decimals!(40usize, 2usize, 42usize, 38usize); +add_sub_const_decimals!(40usize, 1usize, 41usize, 39usize); +add_sub_const_decimals!(40usize, 0usize, 40usize, 40usize); +add_sub_const_decimals!(39usize, 64usize, 103usize, 0usize); +add_sub_const_decimals!(39usize, 63usize, 102usize, 0usize); +add_sub_const_decimals!(39usize, 62usize, 101usize, 0usize); +add_sub_const_decimals!(39usize, 61usize, 100usize, 0usize); +add_sub_const_decimals!(39usize, 60usize, 99usize, 0usize); +add_sub_const_decimals!(39usize, 59usize, 98usize, 0usize); +add_sub_const_decimals!(39usize, 58usize, 97usize, 0usize); +add_sub_const_decimals!(39usize, 57usize, 96usize, 0usize); +add_sub_const_decimals!(39usize, 56usize, 95usize, 0usize); +add_sub_const_decimals!(39usize, 55usize, 94usize, 0usize); +add_sub_const_decimals!(39usize, 54usize, 93usize, 0usize); +add_sub_const_decimals!(39usize, 53usize, 92usize, 0usize); +add_sub_const_decimals!(39usize, 52usize, 91usize, 0usize); +add_sub_const_decimals!(39usize, 51usize, 90usize, 0usize); +add_sub_const_decimals!(39usize, 50usize, 89usize, 0usize); +add_sub_const_decimals!(39usize, 49usize, 88usize, 0usize); +add_sub_const_decimals!(39usize, 48usize, 87usize, 0usize); +add_sub_const_decimals!(39usize, 47usize, 86usize, 0usize); +add_sub_const_decimals!(39usize, 46usize, 85usize, 0usize); +add_sub_const_decimals!(39usize, 45usize, 84usize, 0usize); +add_sub_const_decimals!(39usize, 44usize, 83usize, 0usize); +add_sub_const_decimals!(39usize, 43usize, 82usize, 0usize); +add_sub_const_decimals!(39usize, 42usize, 81usize, 0usize); +add_sub_const_decimals!(39usize, 41usize, 80usize, 0usize); +add_sub_const_decimals!(39usize, 40usize, 79usize, 0usize); +add_sub_const_decimals!(39usize, 39usize, 78usize, 0usize); +add_sub_const_decimals!(39usize, 38usize, 77usize, 1usize); +add_sub_const_decimals!(39usize, 37usize, 76usize, 2usize); +add_sub_const_decimals!(39usize, 36usize, 75usize, 3usize); +add_sub_const_decimals!(39usize, 35usize, 74usize, 4usize); +add_sub_const_decimals!(39usize, 34usize, 73usize, 5usize); +add_sub_const_decimals!(39usize, 33usize, 72usize, 6usize); +add_sub_const_decimals!(39usize, 32usize, 71usize, 7usize); +add_sub_const_decimals!(39usize, 31usize, 70usize, 8usize); +add_sub_const_decimals!(39usize, 30usize, 69usize, 9usize); +add_sub_const_decimals!(39usize, 29usize, 68usize, 10usize); +add_sub_const_decimals!(39usize, 28usize, 67usize, 11usize); +add_sub_const_decimals!(39usize, 27usize, 66usize, 12usize); +add_sub_const_decimals!(39usize, 26usize, 65usize, 13usize); +add_sub_const_decimals!(39usize, 25usize, 64usize, 14usize); +add_sub_const_decimals!(39usize, 24usize, 63usize, 15usize); +add_sub_const_decimals!(39usize, 23usize, 62usize, 16usize); +add_sub_const_decimals!(39usize, 22usize, 61usize, 17usize); +add_sub_const_decimals!(39usize, 21usize, 60usize, 18usize); +add_sub_const_decimals!(39usize, 20usize, 59usize, 19usize); +add_sub_const_decimals!(39usize, 19usize, 58usize, 20usize); +add_sub_const_decimals!(39usize, 18usize, 57usize, 21usize); +add_sub_const_decimals!(39usize, 17usize, 56usize, 22usize); +add_sub_const_decimals!(39usize, 16usize, 55usize, 23usize); +add_sub_const_decimals!(39usize, 15usize, 54usize, 24usize); +add_sub_const_decimals!(39usize, 14usize, 53usize, 25usize); +add_sub_const_decimals!(39usize, 13usize, 52usize, 26usize); +add_sub_const_decimals!(39usize, 12usize, 51usize, 27usize); +add_sub_const_decimals!(39usize, 11usize, 50usize, 28usize); +add_sub_const_decimals!(39usize, 10usize, 49usize, 29usize); +add_sub_const_decimals!(39usize, 9usize, 48usize, 30usize); +add_sub_const_decimals!(39usize, 8usize, 47usize, 31usize); +add_sub_const_decimals!(39usize, 7usize, 46usize, 32usize); +add_sub_const_decimals!(39usize, 6usize, 45usize, 33usize); +add_sub_const_decimals!(39usize, 5usize, 44usize, 34usize); +add_sub_const_decimals!(39usize, 4usize, 43usize, 35usize); +add_sub_const_decimals!(39usize, 3usize, 42usize, 36usize); +add_sub_const_decimals!(39usize, 2usize, 41usize, 37usize); +add_sub_const_decimals!(39usize, 1usize, 40usize, 38usize); +add_sub_const_decimals!(39usize, 0usize, 39usize, 39usize); +add_sub_const_decimals!(38usize, 64usize, 102usize, 0usize); +add_sub_const_decimals!(38usize, 63usize, 101usize, 0usize); +add_sub_const_decimals!(38usize, 62usize, 100usize, 0usize); +add_sub_const_decimals!(38usize, 61usize, 99usize, 0usize); +add_sub_const_decimals!(38usize, 60usize, 98usize, 0usize); +add_sub_const_decimals!(38usize, 59usize, 97usize, 0usize); +add_sub_const_decimals!(38usize, 58usize, 96usize, 0usize); +add_sub_const_decimals!(38usize, 57usize, 95usize, 0usize); +add_sub_const_decimals!(38usize, 56usize, 94usize, 0usize); +add_sub_const_decimals!(38usize, 55usize, 93usize, 0usize); +add_sub_const_decimals!(38usize, 54usize, 92usize, 0usize); +add_sub_const_decimals!(38usize, 53usize, 91usize, 0usize); +add_sub_const_decimals!(38usize, 52usize, 90usize, 0usize); +add_sub_const_decimals!(38usize, 51usize, 89usize, 0usize); +add_sub_const_decimals!(38usize, 50usize, 88usize, 0usize); +add_sub_const_decimals!(38usize, 49usize, 87usize, 0usize); +add_sub_const_decimals!(38usize, 48usize, 86usize, 0usize); +add_sub_const_decimals!(38usize, 47usize, 85usize, 0usize); +add_sub_const_decimals!(38usize, 46usize, 84usize, 0usize); +add_sub_const_decimals!(38usize, 45usize, 83usize, 0usize); +add_sub_const_decimals!(38usize, 44usize, 82usize, 0usize); +add_sub_const_decimals!(38usize, 43usize, 81usize, 0usize); +add_sub_const_decimals!(38usize, 42usize, 80usize, 0usize); +add_sub_const_decimals!(38usize, 41usize, 79usize, 0usize); +add_sub_const_decimals!(38usize, 40usize, 78usize, 0usize); +add_sub_const_decimals!(38usize, 39usize, 77usize, 0usize); +add_sub_const_decimals!(38usize, 38usize, 76usize, 0usize); +add_sub_const_decimals!(38usize, 37usize, 75usize, 1usize); +add_sub_const_decimals!(38usize, 36usize, 74usize, 2usize); +add_sub_const_decimals!(38usize, 35usize, 73usize, 3usize); +add_sub_const_decimals!(38usize, 34usize, 72usize, 4usize); +add_sub_const_decimals!(38usize, 33usize, 71usize, 5usize); +add_sub_const_decimals!(38usize, 32usize, 70usize, 6usize); +add_sub_const_decimals!(38usize, 31usize, 69usize, 7usize); +add_sub_const_decimals!(38usize, 30usize, 68usize, 8usize); +add_sub_const_decimals!(38usize, 29usize, 67usize, 9usize); +add_sub_const_decimals!(38usize, 28usize, 66usize, 10usize); +add_sub_const_decimals!(38usize, 27usize, 65usize, 11usize); +add_sub_const_decimals!(38usize, 26usize, 64usize, 12usize); +add_sub_const_decimals!(38usize, 25usize, 63usize, 13usize); +add_sub_const_decimals!(38usize, 24usize, 62usize, 14usize); +add_sub_const_decimals!(38usize, 23usize, 61usize, 15usize); +add_sub_const_decimals!(38usize, 22usize, 60usize, 16usize); +add_sub_const_decimals!(38usize, 21usize, 59usize, 17usize); +add_sub_const_decimals!(38usize, 20usize, 58usize, 18usize); +add_sub_const_decimals!(38usize, 19usize, 57usize, 19usize); +add_sub_const_decimals!(38usize, 18usize, 56usize, 20usize); +add_sub_const_decimals!(38usize, 17usize, 55usize, 21usize); +add_sub_const_decimals!(38usize, 16usize, 54usize, 22usize); +add_sub_const_decimals!(38usize, 15usize, 53usize, 23usize); +add_sub_const_decimals!(38usize, 14usize, 52usize, 24usize); +add_sub_const_decimals!(38usize, 13usize, 51usize, 25usize); +add_sub_const_decimals!(38usize, 12usize, 50usize, 26usize); +add_sub_const_decimals!(38usize, 11usize, 49usize, 27usize); +add_sub_const_decimals!(38usize, 10usize, 48usize, 28usize); +add_sub_const_decimals!(38usize, 9usize, 47usize, 29usize); +add_sub_const_decimals!(38usize, 8usize, 46usize, 30usize); +add_sub_const_decimals!(38usize, 7usize, 45usize, 31usize); +add_sub_const_decimals!(38usize, 6usize, 44usize, 32usize); +add_sub_const_decimals!(38usize, 5usize, 43usize, 33usize); +add_sub_const_decimals!(38usize, 4usize, 42usize, 34usize); +add_sub_const_decimals!(38usize, 3usize, 41usize, 35usize); +add_sub_const_decimals!(38usize, 2usize, 40usize, 36usize); +add_sub_const_decimals!(38usize, 1usize, 39usize, 37usize); +add_sub_const_decimals!(38usize, 0usize, 38usize, 38usize); +add_sub_const_decimals!(37usize, 64usize, 101usize, 0usize); +add_sub_const_decimals!(37usize, 63usize, 100usize, 0usize); +add_sub_const_decimals!(37usize, 62usize, 99usize, 0usize); +add_sub_const_decimals!(37usize, 61usize, 98usize, 0usize); +add_sub_const_decimals!(37usize, 60usize, 97usize, 0usize); +add_sub_const_decimals!(37usize, 59usize, 96usize, 0usize); +add_sub_const_decimals!(37usize, 58usize, 95usize, 0usize); +add_sub_const_decimals!(37usize, 57usize, 94usize, 0usize); +add_sub_const_decimals!(37usize, 56usize, 93usize, 0usize); +add_sub_const_decimals!(37usize, 55usize, 92usize, 0usize); +add_sub_const_decimals!(37usize, 54usize, 91usize, 0usize); +add_sub_const_decimals!(37usize, 53usize, 90usize, 0usize); +add_sub_const_decimals!(37usize, 52usize, 89usize, 0usize); +add_sub_const_decimals!(37usize, 51usize, 88usize, 0usize); +add_sub_const_decimals!(37usize, 50usize, 87usize, 0usize); +add_sub_const_decimals!(37usize, 49usize, 86usize, 0usize); +add_sub_const_decimals!(37usize, 48usize, 85usize, 0usize); +add_sub_const_decimals!(37usize, 47usize, 84usize, 0usize); +add_sub_const_decimals!(37usize, 46usize, 83usize, 0usize); +add_sub_const_decimals!(37usize, 45usize, 82usize, 0usize); +add_sub_const_decimals!(37usize, 44usize, 81usize, 0usize); +add_sub_const_decimals!(37usize, 43usize, 80usize, 0usize); +add_sub_const_decimals!(37usize, 42usize, 79usize, 0usize); +add_sub_const_decimals!(37usize, 41usize, 78usize, 0usize); +add_sub_const_decimals!(37usize, 40usize, 77usize, 0usize); +add_sub_const_decimals!(37usize, 39usize, 76usize, 0usize); +add_sub_const_decimals!(37usize, 38usize, 75usize, 0usize); +add_sub_const_decimals!(37usize, 37usize, 74usize, 0usize); +add_sub_const_decimals!(37usize, 36usize, 73usize, 1usize); +add_sub_const_decimals!(37usize, 35usize, 72usize, 2usize); +add_sub_const_decimals!(37usize, 34usize, 71usize, 3usize); +add_sub_const_decimals!(37usize, 33usize, 70usize, 4usize); +add_sub_const_decimals!(37usize, 32usize, 69usize, 5usize); +add_sub_const_decimals!(37usize, 31usize, 68usize, 6usize); +add_sub_const_decimals!(37usize, 30usize, 67usize, 7usize); +add_sub_const_decimals!(37usize, 29usize, 66usize, 8usize); +add_sub_const_decimals!(37usize, 28usize, 65usize, 9usize); +add_sub_const_decimals!(37usize, 27usize, 64usize, 10usize); +add_sub_const_decimals!(37usize, 26usize, 63usize, 11usize); +add_sub_const_decimals!(37usize, 25usize, 62usize, 12usize); +add_sub_const_decimals!(37usize, 24usize, 61usize, 13usize); +add_sub_const_decimals!(37usize, 23usize, 60usize, 14usize); +add_sub_const_decimals!(37usize, 22usize, 59usize, 15usize); +add_sub_const_decimals!(37usize, 21usize, 58usize, 16usize); +add_sub_const_decimals!(37usize, 20usize, 57usize, 17usize); +add_sub_const_decimals!(37usize, 19usize, 56usize, 18usize); +add_sub_const_decimals!(37usize, 18usize, 55usize, 19usize); +add_sub_const_decimals!(37usize, 17usize, 54usize, 20usize); +add_sub_const_decimals!(37usize, 16usize, 53usize, 21usize); +add_sub_const_decimals!(37usize, 15usize, 52usize, 22usize); +add_sub_const_decimals!(37usize, 14usize, 51usize, 23usize); +add_sub_const_decimals!(37usize, 13usize, 50usize, 24usize); +add_sub_const_decimals!(37usize, 12usize, 49usize, 25usize); +add_sub_const_decimals!(37usize, 11usize, 48usize, 26usize); +add_sub_const_decimals!(37usize, 10usize, 47usize, 27usize); +add_sub_const_decimals!(37usize, 9usize, 46usize, 28usize); +add_sub_const_decimals!(37usize, 8usize, 45usize, 29usize); +add_sub_const_decimals!(37usize, 7usize, 44usize, 30usize); +add_sub_const_decimals!(37usize, 6usize, 43usize, 31usize); +add_sub_const_decimals!(37usize, 5usize, 42usize, 32usize); +add_sub_const_decimals!(37usize, 4usize, 41usize, 33usize); +add_sub_const_decimals!(37usize, 3usize, 40usize, 34usize); +add_sub_const_decimals!(37usize, 2usize, 39usize, 35usize); +add_sub_const_decimals!(37usize, 1usize, 38usize, 36usize); +add_sub_const_decimals!(37usize, 0usize, 37usize, 37usize); +add_sub_const_decimals!(36usize, 64usize, 100usize, 0usize); +add_sub_const_decimals!(36usize, 63usize, 99usize, 0usize); +add_sub_const_decimals!(36usize, 62usize, 98usize, 0usize); +add_sub_const_decimals!(36usize, 61usize, 97usize, 0usize); +add_sub_const_decimals!(36usize, 60usize, 96usize, 0usize); +add_sub_const_decimals!(36usize, 59usize, 95usize, 0usize); +add_sub_const_decimals!(36usize, 58usize, 94usize, 0usize); +add_sub_const_decimals!(36usize, 57usize, 93usize, 0usize); +add_sub_const_decimals!(36usize, 56usize, 92usize, 0usize); +add_sub_const_decimals!(36usize, 55usize, 91usize, 0usize); +add_sub_const_decimals!(36usize, 54usize, 90usize, 0usize); +add_sub_const_decimals!(36usize, 53usize, 89usize, 0usize); +add_sub_const_decimals!(36usize, 52usize, 88usize, 0usize); +add_sub_const_decimals!(36usize, 51usize, 87usize, 0usize); +add_sub_const_decimals!(36usize, 50usize, 86usize, 0usize); +add_sub_const_decimals!(36usize, 49usize, 85usize, 0usize); +add_sub_const_decimals!(36usize, 48usize, 84usize, 0usize); +add_sub_const_decimals!(36usize, 47usize, 83usize, 0usize); +add_sub_const_decimals!(36usize, 46usize, 82usize, 0usize); +add_sub_const_decimals!(36usize, 45usize, 81usize, 0usize); +add_sub_const_decimals!(36usize, 44usize, 80usize, 0usize); +add_sub_const_decimals!(36usize, 43usize, 79usize, 0usize); +add_sub_const_decimals!(36usize, 42usize, 78usize, 0usize); +add_sub_const_decimals!(36usize, 41usize, 77usize, 0usize); +add_sub_const_decimals!(36usize, 40usize, 76usize, 0usize); +add_sub_const_decimals!(36usize, 39usize, 75usize, 0usize); +add_sub_const_decimals!(36usize, 38usize, 74usize, 0usize); +add_sub_const_decimals!(36usize, 37usize, 73usize, 0usize); +add_sub_const_decimals!(36usize, 36usize, 72usize, 0usize); +add_sub_const_decimals!(36usize, 35usize, 71usize, 1usize); +add_sub_const_decimals!(36usize, 34usize, 70usize, 2usize); +add_sub_const_decimals!(36usize, 33usize, 69usize, 3usize); +add_sub_const_decimals!(36usize, 32usize, 68usize, 4usize); +add_sub_const_decimals!(36usize, 31usize, 67usize, 5usize); +add_sub_const_decimals!(36usize, 30usize, 66usize, 6usize); +add_sub_const_decimals!(36usize, 29usize, 65usize, 7usize); +add_sub_const_decimals!(36usize, 28usize, 64usize, 8usize); +add_sub_const_decimals!(36usize, 27usize, 63usize, 9usize); +add_sub_const_decimals!(36usize, 26usize, 62usize, 10usize); +add_sub_const_decimals!(36usize, 25usize, 61usize, 11usize); +add_sub_const_decimals!(36usize, 24usize, 60usize, 12usize); +add_sub_const_decimals!(36usize, 23usize, 59usize, 13usize); +add_sub_const_decimals!(36usize, 22usize, 58usize, 14usize); +add_sub_const_decimals!(36usize, 21usize, 57usize, 15usize); +add_sub_const_decimals!(36usize, 20usize, 56usize, 16usize); +add_sub_const_decimals!(36usize, 19usize, 55usize, 17usize); +add_sub_const_decimals!(36usize, 18usize, 54usize, 18usize); +add_sub_const_decimals!(36usize, 17usize, 53usize, 19usize); +add_sub_const_decimals!(36usize, 16usize, 52usize, 20usize); +add_sub_const_decimals!(36usize, 15usize, 51usize, 21usize); +add_sub_const_decimals!(36usize, 14usize, 50usize, 22usize); +add_sub_const_decimals!(36usize, 13usize, 49usize, 23usize); +add_sub_const_decimals!(36usize, 12usize, 48usize, 24usize); +add_sub_const_decimals!(36usize, 11usize, 47usize, 25usize); +add_sub_const_decimals!(36usize, 10usize, 46usize, 26usize); +add_sub_const_decimals!(36usize, 9usize, 45usize, 27usize); +add_sub_const_decimals!(36usize, 8usize, 44usize, 28usize); +add_sub_const_decimals!(36usize, 7usize, 43usize, 29usize); +add_sub_const_decimals!(36usize, 6usize, 42usize, 30usize); +add_sub_const_decimals!(36usize, 5usize, 41usize, 31usize); +add_sub_const_decimals!(36usize, 4usize, 40usize, 32usize); +add_sub_const_decimals!(36usize, 3usize, 39usize, 33usize); +add_sub_const_decimals!(36usize, 2usize, 38usize, 34usize); +add_sub_const_decimals!(36usize, 1usize, 37usize, 35usize); +add_sub_const_decimals!(36usize, 0usize, 36usize, 36usize); +add_sub_const_decimals!(35usize, 64usize, 99usize, 0usize); +add_sub_const_decimals!(35usize, 63usize, 98usize, 0usize); +add_sub_const_decimals!(35usize, 62usize, 97usize, 0usize); +add_sub_const_decimals!(35usize, 61usize, 96usize, 0usize); +add_sub_const_decimals!(35usize, 60usize, 95usize, 0usize); +add_sub_const_decimals!(35usize, 59usize, 94usize, 0usize); +add_sub_const_decimals!(35usize, 58usize, 93usize, 0usize); +add_sub_const_decimals!(35usize, 57usize, 92usize, 0usize); +add_sub_const_decimals!(35usize, 56usize, 91usize, 0usize); +add_sub_const_decimals!(35usize, 55usize, 90usize, 0usize); +add_sub_const_decimals!(35usize, 54usize, 89usize, 0usize); +add_sub_const_decimals!(35usize, 53usize, 88usize, 0usize); +add_sub_const_decimals!(35usize, 52usize, 87usize, 0usize); +add_sub_const_decimals!(35usize, 51usize, 86usize, 0usize); +add_sub_const_decimals!(35usize, 50usize, 85usize, 0usize); +add_sub_const_decimals!(35usize, 49usize, 84usize, 0usize); +add_sub_const_decimals!(35usize, 48usize, 83usize, 0usize); +add_sub_const_decimals!(35usize, 47usize, 82usize, 0usize); +add_sub_const_decimals!(35usize, 46usize, 81usize, 0usize); +add_sub_const_decimals!(35usize, 45usize, 80usize, 0usize); +add_sub_const_decimals!(35usize, 44usize, 79usize, 0usize); +add_sub_const_decimals!(35usize, 43usize, 78usize, 0usize); +add_sub_const_decimals!(35usize, 42usize, 77usize, 0usize); +add_sub_const_decimals!(35usize, 41usize, 76usize, 0usize); +add_sub_const_decimals!(35usize, 40usize, 75usize, 0usize); +add_sub_const_decimals!(35usize, 39usize, 74usize, 0usize); +add_sub_const_decimals!(35usize, 38usize, 73usize, 0usize); +add_sub_const_decimals!(35usize, 37usize, 72usize, 0usize); +add_sub_const_decimals!(35usize, 36usize, 71usize, 0usize); +add_sub_const_decimals!(35usize, 35usize, 70usize, 0usize); +add_sub_const_decimals!(35usize, 34usize, 69usize, 1usize); +add_sub_const_decimals!(35usize, 33usize, 68usize, 2usize); +add_sub_const_decimals!(35usize, 32usize, 67usize, 3usize); +add_sub_const_decimals!(35usize, 31usize, 66usize, 4usize); +add_sub_const_decimals!(35usize, 30usize, 65usize, 5usize); +add_sub_const_decimals!(35usize, 29usize, 64usize, 6usize); +add_sub_const_decimals!(35usize, 28usize, 63usize, 7usize); +add_sub_const_decimals!(35usize, 27usize, 62usize, 8usize); +add_sub_const_decimals!(35usize, 26usize, 61usize, 9usize); +add_sub_const_decimals!(35usize, 25usize, 60usize, 10usize); +add_sub_const_decimals!(35usize, 24usize, 59usize, 11usize); +add_sub_const_decimals!(35usize, 23usize, 58usize, 12usize); +add_sub_const_decimals!(35usize, 22usize, 57usize, 13usize); +add_sub_const_decimals!(35usize, 21usize, 56usize, 14usize); +add_sub_const_decimals!(35usize, 20usize, 55usize, 15usize); +add_sub_const_decimals!(35usize, 19usize, 54usize, 16usize); +add_sub_const_decimals!(35usize, 18usize, 53usize, 17usize); +add_sub_const_decimals!(35usize, 17usize, 52usize, 18usize); +add_sub_const_decimals!(35usize, 16usize, 51usize, 19usize); +add_sub_const_decimals!(35usize, 15usize, 50usize, 20usize); +add_sub_const_decimals!(35usize, 14usize, 49usize, 21usize); +add_sub_const_decimals!(35usize, 13usize, 48usize, 22usize); +add_sub_const_decimals!(35usize, 12usize, 47usize, 23usize); +add_sub_const_decimals!(35usize, 11usize, 46usize, 24usize); +add_sub_const_decimals!(35usize, 10usize, 45usize, 25usize); +add_sub_const_decimals!(35usize, 9usize, 44usize, 26usize); +add_sub_const_decimals!(35usize, 8usize, 43usize, 27usize); +add_sub_const_decimals!(35usize, 7usize, 42usize, 28usize); +add_sub_const_decimals!(35usize, 6usize, 41usize, 29usize); +add_sub_const_decimals!(35usize, 5usize, 40usize, 30usize); +add_sub_const_decimals!(35usize, 4usize, 39usize, 31usize); +add_sub_const_decimals!(35usize, 3usize, 38usize, 32usize); +add_sub_const_decimals!(35usize, 2usize, 37usize, 33usize); +add_sub_const_decimals!(35usize, 1usize, 36usize, 34usize); +add_sub_const_decimals!(35usize, 0usize, 35usize, 35usize); +add_sub_const_decimals!(34usize, 64usize, 98usize, 0usize); +add_sub_const_decimals!(34usize, 63usize, 97usize, 0usize); +add_sub_const_decimals!(34usize, 62usize, 96usize, 0usize); +add_sub_const_decimals!(34usize, 61usize, 95usize, 0usize); +add_sub_const_decimals!(34usize, 60usize, 94usize, 0usize); +add_sub_const_decimals!(34usize, 59usize, 93usize, 0usize); +add_sub_const_decimals!(34usize, 58usize, 92usize, 0usize); +add_sub_const_decimals!(34usize, 57usize, 91usize, 0usize); +add_sub_const_decimals!(34usize, 56usize, 90usize, 0usize); +add_sub_const_decimals!(34usize, 55usize, 89usize, 0usize); +add_sub_const_decimals!(34usize, 54usize, 88usize, 0usize); +add_sub_const_decimals!(34usize, 53usize, 87usize, 0usize); +add_sub_const_decimals!(34usize, 52usize, 86usize, 0usize); +add_sub_const_decimals!(34usize, 51usize, 85usize, 0usize); +add_sub_const_decimals!(34usize, 50usize, 84usize, 0usize); +add_sub_const_decimals!(34usize, 49usize, 83usize, 0usize); +add_sub_const_decimals!(34usize, 48usize, 82usize, 0usize); +add_sub_const_decimals!(34usize, 47usize, 81usize, 0usize); +add_sub_const_decimals!(34usize, 46usize, 80usize, 0usize); +add_sub_const_decimals!(34usize, 45usize, 79usize, 0usize); +add_sub_const_decimals!(34usize, 44usize, 78usize, 0usize); +add_sub_const_decimals!(34usize, 43usize, 77usize, 0usize); +add_sub_const_decimals!(34usize, 42usize, 76usize, 0usize); +add_sub_const_decimals!(34usize, 41usize, 75usize, 0usize); +add_sub_const_decimals!(34usize, 40usize, 74usize, 0usize); +add_sub_const_decimals!(34usize, 39usize, 73usize, 0usize); +add_sub_const_decimals!(34usize, 38usize, 72usize, 0usize); +add_sub_const_decimals!(34usize, 37usize, 71usize, 0usize); +add_sub_const_decimals!(34usize, 36usize, 70usize, 0usize); +add_sub_const_decimals!(34usize, 35usize, 69usize, 0usize); +add_sub_const_decimals!(34usize, 34usize, 68usize, 0usize); +add_sub_const_decimals!(34usize, 33usize, 67usize, 1usize); +add_sub_const_decimals!(34usize, 32usize, 66usize, 2usize); +add_sub_const_decimals!(34usize, 31usize, 65usize, 3usize); +add_sub_const_decimals!(34usize, 30usize, 64usize, 4usize); +add_sub_const_decimals!(34usize, 29usize, 63usize, 5usize); +add_sub_const_decimals!(34usize, 28usize, 62usize, 6usize); +add_sub_const_decimals!(34usize, 27usize, 61usize, 7usize); +add_sub_const_decimals!(34usize, 26usize, 60usize, 8usize); +add_sub_const_decimals!(34usize, 25usize, 59usize, 9usize); +add_sub_const_decimals!(34usize, 24usize, 58usize, 10usize); +add_sub_const_decimals!(34usize, 23usize, 57usize, 11usize); +add_sub_const_decimals!(34usize, 22usize, 56usize, 12usize); +add_sub_const_decimals!(34usize, 21usize, 55usize, 13usize); +add_sub_const_decimals!(34usize, 20usize, 54usize, 14usize); +add_sub_const_decimals!(34usize, 19usize, 53usize, 15usize); +add_sub_const_decimals!(34usize, 18usize, 52usize, 16usize); +add_sub_const_decimals!(34usize, 17usize, 51usize, 17usize); +add_sub_const_decimals!(34usize, 16usize, 50usize, 18usize); +add_sub_const_decimals!(34usize, 15usize, 49usize, 19usize); +add_sub_const_decimals!(34usize, 14usize, 48usize, 20usize); +add_sub_const_decimals!(34usize, 13usize, 47usize, 21usize); +add_sub_const_decimals!(34usize, 12usize, 46usize, 22usize); +add_sub_const_decimals!(34usize, 11usize, 45usize, 23usize); +add_sub_const_decimals!(34usize, 10usize, 44usize, 24usize); +add_sub_const_decimals!(34usize, 9usize, 43usize, 25usize); +add_sub_const_decimals!(34usize, 8usize, 42usize, 26usize); +add_sub_const_decimals!(34usize, 7usize, 41usize, 27usize); +add_sub_const_decimals!(34usize, 6usize, 40usize, 28usize); +add_sub_const_decimals!(34usize, 5usize, 39usize, 29usize); +add_sub_const_decimals!(34usize, 4usize, 38usize, 30usize); +add_sub_const_decimals!(34usize, 3usize, 37usize, 31usize); +add_sub_const_decimals!(34usize, 2usize, 36usize, 32usize); +add_sub_const_decimals!(34usize, 1usize, 35usize, 33usize); +add_sub_const_decimals!(34usize, 0usize, 34usize, 34usize); +add_sub_const_decimals!(33usize, 64usize, 97usize, 0usize); +add_sub_const_decimals!(33usize, 63usize, 96usize, 0usize); +add_sub_const_decimals!(33usize, 62usize, 95usize, 0usize); +add_sub_const_decimals!(33usize, 61usize, 94usize, 0usize); +add_sub_const_decimals!(33usize, 60usize, 93usize, 0usize); +add_sub_const_decimals!(33usize, 59usize, 92usize, 0usize); +add_sub_const_decimals!(33usize, 58usize, 91usize, 0usize); +add_sub_const_decimals!(33usize, 57usize, 90usize, 0usize); +add_sub_const_decimals!(33usize, 56usize, 89usize, 0usize); +add_sub_const_decimals!(33usize, 55usize, 88usize, 0usize); +add_sub_const_decimals!(33usize, 54usize, 87usize, 0usize); +add_sub_const_decimals!(33usize, 53usize, 86usize, 0usize); +add_sub_const_decimals!(33usize, 52usize, 85usize, 0usize); +add_sub_const_decimals!(33usize, 51usize, 84usize, 0usize); +add_sub_const_decimals!(33usize, 50usize, 83usize, 0usize); +add_sub_const_decimals!(33usize, 49usize, 82usize, 0usize); +add_sub_const_decimals!(33usize, 48usize, 81usize, 0usize); +add_sub_const_decimals!(33usize, 47usize, 80usize, 0usize); +add_sub_const_decimals!(33usize, 46usize, 79usize, 0usize); +add_sub_const_decimals!(33usize, 45usize, 78usize, 0usize); +add_sub_const_decimals!(33usize, 44usize, 77usize, 0usize); +add_sub_const_decimals!(33usize, 43usize, 76usize, 0usize); +add_sub_const_decimals!(33usize, 42usize, 75usize, 0usize); +add_sub_const_decimals!(33usize, 41usize, 74usize, 0usize); +add_sub_const_decimals!(33usize, 40usize, 73usize, 0usize); +add_sub_const_decimals!(33usize, 39usize, 72usize, 0usize); +add_sub_const_decimals!(33usize, 38usize, 71usize, 0usize); +add_sub_const_decimals!(33usize, 37usize, 70usize, 0usize); +add_sub_const_decimals!(33usize, 36usize, 69usize, 0usize); +add_sub_const_decimals!(33usize, 35usize, 68usize, 0usize); +add_sub_const_decimals!(33usize, 34usize, 67usize, 0usize); +add_sub_const_decimals!(33usize, 33usize, 66usize, 0usize); +add_sub_const_decimals!(33usize, 32usize, 65usize, 1usize); +add_sub_const_decimals!(33usize, 31usize, 64usize, 2usize); +add_sub_const_decimals!(33usize, 30usize, 63usize, 3usize); +add_sub_const_decimals!(33usize, 29usize, 62usize, 4usize); +add_sub_const_decimals!(33usize, 28usize, 61usize, 5usize); +add_sub_const_decimals!(33usize, 27usize, 60usize, 6usize); +add_sub_const_decimals!(33usize, 26usize, 59usize, 7usize); +add_sub_const_decimals!(33usize, 25usize, 58usize, 8usize); +add_sub_const_decimals!(33usize, 24usize, 57usize, 9usize); +add_sub_const_decimals!(33usize, 23usize, 56usize, 10usize); +add_sub_const_decimals!(33usize, 22usize, 55usize, 11usize); +add_sub_const_decimals!(33usize, 21usize, 54usize, 12usize); +add_sub_const_decimals!(33usize, 20usize, 53usize, 13usize); +add_sub_const_decimals!(33usize, 19usize, 52usize, 14usize); +add_sub_const_decimals!(33usize, 18usize, 51usize, 15usize); +add_sub_const_decimals!(33usize, 17usize, 50usize, 16usize); +add_sub_const_decimals!(33usize, 16usize, 49usize, 17usize); +add_sub_const_decimals!(33usize, 15usize, 48usize, 18usize); +add_sub_const_decimals!(33usize, 14usize, 47usize, 19usize); +add_sub_const_decimals!(33usize, 13usize, 46usize, 20usize); +add_sub_const_decimals!(33usize, 12usize, 45usize, 21usize); +add_sub_const_decimals!(33usize, 11usize, 44usize, 22usize); +add_sub_const_decimals!(33usize, 10usize, 43usize, 23usize); +add_sub_const_decimals!(33usize, 9usize, 42usize, 24usize); +add_sub_const_decimals!(33usize, 8usize, 41usize, 25usize); +add_sub_const_decimals!(33usize, 7usize, 40usize, 26usize); +add_sub_const_decimals!(33usize, 6usize, 39usize, 27usize); +add_sub_const_decimals!(33usize, 5usize, 38usize, 28usize); +add_sub_const_decimals!(33usize, 4usize, 37usize, 29usize); +add_sub_const_decimals!(33usize, 3usize, 36usize, 30usize); +add_sub_const_decimals!(33usize, 2usize, 35usize, 31usize); +add_sub_const_decimals!(33usize, 1usize, 34usize, 32usize); +add_sub_const_decimals!(33usize, 0usize, 33usize, 33usize); +add_sub_const_decimals!(32usize, 64usize, 96usize, 0usize); +add_sub_const_decimals!(32usize, 63usize, 95usize, 0usize); +add_sub_const_decimals!(32usize, 62usize, 94usize, 0usize); +add_sub_const_decimals!(32usize, 61usize, 93usize, 0usize); +add_sub_const_decimals!(32usize, 60usize, 92usize, 0usize); +add_sub_const_decimals!(32usize, 59usize, 91usize, 0usize); +add_sub_const_decimals!(32usize, 58usize, 90usize, 0usize); +add_sub_const_decimals!(32usize, 57usize, 89usize, 0usize); +add_sub_const_decimals!(32usize, 56usize, 88usize, 0usize); +add_sub_const_decimals!(32usize, 55usize, 87usize, 0usize); +add_sub_const_decimals!(32usize, 54usize, 86usize, 0usize); +add_sub_const_decimals!(32usize, 53usize, 85usize, 0usize); +add_sub_const_decimals!(32usize, 52usize, 84usize, 0usize); +add_sub_const_decimals!(32usize, 51usize, 83usize, 0usize); +add_sub_const_decimals!(32usize, 50usize, 82usize, 0usize); +add_sub_const_decimals!(32usize, 49usize, 81usize, 0usize); +add_sub_const_decimals!(32usize, 48usize, 80usize, 0usize); +add_sub_const_decimals!(32usize, 47usize, 79usize, 0usize); +add_sub_const_decimals!(32usize, 46usize, 78usize, 0usize); +add_sub_const_decimals!(32usize, 45usize, 77usize, 0usize); +add_sub_const_decimals!(32usize, 44usize, 76usize, 0usize); +add_sub_const_decimals!(32usize, 43usize, 75usize, 0usize); +add_sub_const_decimals!(32usize, 42usize, 74usize, 0usize); +add_sub_const_decimals!(32usize, 41usize, 73usize, 0usize); +add_sub_const_decimals!(32usize, 40usize, 72usize, 0usize); +add_sub_const_decimals!(32usize, 39usize, 71usize, 0usize); +add_sub_const_decimals!(32usize, 38usize, 70usize, 0usize); +add_sub_const_decimals!(32usize, 37usize, 69usize, 0usize); +add_sub_const_decimals!(32usize, 36usize, 68usize, 0usize); +add_sub_const_decimals!(32usize, 35usize, 67usize, 0usize); +add_sub_const_decimals!(32usize, 34usize, 66usize, 0usize); +add_sub_const_decimals!(32usize, 33usize, 65usize, 0usize); +add_sub_const_decimals!(32usize, 32usize, 64usize, 0usize); +add_sub_const_decimals!(32usize, 31usize, 63usize, 1usize); +add_sub_const_decimals!(32usize, 30usize, 62usize, 2usize); +add_sub_const_decimals!(32usize, 29usize, 61usize, 3usize); +add_sub_const_decimals!(32usize, 28usize, 60usize, 4usize); +add_sub_const_decimals!(32usize, 27usize, 59usize, 5usize); +add_sub_const_decimals!(32usize, 26usize, 58usize, 6usize); +add_sub_const_decimals!(32usize, 25usize, 57usize, 7usize); +add_sub_const_decimals!(32usize, 24usize, 56usize, 8usize); +add_sub_const_decimals!(32usize, 23usize, 55usize, 9usize); +add_sub_const_decimals!(32usize, 22usize, 54usize, 10usize); +add_sub_const_decimals!(32usize, 21usize, 53usize, 11usize); +add_sub_const_decimals!(32usize, 20usize, 52usize, 12usize); +add_sub_const_decimals!(32usize, 19usize, 51usize, 13usize); +add_sub_const_decimals!(32usize, 18usize, 50usize, 14usize); +add_sub_const_decimals!(32usize, 17usize, 49usize, 15usize); +add_sub_const_decimals!(32usize, 16usize, 48usize, 16usize); +add_sub_const_decimals!(32usize, 15usize, 47usize, 17usize); +add_sub_const_decimals!(32usize, 14usize, 46usize, 18usize); +add_sub_const_decimals!(32usize, 13usize, 45usize, 19usize); +add_sub_const_decimals!(32usize, 12usize, 44usize, 20usize); +add_sub_const_decimals!(32usize, 11usize, 43usize, 21usize); +add_sub_const_decimals!(32usize, 10usize, 42usize, 22usize); +add_sub_const_decimals!(32usize, 9usize, 41usize, 23usize); +add_sub_const_decimals!(32usize, 8usize, 40usize, 24usize); +add_sub_const_decimals!(32usize, 7usize, 39usize, 25usize); +add_sub_const_decimals!(32usize, 6usize, 38usize, 26usize); +add_sub_const_decimals!(32usize, 5usize, 37usize, 27usize); +add_sub_const_decimals!(32usize, 4usize, 36usize, 28usize); +add_sub_const_decimals!(32usize, 3usize, 35usize, 29usize); +add_sub_const_decimals!(32usize, 2usize, 34usize, 30usize); +add_sub_const_decimals!(32usize, 1usize, 33usize, 31usize); +add_sub_const_decimals!(32usize, 0usize, 32usize, 32usize); +add_sub_const_decimals!(31usize, 64usize, 95usize, 0usize); +add_sub_const_decimals!(31usize, 63usize, 94usize, 0usize); +add_sub_const_decimals!(31usize, 62usize, 93usize, 0usize); +add_sub_const_decimals!(31usize, 61usize, 92usize, 0usize); +add_sub_const_decimals!(31usize, 60usize, 91usize, 0usize); +add_sub_const_decimals!(31usize, 59usize, 90usize, 0usize); +add_sub_const_decimals!(31usize, 58usize, 89usize, 0usize); +add_sub_const_decimals!(31usize, 57usize, 88usize, 0usize); +add_sub_const_decimals!(31usize, 56usize, 87usize, 0usize); +add_sub_const_decimals!(31usize, 55usize, 86usize, 0usize); +add_sub_const_decimals!(31usize, 54usize, 85usize, 0usize); +add_sub_const_decimals!(31usize, 53usize, 84usize, 0usize); +add_sub_const_decimals!(31usize, 52usize, 83usize, 0usize); +add_sub_const_decimals!(31usize, 51usize, 82usize, 0usize); +add_sub_const_decimals!(31usize, 50usize, 81usize, 0usize); +add_sub_const_decimals!(31usize, 49usize, 80usize, 0usize); +add_sub_const_decimals!(31usize, 48usize, 79usize, 0usize); +add_sub_const_decimals!(31usize, 47usize, 78usize, 0usize); +add_sub_const_decimals!(31usize, 46usize, 77usize, 0usize); +add_sub_const_decimals!(31usize, 45usize, 76usize, 0usize); +add_sub_const_decimals!(31usize, 44usize, 75usize, 0usize); +add_sub_const_decimals!(31usize, 43usize, 74usize, 0usize); +add_sub_const_decimals!(31usize, 42usize, 73usize, 0usize); +add_sub_const_decimals!(31usize, 41usize, 72usize, 0usize); +add_sub_const_decimals!(31usize, 40usize, 71usize, 0usize); +add_sub_const_decimals!(31usize, 39usize, 70usize, 0usize); +add_sub_const_decimals!(31usize, 38usize, 69usize, 0usize); +add_sub_const_decimals!(31usize, 37usize, 68usize, 0usize); +add_sub_const_decimals!(31usize, 36usize, 67usize, 0usize); +add_sub_const_decimals!(31usize, 35usize, 66usize, 0usize); +add_sub_const_decimals!(31usize, 34usize, 65usize, 0usize); +add_sub_const_decimals!(31usize, 33usize, 64usize, 0usize); +add_sub_const_decimals!(31usize, 32usize, 63usize, 0usize); +add_sub_const_decimals!(31usize, 31usize, 62usize, 0usize); +add_sub_const_decimals!(31usize, 30usize, 61usize, 1usize); +add_sub_const_decimals!(31usize, 29usize, 60usize, 2usize); +add_sub_const_decimals!(31usize, 28usize, 59usize, 3usize); +add_sub_const_decimals!(31usize, 27usize, 58usize, 4usize); +add_sub_const_decimals!(31usize, 26usize, 57usize, 5usize); +add_sub_const_decimals!(31usize, 25usize, 56usize, 6usize); +add_sub_const_decimals!(31usize, 24usize, 55usize, 7usize); +add_sub_const_decimals!(31usize, 23usize, 54usize, 8usize); +add_sub_const_decimals!(31usize, 22usize, 53usize, 9usize); +add_sub_const_decimals!(31usize, 21usize, 52usize, 10usize); +add_sub_const_decimals!(31usize, 20usize, 51usize, 11usize); +add_sub_const_decimals!(31usize, 19usize, 50usize, 12usize); +add_sub_const_decimals!(31usize, 18usize, 49usize, 13usize); +add_sub_const_decimals!(31usize, 17usize, 48usize, 14usize); +add_sub_const_decimals!(31usize, 16usize, 47usize, 15usize); +add_sub_const_decimals!(31usize, 15usize, 46usize, 16usize); +add_sub_const_decimals!(31usize, 14usize, 45usize, 17usize); +add_sub_const_decimals!(31usize, 13usize, 44usize, 18usize); +add_sub_const_decimals!(31usize, 12usize, 43usize, 19usize); +add_sub_const_decimals!(31usize, 11usize, 42usize, 20usize); +add_sub_const_decimals!(31usize, 10usize, 41usize, 21usize); +add_sub_const_decimals!(31usize, 9usize, 40usize, 22usize); +add_sub_const_decimals!(31usize, 8usize, 39usize, 23usize); +add_sub_const_decimals!(31usize, 7usize, 38usize, 24usize); +add_sub_const_decimals!(31usize, 6usize, 37usize, 25usize); +add_sub_const_decimals!(31usize, 5usize, 36usize, 26usize); +add_sub_const_decimals!(31usize, 4usize, 35usize, 27usize); +add_sub_const_decimals!(31usize, 3usize, 34usize, 28usize); +add_sub_const_decimals!(31usize, 2usize, 33usize, 29usize); +add_sub_const_decimals!(31usize, 1usize, 32usize, 30usize); +add_sub_const_decimals!(31usize, 0usize, 31usize, 31usize); +add_sub_const_decimals!(30usize, 64usize, 94usize, 0usize); +add_sub_const_decimals!(30usize, 63usize, 93usize, 0usize); +add_sub_const_decimals!(30usize, 62usize, 92usize, 0usize); +add_sub_const_decimals!(30usize, 61usize, 91usize, 0usize); +add_sub_const_decimals!(30usize, 60usize, 90usize, 0usize); +add_sub_const_decimals!(30usize, 59usize, 89usize, 0usize); +add_sub_const_decimals!(30usize, 58usize, 88usize, 0usize); +add_sub_const_decimals!(30usize, 57usize, 87usize, 0usize); +add_sub_const_decimals!(30usize, 56usize, 86usize, 0usize); +add_sub_const_decimals!(30usize, 55usize, 85usize, 0usize); +add_sub_const_decimals!(30usize, 54usize, 84usize, 0usize); +add_sub_const_decimals!(30usize, 53usize, 83usize, 0usize); +add_sub_const_decimals!(30usize, 52usize, 82usize, 0usize); +add_sub_const_decimals!(30usize, 51usize, 81usize, 0usize); +add_sub_const_decimals!(30usize, 50usize, 80usize, 0usize); +add_sub_const_decimals!(30usize, 49usize, 79usize, 0usize); +add_sub_const_decimals!(30usize, 48usize, 78usize, 0usize); +add_sub_const_decimals!(30usize, 47usize, 77usize, 0usize); +add_sub_const_decimals!(30usize, 46usize, 76usize, 0usize); +add_sub_const_decimals!(30usize, 45usize, 75usize, 0usize); +add_sub_const_decimals!(30usize, 44usize, 74usize, 0usize); +add_sub_const_decimals!(30usize, 43usize, 73usize, 0usize); +add_sub_const_decimals!(30usize, 42usize, 72usize, 0usize); +add_sub_const_decimals!(30usize, 41usize, 71usize, 0usize); +add_sub_const_decimals!(30usize, 40usize, 70usize, 0usize); +add_sub_const_decimals!(30usize, 39usize, 69usize, 0usize); +add_sub_const_decimals!(30usize, 38usize, 68usize, 0usize); +add_sub_const_decimals!(30usize, 37usize, 67usize, 0usize); +add_sub_const_decimals!(30usize, 36usize, 66usize, 0usize); +add_sub_const_decimals!(30usize, 35usize, 65usize, 0usize); +add_sub_const_decimals!(30usize, 34usize, 64usize, 0usize); +add_sub_const_decimals!(30usize, 33usize, 63usize, 0usize); +add_sub_const_decimals!(30usize, 32usize, 62usize, 0usize); +add_sub_const_decimals!(30usize, 31usize, 61usize, 0usize); +add_sub_const_decimals!(30usize, 30usize, 60usize, 0usize); +add_sub_const_decimals!(30usize, 29usize, 59usize, 1usize); +add_sub_const_decimals!(30usize, 28usize, 58usize, 2usize); +add_sub_const_decimals!(30usize, 27usize, 57usize, 3usize); +add_sub_const_decimals!(30usize, 26usize, 56usize, 4usize); +add_sub_const_decimals!(30usize, 25usize, 55usize, 5usize); +add_sub_const_decimals!(30usize, 24usize, 54usize, 6usize); +add_sub_const_decimals!(30usize, 23usize, 53usize, 7usize); +add_sub_const_decimals!(30usize, 22usize, 52usize, 8usize); +add_sub_const_decimals!(30usize, 21usize, 51usize, 9usize); +add_sub_const_decimals!(30usize, 20usize, 50usize, 10usize); +add_sub_const_decimals!(30usize, 19usize, 49usize, 11usize); +add_sub_const_decimals!(30usize, 18usize, 48usize, 12usize); +add_sub_const_decimals!(30usize, 17usize, 47usize, 13usize); +add_sub_const_decimals!(30usize, 16usize, 46usize, 14usize); +add_sub_const_decimals!(30usize, 15usize, 45usize, 15usize); +add_sub_const_decimals!(30usize, 14usize, 44usize, 16usize); +add_sub_const_decimals!(30usize, 13usize, 43usize, 17usize); +add_sub_const_decimals!(30usize, 12usize, 42usize, 18usize); +add_sub_const_decimals!(30usize, 11usize, 41usize, 19usize); +add_sub_const_decimals!(30usize, 10usize, 40usize, 20usize); +add_sub_const_decimals!(30usize, 9usize, 39usize, 21usize); +add_sub_const_decimals!(30usize, 8usize, 38usize, 22usize); +add_sub_const_decimals!(30usize, 7usize, 37usize, 23usize); +add_sub_const_decimals!(30usize, 6usize, 36usize, 24usize); +add_sub_const_decimals!(30usize, 5usize, 35usize, 25usize); +add_sub_const_decimals!(30usize, 4usize, 34usize, 26usize); +add_sub_const_decimals!(30usize, 3usize, 33usize, 27usize); +add_sub_const_decimals!(30usize, 2usize, 32usize, 28usize); +add_sub_const_decimals!(30usize, 1usize, 31usize, 29usize); +add_sub_const_decimals!(30usize, 0usize, 30usize, 30usize); +add_sub_const_decimals!(29usize, 64usize, 93usize, 0usize); +add_sub_const_decimals!(29usize, 63usize, 92usize, 0usize); +add_sub_const_decimals!(29usize, 62usize, 91usize, 0usize); +add_sub_const_decimals!(29usize, 61usize, 90usize, 0usize); +add_sub_const_decimals!(29usize, 60usize, 89usize, 0usize); +add_sub_const_decimals!(29usize, 59usize, 88usize, 0usize); +add_sub_const_decimals!(29usize, 58usize, 87usize, 0usize); +add_sub_const_decimals!(29usize, 57usize, 86usize, 0usize); +add_sub_const_decimals!(29usize, 56usize, 85usize, 0usize); +add_sub_const_decimals!(29usize, 55usize, 84usize, 0usize); +add_sub_const_decimals!(29usize, 54usize, 83usize, 0usize); +add_sub_const_decimals!(29usize, 53usize, 82usize, 0usize); +add_sub_const_decimals!(29usize, 52usize, 81usize, 0usize); +add_sub_const_decimals!(29usize, 51usize, 80usize, 0usize); +add_sub_const_decimals!(29usize, 50usize, 79usize, 0usize); +add_sub_const_decimals!(29usize, 49usize, 78usize, 0usize); +add_sub_const_decimals!(29usize, 48usize, 77usize, 0usize); +add_sub_const_decimals!(29usize, 47usize, 76usize, 0usize); +add_sub_const_decimals!(29usize, 46usize, 75usize, 0usize); +add_sub_const_decimals!(29usize, 45usize, 74usize, 0usize); +add_sub_const_decimals!(29usize, 44usize, 73usize, 0usize); +add_sub_const_decimals!(29usize, 43usize, 72usize, 0usize); +add_sub_const_decimals!(29usize, 42usize, 71usize, 0usize); +add_sub_const_decimals!(29usize, 41usize, 70usize, 0usize); +add_sub_const_decimals!(29usize, 40usize, 69usize, 0usize); +add_sub_const_decimals!(29usize, 39usize, 68usize, 0usize); +add_sub_const_decimals!(29usize, 38usize, 67usize, 0usize); +add_sub_const_decimals!(29usize, 37usize, 66usize, 0usize); +add_sub_const_decimals!(29usize, 36usize, 65usize, 0usize); +add_sub_const_decimals!(29usize, 35usize, 64usize, 0usize); +add_sub_const_decimals!(29usize, 34usize, 63usize, 0usize); +add_sub_const_decimals!(29usize, 33usize, 62usize, 0usize); +add_sub_const_decimals!(29usize, 32usize, 61usize, 0usize); +add_sub_const_decimals!(29usize, 31usize, 60usize, 0usize); +add_sub_const_decimals!(29usize, 30usize, 59usize, 0usize); +add_sub_const_decimals!(29usize, 29usize, 58usize, 0usize); +add_sub_const_decimals!(29usize, 28usize, 57usize, 1usize); +add_sub_const_decimals!(29usize, 27usize, 56usize, 2usize); +add_sub_const_decimals!(29usize, 26usize, 55usize, 3usize); +add_sub_const_decimals!(29usize, 25usize, 54usize, 4usize); +add_sub_const_decimals!(29usize, 24usize, 53usize, 5usize); +add_sub_const_decimals!(29usize, 23usize, 52usize, 6usize); +add_sub_const_decimals!(29usize, 22usize, 51usize, 7usize); +add_sub_const_decimals!(29usize, 21usize, 50usize, 8usize); +add_sub_const_decimals!(29usize, 20usize, 49usize, 9usize); +add_sub_const_decimals!(29usize, 19usize, 48usize, 10usize); +add_sub_const_decimals!(29usize, 18usize, 47usize, 11usize); +add_sub_const_decimals!(29usize, 17usize, 46usize, 12usize); +add_sub_const_decimals!(29usize, 16usize, 45usize, 13usize); +add_sub_const_decimals!(29usize, 15usize, 44usize, 14usize); +add_sub_const_decimals!(29usize, 14usize, 43usize, 15usize); +add_sub_const_decimals!(29usize, 13usize, 42usize, 16usize); +add_sub_const_decimals!(29usize, 12usize, 41usize, 17usize); +add_sub_const_decimals!(29usize, 11usize, 40usize, 18usize); +add_sub_const_decimals!(29usize, 10usize, 39usize, 19usize); +add_sub_const_decimals!(29usize, 9usize, 38usize, 20usize); +add_sub_const_decimals!(29usize, 8usize, 37usize, 21usize); +add_sub_const_decimals!(29usize, 7usize, 36usize, 22usize); +add_sub_const_decimals!(29usize, 6usize, 35usize, 23usize); +add_sub_const_decimals!(29usize, 5usize, 34usize, 24usize); +add_sub_const_decimals!(29usize, 4usize, 33usize, 25usize); +add_sub_const_decimals!(29usize, 3usize, 32usize, 26usize); +add_sub_const_decimals!(29usize, 2usize, 31usize, 27usize); +add_sub_const_decimals!(29usize, 1usize, 30usize, 28usize); +add_sub_const_decimals!(29usize, 0usize, 29usize, 29usize); +add_sub_const_decimals!(28usize, 64usize, 92usize, 0usize); +add_sub_const_decimals!(28usize, 63usize, 91usize, 0usize); +add_sub_const_decimals!(28usize, 62usize, 90usize, 0usize); +add_sub_const_decimals!(28usize, 61usize, 89usize, 0usize); +add_sub_const_decimals!(28usize, 60usize, 88usize, 0usize); +add_sub_const_decimals!(28usize, 59usize, 87usize, 0usize); +add_sub_const_decimals!(28usize, 58usize, 86usize, 0usize); +add_sub_const_decimals!(28usize, 57usize, 85usize, 0usize); +add_sub_const_decimals!(28usize, 56usize, 84usize, 0usize); +add_sub_const_decimals!(28usize, 55usize, 83usize, 0usize); +add_sub_const_decimals!(28usize, 54usize, 82usize, 0usize); +add_sub_const_decimals!(28usize, 53usize, 81usize, 0usize); +add_sub_const_decimals!(28usize, 52usize, 80usize, 0usize); +add_sub_const_decimals!(28usize, 51usize, 79usize, 0usize); +add_sub_const_decimals!(28usize, 50usize, 78usize, 0usize); +add_sub_const_decimals!(28usize, 49usize, 77usize, 0usize); +add_sub_const_decimals!(28usize, 48usize, 76usize, 0usize); +add_sub_const_decimals!(28usize, 47usize, 75usize, 0usize); +add_sub_const_decimals!(28usize, 46usize, 74usize, 0usize); +add_sub_const_decimals!(28usize, 45usize, 73usize, 0usize); +add_sub_const_decimals!(28usize, 44usize, 72usize, 0usize); +add_sub_const_decimals!(28usize, 43usize, 71usize, 0usize); +add_sub_const_decimals!(28usize, 42usize, 70usize, 0usize); +add_sub_const_decimals!(28usize, 41usize, 69usize, 0usize); +add_sub_const_decimals!(28usize, 40usize, 68usize, 0usize); +add_sub_const_decimals!(28usize, 39usize, 67usize, 0usize); +add_sub_const_decimals!(28usize, 38usize, 66usize, 0usize); +add_sub_const_decimals!(28usize, 37usize, 65usize, 0usize); +add_sub_const_decimals!(28usize, 36usize, 64usize, 0usize); +add_sub_const_decimals!(28usize, 35usize, 63usize, 0usize); +add_sub_const_decimals!(28usize, 34usize, 62usize, 0usize); +add_sub_const_decimals!(28usize, 33usize, 61usize, 0usize); +add_sub_const_decimals!(28usize, 32usize, 60usize, 0usize); +add_sub_const_decimals!(28usize, 31usize, 59usize, 0usize); +add_sub_const_decimals!(28usize, 30usize, 58usize, 0usize); +add_sub_const_decimals!(28usize, 29usize, 57usize, 0usize); +add_sub_const_decimals!(28usize, 28usize, 56usize, 0usize); +add_sub_const_decimals!(28usize, 27usize, 55usize, 1usize); +add_sub_const_decimals!(28usize, 26usize, 54usize, 2usize); +add_sub_const_decimals!(28usize, 25usize, 53usize, 3usize); +add_sub_const_decimals!(28usize, 24usize, 52usize, 4usize); +add_sub_const_decimals!(28usize, 23usize, 51usize, 5usize); +add_sub_const_decimals!(28usize, 22usize, 50usize, 6usize); +add_sub_const_decimals!(28usize, 21usize, 49usize, 7usize); +add_sub_const_decimals!(28usize, 20usize, 48usize, 8usize); +add_sub_const_decimals!(28usize, 19usize, 47usize, 9usize); +add_sub_const_decimals!(28usize, 18usize, 46usize, 10usize); +add_sub_const_decimals!(28usize, 17usize, 45usize, 11usize); +add_sub_const_decimals!(28usize, 16usize, 44usize, 12usize); +add_sub_const_decimals!(28usize, 15usize, 43usize, 13usize); +add_sub_const_decimals!(28usize, 14usize, 42usize, 14usize); +add_sub_const_decimals!(28usize, 13usize, 41usize, 15usize); +add_sub_const_decimals!(28usize, 12usize, 40usize, 16usize); +add_sub_const_decimals!(28usize, 11usize, 39usize, 17usize); +add_sub_const_decimals!(28usize, 10usize, 38usize, 18usize); +add_sub_const_decimals!(28usize, 9usize, 37usize, 19usize); +add_sub_const_decimals!(28usize, 8usize, 36usize, 20usize); +add_sub_const_decimals!(28usize, 7usize, 35usize, 21usize); +add_sub_const_decimals!(28usize, 6usize, 34usize, 22usize); +add_sub_const_decimals!(28usize, 5usize, 33usize, 23usize); +add_sub_const_decimals!(28usize, 4usize, 32usize, 24usize); +add_sub_const_decimals!(28usize, 3usize, 31usize, 25usize); +add_sub_const_decimals!(28usize, 2usize, 30usize, 26usize); +add_sub_const_decimals!(28usize, 1usize, 29usize, 27usize); +add_sub_const_decimals!(28usize, 0usize, 28usize, 28usize); +add_sub_const_decimals!(27usize, 64usize, 91usize, 0usize); +add_sub_const_decimals!(27usize, 63usize, 90usize, 0usize); +add_sub_const_decimals!(27usize, 62usize, 89usize, 0usize); +add_sub_const_decimals!(27usize, 61usize, 88usize, 0usize); +add_sub_const_decimals!(27usize, 60usize, 87usize, 0usize); +add_sub_const_decimals!(27usize, 59usize, 86usize, 0usize); +add_sub_const_decimals!(27usize, 58usize, 85usize, 0usize); +add_sub_const_decimals!(27usize, 57usize, 84usize, 0usize); +add_sub_const_decimals!(27usize, 56usize, 83usize, 0usize); +add_sub_const_decimals!(27usize, 55usize, 82usize, 0usize); +add_sub_const_decimals!(27usize, 54usize, 81usize, 0usize); +add_sub_const_decimals!(27usize, 53usize, 80usize, 0usize); +add_sub_const_decimals!(27usize, 52usize, 79usize, 0usize); +add_sub_const_decimals!(27usize, 51usize, 78usize, 0usize); +add_sub_const_decimals!(27usize, 50usize, 77usize, 0usize); +add_sub_const_decimals!(27usize, 49usize, 76usize, 0usize); +add_sub_const_decimals!(27usize, 48usize, 75usize, 0usize); +add_sub_const_decimals!(27usize, 47usize, 74usize, 0usize); +add_sub_const_decimals!(27usize, 46usize, 73usize, 0usize); +add_sub_const_decimals!(27usize, 45usize, 72usize, 0usize); +add_sub_const_decimals!(27usize, 44usize, 71usize, 0usize); +add_sub_const_decimals!(27usize, 43usize, 70usize, 0usize); +add_sub_const_decimals!(27usize, 42usize, 69usize, 0usize); +add_sub_const_decimals!(27usize, 41usize, 68usize, 0usize); +add_sub_const_decimals!(27usize, 40usize, 67usize, 0usize); +add_sub_const_decimals!(27usize, 39usize, 66usize, 0usize); +add_sub_const_decimals!(27usize, 38usize, 65usize, 0usize); +add_sub_const_decimals!(27usize, 37usize, 64usize, 0usize); +add_sub_const_decimals!(27usize, 36usize, 63usize, 0usize); +add_sub_const_decimals!(27usize, 35usize, 62usize, 0usize); +add_sub_const_decimals!(27usize, 34usize, 61usize, 0usize); +add_sub_const_decimals!(27usize, 33usize, 60usize, 0usize); +add_sub_const_decimals!(27usize, 32usize, 59usize, 0usize); +add_sub_const_decimals!(27usize, 31usize, 58usize, 0usize); +add_sub_const_decimals!(27usize, 30usize, 57usize, 0usize); +add_sub_const_decimals!(27usize, 29usize, 56usize, 0usize); +add_sub_const_decimals!(27usize, 28usize, 55usize, 0usize); +add_sub_const_decimals!(27usize, 27usize, 54usize, 0usize); +add_sub_const_decimals!(27usize, 26usize, 53usize, 1usize); +add_sub_const_decimals!(27usize, 25usize, 52usize, 2usize); +add_sub_const_decimals!(27usize, 24usize, 51usize, 3usize); +add_sub_const_decimals!(27usize, 23usize, 50usize, 4usize); +add_sub_const_decimals!(27usize, 22usize, 49usize, 5usize); +add_sub_const_decimals!(27usize, 21usize, 48usize, 6usize); +add_sub_const_decimals!(27usize, 20usize, 47usize, 7usize); +add_sub_const_decimals!(27usize, 19usize, 46usize, 8usize); +add_sub_const_decimals!(27usize, 18usize, 45usize, 9usize); +add_sub_const_decimals!(27usize, 17usize, 44usize, 10usize); +add_sub_const_decimals!(27usize, 16usize, 43usize, 11usize); +add_sub_const_decimals!(27usize, 15usize, 42usize, 12usize); +add_sub_const_decimals!(27usize, 14usize, 41usize, 13usize); +add_sub_const_decimals!(27usize, 13usize, 40usize, 14usize); +add_sub_const_decimals!(27usize, 12usize, 39usize, 15usize); +add_sub_const_decimals!(27usize, 11usize, 38usize, 16usize); +add_sub_const_decimals!(27usize, 10usize, 37usize, 17usize); +add_sub_const_decimals!(27usize, 9usize, 36usize, 18usize); +add_sub_const_decimals!(27usize, 8usize, 35usize, 19usize); +add_sub_const_decimals!(27usize, 7usize, 34usize, 20usize); +add_sub_const_decimals!(27usize, 6usize, 33usize, 21usize); +add_sub_const_decimals!(27usize, 5usize, 32usize, 22usize); +add_sub_const_decimals!(27usize, 4usize, 31usize, 23usize); +add_sub_const_decimals!(27usize, 3usize, 30usize, 24usize); +add_sub_const_decimals!(27usize, 2usize, 29usize, 25usize); +add_sub_const_decimals!(27usize, 1usize, 28usize, 26usize); +add_sub_const_decimals!(27usize, 0usize, 27usize, 27usize); +add_sub_const_decimals!(26usize, 64usize, 90usize, 0usize); +add_sub_const_decimals!(26usize, 63usize, 89usize, 0usize); +add_sub_const_decimals!(26usize, 62usize, 88usize, 0usize); +add_sub_const_decimals!(26usize, 61usize, 87usize, 0usize); +add_sub_const_decimals!(26usize, 60usize, 86usize, 0usize); +add_sub_const_decimals!(26usize, 59usize, 85usize, 0usize); +add_sub_const_decimals!(26usize, 58usize, 84usize, 0usize); +add_sub_const_decimals!(26usize, 57usize, 83usize, 0usize); +add_sub_const_decimals!(26usize, 56usize, 82usize, 0usize); +add_sub_const_decimals!(26usize, 55usize, 81usize, 0usize); +add_sub_const_decimals!(26usize, 54usize, 80usize, 0usize); +add_sub_const_decimals!(26usize, 53usize, 79usize, 0usize); +add_sub_const_decimals!(26usize, 52usize, 78usize, 0usize); +add_sub_const_decimals!(26usize, 51usize, 77usize, 0usize); +add_sub_const_decimals!(26usize, 50usize, 76usize, 0usize); +add_sub_const_decimals!(26usize, 49usize, 75usize, 0usize); +add_sub_const_decimals!(26usize, 48usize, 74usize, 0usize); +add_sub_const_decimals!(26usize, 47usize, 73usize, 0usize); +add_sub_const_decimals!(26usize, 46usize, 72usize, 0usize); +add_sub_const_decimals!(26usize, 45usize, 71usize, 0usize); +add_sub_const_decimals!(26usize, 44usize, 70usize, 0usize); +add_sub_const_decimals!(26usize, 43usize, 69usize, 0usize); +add_sub_const_decimals!(26usize, 42usize, 68usize, 0usize); +add_sub_const_decimals!(26usize, 41usize, 67usize, 0usize); +add_sub_const_decimals!(26usize, 40usize, 66usize, 0usize); +add_sub_const_decimals!(26usize, 39usize, 65usize, 0usize); +add_sub_const_decimals!(26usize, 38usize, 64usize, 0usize); +add_sub_const_decimals!(26usize, 37usize, 63usize, 0usize); +add_sub_const_decimals!(26usize, 36usize, 62usize, 0usize); +add_sub_const_decimals!(26usize, 35usize, 61usize, 0usize); +add_sub_const_decimals!(26usize, 34usize, 60usize, 0usize); +add_sub_const_decimals!(26usize, 33usize, 59usize, 0usize); +add_sub_const_decimals!(26usize, 32usize, 58usize, 0usize); +add_sub_const_decimals!(26usize, 31usize, 57usize, 0usize); +add_sub_const_decimals!(26usize, 30usize, 56usize, 0usize); +add_sub_const_decimals!(26usize, 29usize, 55usize, 0usize); +add_sub_const_decimals!(26usize, 28usize, 54usize, 0usize); +add_sub_const_decimals!(26usize, 27usize, 53usize, 0usize); +add_sub_const_decimals!(26usize, 26usize, 52usize, 0usize); +add_sub_const_decimals!(26usize, 25usize, 51usize, 1usize); +add_sub_const_decimals!(26usize, 24usize, 50usize, 2usize); +add_sub_const_decimals!(26usize, 23usize, 49usize, 3usize); +add_sub_const_decimals!(26usize, 22usize, 48usize, 4usize); +add_sub_const_decimals!(26usize, 21usize, 47usize, 5usize); +add_sub_const_decimals!(26usize, 20usize, 46usize, 6usize); +add_sub_const_decimals!(26usize, 19usize, 45usize, 7usize); +add_sub_const_decimals!(26usize, 18usize, 44usize, 8usize); +add_sub_const_decimals!(26usize, 17usize, 43usize, 9usize); +add_sub_const_decimals!(26usize, 16usize, 42usize, 10usize); +add_sub_const_decimals!(26usize, 15usize, 41usize, 11usize); +add_sub_const_decimals!(26usize, 14usize, 40usize, 12usize); +add_sub_const_decimals!(26usize, 13usize, 39usize, 13usize); +add_sub_const_decimals!(26usize, 12usize, 38usize, 14usize); +add_sub_const_decimals!(26usize, 11usize, 37usize, 15usize); +add_sub_const_decimals!(26usize, 10usize, 36usize, 16usize); +add_sub_const_decimals!(26usize, 9usize, 35usize, 17usize); +add_sub_const_decimals!(26usize, 8usize, 34usize, 18usize); +add_sub_const_decimals!(26usize, 7usize, 33usize, 19usize); +add_sub_const_decimals!(26usize, 6usize, 32usize, 20usize); +add_sub_const_decimals!(26usize, 5usize, 31usize, 21usize); +add_sub_const_decimals!(26usize, 4usize, 30usize, 22usize); +add_sub_const_decimals!(26usize, 3usize, 29usize, 23usize); +add_sub_const_decimals!(26usize, 2usize, 28usize, 24usize); +add_sub_const_decimals!(26usize, 1usize, 27usize, 25usize); +add_sub_const_decimals!(26usize, 0usize, 26usize, 26usize); +add_sub_const_decimals!(25usize, 64usize, 89usize, 0usize); +add_sub_const_decimals!(25usize, 63usize, 88usize, 0usize); +add_sub_const_decimals!(25usize, 62usize, 87usize, 0usize); +add_sub_const_decimals!(25usize, 61usize, 86usize, 0usize); +add_sub_const_decimals!(25usize, 60usize, 85usize, 0usize); +add_sub_const_decimals!(25usize, 59usize, 84usize, 0usize); +add_sub_const_decimals!(25usize, 58usize, 83usize, 0usize); +add_sub_const_decimals!(25usize, 57usize, 82usize, 0usize); +add_sub_const_decimals!(25usize, 56usize, 81usize, 0usize); +add_sub_const_decimals!(25usize, 55usize, 80usize, 0usize); +add_sub_const_decimals!(25usize, 54usize, 79usize, 0usize); +add_sub_const_decimals!(25usize, 53usize, 78usize, 0usize); +add_sub_const_decimals!(25usize, 52usize, 77usize, 0usize); +add_sub_const_decimals!(25usize, 51usize, 76usize, 0usize); +add_sub_const_decimals!(25usize, 50usize, 75usize, 0usize); +add_sub_const_decimals!(25usize, 49usize, 74usize, 0usize); +add_sub_const_decimals!(25usize, 48usize, 73usize, 0usize); +add_sub_const_decimals!(25usize, 47usize, 72usize, 0usize); +add_sub_const_decimals!(25usize, 46usize, 71usize, 0usize); +add_sub_const_decimals!(25usize, 45usize, 70usize, 0usize); +add_sub_const_decimals!(25usize, 44usize, 69usize, 0usize); +add_sub_const_decimals!(25usize, 43usize, 68usize, 0usize); +add_sub_const_decimals!(25usize, 42usize, 67usize, 0usize); +add_sub_const_decimals!(25usize, 41usize, 66usize, 0usize); +add_sub_const_decimals!(25usize, 40usize, 65usize, 0usize); +add_sub_const_decimals!(25usize, 39usize, 64usize, 0usize); +add_sub_const_decimals!(25usize, 38usize, 63usize, 0usize); +add_sub_const_decimals!(25usize, 37usize, 62usize, 0usize); +add_sub_const_decimals!(25usize, 36usize, 61usize, 0usize); +add_sub_const_decimals!(25usize, 35usize, 60usize, 0usize); +add_sub_const_decimals!(25usize, 34usize, 59usize, 0usize); +add_sub_const_decimals!(25usize, 33usize, 58usize, 0usize); +add_sub_const_decimals!(25usize, 32usize, 57usize, 0usize); +add_sub_const_decimals!(25usize, 31usize, 56usize, 0usize); +add_sub_const_decimals!(25usize, 30usize, 55usize, 0usize); +add_sub_const_decimals!(25usize, 29usize, 54usize, 0usize); +add_sub_const_decimals!(25usize, 28usize, 53usize, 0usize); +add_sub_const_decimals!(25usize, 27usize, 52usize, 0usize); +add_sub_const_decimals!(25usize, 26usize, 51usize, 0usize); +add_sub_const_decimals!(25usize, 25usize, 50usize, 0usize); +add_sub_const_decimals!(25usize, 24usize, 49usize, 1usize); +add_sub_const_decimals!(25usize, 23usize, 48usize, 2usize); +add_sub_const_decimals!(25usize, 22usize, 47usize, 3usize); +add_sub_const_decimals!(25usize, 21usize, 46usize, 4usize); +add_sub_const_decimals!(25usize, 20usize, 45usize, 5usize); +add_sub_const_decimals!(25usize, 19usize, 44usize, 6usize); +add_sub_const_decimals!(25usize, 18usize, 43usize, 7usize); +add_sub_const_decimals!(25usize, 17usize, 42usize, 8usize); +add_sub_const_decimals!(25usize, 16usize, 41usize, 9usize); +add_sub_const_decimals!(25usize, 15usize, 40usize, 10usize); +add_sub_const_decimals!(25usize, 14usize, 39usize, 11usize); +add_sub_const_decimals!(25usize, 13usize, 38usize, 12usize); +add_sub_const_decimals!(25usize, 12usize, 37usize, 13usize); +add_sub_const_decimals!(25usize, 11usize, 36usize, 14usize); +add_sub_const_decimals!(25usize, 10usize, 35usize, 15usize); +add_sub_const_decimals!(25usize, 9usize, 34usize, 16usize); +add_sub_const_decimals!(25usize, 8usize, 33usize, 17usize); +add_sub_const_decimals!(25usize, 7usize, 32usize, 18usize); +add_sub_const_decimals!(25usize, 6usize, 31usize, 19usize); +add_sub_const_decimals!(25usize, 5usize, 30usize, 20usize); +add_sub_const_decimals!(25usize, 4usize, 29usize, 21usize); +add_sub_const_decimals!(25usize, 3usize, 28usize, 22usize); +add_sub_const_decimals!(25usize, 2usize, 27usize, 23usize); +add_sub_const_decimals!(25usize, 1usize, 26usize, 24usize); +add_sub_const_decimals!(25usize, 0usize, 25usize, 25usize); +add_sub_const_decimals!(24usize, 64usize, 88usize, 0usize); +add_sub_const_decimals!(24usize, 63usize, 87usize, 0usize); +add_sub_const_decimals!(24usize, 62usize, 86usize, 0usize); +add_sub_const_decimals!(24usize, 61usize, 85usize, 0usize); +add_sub_const_decimals!(24usize, 60usize, 84usize, 0usize); +add_sub_const_decimals!(24usize, 59usize, 83usize, 0usize); +add_sub_const_decimals!(24usize, 58usize, 82usize, 0usize); +add_sub_const_decimals!(24usize, 57usize, 81usize, 0usize); +add_sub_const_decimals!(24usize, 56usize, 80usize, 0usize); +add_sub_const_decimals!(24usize, 55usize, 79usize, 0usize); +add_sub_const_decimals!(24usize, 54usize, 78usize, 0usize); +add_sub_const_decimals!(24usize, 53usize, 77usize, 0usize); +add_sub_const_decimals!(24usize, 52usize, 76usize, 0usize); +add_sub_const_decimals!(24usize, 51usize, 75usize, 0usize); +add_sub_const_decimals!(24usize, 50usize, 74usize, 0usize); +add_sub_const_decimals!(24usize, 49usize, 73usize, 0usize); +add_sub_const_decimals!(24usize, 48usize, 72usize, 0usize); +add_sub_const_decimals!(24usize, 47usize, 71usize, 0usize); +add_sub_const_decimals!(24usize, 46usize, 70usize, 0usize); +add_sub_const_decimals!(24usize, 45usize, 69usize, 0usize); +add_sub_const_decimals!(24usize, 44usize, 68usize, 0usize); +add_sub_const_decimals!(24usize, 43usize, 67usize, 0usize); +add_sub_const_decimals!(24usize, 42usize, 66usize, 0usize); +add_sub_const_decimals!(24usize, 41usize, 65usize, 0usize); +add_sub_const_decimals!(24usize, 40usize, 64usize, 0usize); +add_sub_const_decimals!(24usize, 39usize, 63usize, 0usize); +add_sub_const_decimals!(24usize, 38usize, 62usize, 0usize); +add_sub_const_decimals!(24usize, 37usize, 61usize, 0usize); +add_sub_const_decimals!(24usize, 36usize, 60usize, 0usize); +add_sub_const_decimals!(24usize, 35usize, 59usize, 0usize); +add_sub_const_decimals!(24usize, 34usize, 58usize, 0usize); +add_sub_const_decimals!(24usize, 33usize, 57usize, 0usize); +add_sub_const_decimals!(24usize, 32usize, 56usize, 0usize); +add_sub_const_decimals!(24usize, 31usize, 55usize, 0usize); +add_sub_const_decimals!(24usize, 30usize, 54usize, 0usize); +add_sub_const_decimals!(24usize, 29usize, 53usize, 0usize); +add_sub_const_decimals!(24usize, 28usize, 52usize, 0usize); +add_sub_const_decimals!(24usize, 27usize, 51usize, 0usize); +add_sub_const_decimals!(24usize, 26usize, 50usize, 0usize); +add_sub_const_decimals!(24usize, 25usize, 49usize, 0usize); +add_sub_const_decimals!(24usize, 24usize, 48usize, 0usize); +add_sub_const_decimals!(24usize, 23usize, 47usize, 1usize); +add_sub_const_decimals!(24usize, 22usize, 46usize, 2usize); +add_sub_const_decimals!(24usize, 21usize, 45usize, 3usize); +add_sub_const_decimals!(24usize, 20usize, 44usize, 4usize); +add_sub_const_decimals!(24usize, 19usize, 43usize, 5usize); +add_sub_const_decimals!(24usize, 18usize, 42usize, 6usize); +add_sub_const_decimals!(24usize, 17usize, 41usize, 7usize); +add_sub_const_decimals!(24usize, 16usize, 40usize, 8usize); +add_sub_const_decimals!(24usize, 15usize, 39usize, 9usize); +add_sub_const_decimals!(24usize, 14usize, 38usize, 10usize); +add_sub_const_decimals!(24usize, 13usize, 37usize, 11usize); +add_sub_const_decimals!(24usize, 12usize, 36usize, 12usize); +add_sub_const_decimals!(24usize, 11usize, 35usize, 13usize); +add_sub_const_decimals!(24usize, 10usize, 34usize, 14usize); +add_sub_const_decimals!(24usize, 9usize, 33usize, 15usize); +add_sub_const_decimals!(24usize, 8usize, 32usize, 16usize); +add_sub_const_decimals!(24usize, 7usize, 31usize, 17usize); +add_sub_const_decimals!(24usize, 6usize, 30usize, 18usize); +add_sub_const_decimals!(24usize, 5usize, 29usize, 19usize); +add_sub_const_decimals!(24usize, 4usize, 28usize, 20usize); +add_sub_const_decimals!(24usize, 3usize, 27usize, 21usize); +add_sub_const_decimals!(24usize, 2usize, 26usize, 22usize); +add_sub_const_decimals!(24usize, 1usize, 25usize, 23usize); +add_sub_const_decimals!(24usize, 0usize, 24usize, 24usize); +add_sub_const_decimals!(23usize, 64usize, 87usize, 0usize); +add_sub_const_decimals!(23usize, 63usize, 86usize, 0usize); +add_sub_const_decimals!(23usize, 62usize, 85usize, 0usize); +add_sub_const_decimals!(23usize, 61usize, 84usize, 0usize); +add_sub_const_decimals!(23usize, 60usize, 83usize, 0usize); +add_sub_const_decimals!(23usize, 59usize, 82usize, 0usize); +add_sub_const_decimals!(23usize, 58usize, 81usize, 0usize); +add_sub_const_decimals!(23usize, 57usize, 80usize, 0usize); +add_sub_const_decimals!(23usize, 56usize, 79usize, 0usize); +add_sub_const_decimals!(23usize, 55usize, 78usize, 0usize); +add_sub_const_decimals!(23usize, 54usize, 77usize, 0usize); +add_sub_const_decimals!(23usize, 53usize, 76usize, 0usize); +add_sub_const_decimals!(23usize, 52usize, 75usize, 0usize); +add_sub_const_decimals!(23usize, 51usize, 74usize, 0usize); +add_sub_const_decimals!(23usize, 50usize, 73usize, 0usize); +add_sub_const_decimals!(23usize, 49usize, 72usize, 0usize); +add_sub_const_decimals!(23usize, 48usize, 71usize, 0usize); +add_sub_const_decimals!(23usize, 47usize, 70usize, 0usize); +add_sub_const_decimals!(23usize, 46usize, 69usize, 0usize); +add_sub_const_decimals!(23usize, 45usize, 68usize, 0usize); +add_sub_const_decimals!(23usize, 44usize, 67usize, 0usize); +add_sub_const_decimals!(23usize, 43usize, 66usize, 0usize); +add_sub_const_decimals!(23usize, 42usize, 65usize, 0usize); +add_sub_const_decimals!(23usize, 41usize, 64usize, 0usize); +add_sub_const_decimals!(23usize, 40usize, 63usize, 0usize); +add_sub_const_decimals!(23usize, 39usize, 62usize, 0usize); +add_sub_const_decimals!(23usize, 38usize, 61usize, 0usize); +add_sub_const_decimals!(23usize, 37usize, 60usize, 0usize); +add_sub_const_decimals!(23usize, 36usize, 59usize, 0usize); +add_sub_const_decimals!(23usize, 35usize, 58usize, 0usize); +add_sub_const_decimals!(23usize, 34usize, 57usize, 0usize); +add_sub_const_decimals!(23usize, 33usize, 56usize, 0usize); +add_sub_const_decimals!(23usize, 32usize, 55usize, 0usize); +add_sub_const_decimals!(23usize, 31usize, 54usize, 0usize); +add_sub_const_decimals!(23usize, 30usize, 53usize, 0usize); +add_sub_const_decimals!(23usize, 29usize, 52usize, 0usize); +add_sub_const_decimals!(23usize, 28usize, 51usize, 0usize); +add_sub_const_decimals!(23usize, 27usize, 50usize, 0usize); +add_sub_const_decimals!(23usize, 26usize, 49usize, 0usize); +add_sub_const_decimals!(23usize, 25usize, 48usize, 0usize); +add_sub_const_decimals!(23usize, 24usize, 47usize, 0usize); +add_sub_const_decimals!(23usize, 23usize, 46usize, 0usize); +add_sub_const_decimals!(23usize, 22usize, 45usize, 1usize); +add_sub_const_decimals!(23usize, 21usize, 44usize, 2usize); +add_sub_const_decimals!(23usize, 20usize, 43usize, 3usize); +add_sub_const_decimals!(23usize, 19usize, 42usize, 4usize); +add_sub_const_decimals!(23usize, 18usize, 41usize, 5usize); +add_sub_const_decimals!(23usize, 17usize, 40usize, 6usize); +add_sub_const_decimals!(23usize, 16usize, 39usize, 7usize); +add_sub_const_decimals!(23usize, 15usize, 38usize, 8usize); +add_sub_const_decimals!(23usize, 14usize, 37usize, 9usize); +add_sub_const_decimals!(23usize, 13usize, 36usize, 10usize); +add_sub_const_decimals!(23usize, 12usize, 35usize, 11usize); +add_sub_const_decimals!(23usize, 11usize, 34usize, 12usize); +add_sub_const_decimals!(23usize, 10usize, 33usize, 13usize); +add_sub_const_decimals!(23usize, 9usize, 32usize, 14usize); +add_sub_const_decimals!(23usize, 8usize, 31usize, 15usize); +add_sub_const_decimals!(23usize, 7usize, 30usize, 16usize); +add_sub_const_decimals!(23usize, 6usize, 29usize, 17usize); +add_sub_const_decimals!(23usize, 5usize, 28usize, 18usize); +add_sub_const_decimals!(23usize, 4usize, 27usize, 19usize); +add_sub_const_decimals!(23usize, 3usize, 26usize, 20usize); +add_sub_const_decimals!(23usize, 2usize, 25usize, 21usize); +add_sub_const_decimals!(23usize, 1usize, 24usize, 22usize); +add_sub_const_decimals!(23usize, 0usize, 23usize, 23usize); +add_sub_const_decimals!(22usize, 64usize, 86usize, 0usize); +add_sub_const_decimals!(22usize, 63usize, 85usize, 0usize); +add_sub_const_decimals!(22usize, 62usize, 84usize, 0usize); +add_sub_const_decimals!(22usize, 61usize, 83usize, 0usize); +add_sub_const_decimals!(22usize, 60usize, 82usize, 0usize); +add_sub_const_decimals!(22usize, 59usize, 81usize, 0usize); +add_sub_const_decimals!(22usize, 58usize, 80usize, 0usize); +add_sub_const_decimals!(22usize, 57usize, 79usize, 0usize); +add_sub_const_decimals!(22usize, 56usize, 78usize, 0usize); +add_sub_const_decimals!(22usize, 55usize, 77usize, 0usize); +add_sub_const_decimals!(22usize, 54usize, 76usize, 0usize); +add_sub_const_decimals!(22usize, 53usize, 75usize, 0usize); +add_sub_const_decimals!(22usize, 52usize, 74usize, 0usize); +add_sub_const_decimals!(22usize, 51usize, 73usize, 0usize); +add_sub_const_decimals!(22usize, 50usize, 72usize, 0usize); +add_sub_const_decimals!(22usize, 49usize, 71usize, 0usize); +add_sub_const_decimals!(22usize, 48usize, 70usize, 0usize); +add_sub_const_decimals!(22usize, 47usize, 69usize, 0usize); +add_sub_const_decimals!(22usize, 46usize, 68usize, 0usize); +add_sub_const_decimals!(22usize, 45usize, 67usize, 0usize); +add_sub_const_decimals!(22usize, 44usize, 66usize, 0usize); +add_sub_const_decimals!(22usize, 43usize, 65usize, 0usize); +add_sub_const_decimals!(22usize, 42usize, 64usize, 0usize); +add_sub_const_decimals!(22usize, 41usize, 63usize, 0usize); +add_sub_const_decimals!(22usize, 40usize, 62usize, 0usize); +add_sub_const_decimals!(22usize, 39usize, 61usize, 0usize); +add_sub_const_decimals!(22usize, 38usize, 60usize, 0usize); +add_sub_const_decimals!(22usize, 37usize, 59usize, 0usize); +add_sub_const_decimals!(22usize, 36usize, 58usize, 0usize); +add_sub_const_decimals!(22usize, 35usize, 57usize, 0usize); +add_sub_const_decimals!(22usize, 34usize, 56usize, 0usize); +add_sub_const_decimals!(22usize, 33usize, 55usize, 0usize); +add_sub_const_decimals!(22usize, 32usize, 54usize, 0usize); +add_sub_const_decimals!(22usize, 31usize, 53usize, 0usize); +add_sub_const_decimals!(22usize, 30usize, 52usize, 0usize); +add_sub_const_decimals!(22usize, 29usize, 51usize, 0usize); +add_sub_const_decimals!(22usize, 28usize, 50usize, 0usize); +add_sub_const_decimals!(22usize, 27usize, 49usize, 0usize); +add_sub_const_decimals!(22usize, 26usize, 48usize, 0usize); +add_sub_const_decimals!(22usize, 25usize, 47usize, 0usize); +add_sub_const_decimals!(22usize, 24usize, 46usize, 0usize); +add_sub_const_decimals!(22usize, 23usize, 45usize, 0usize); +add_sub_const_decimals!(22usize, 22usize, 44usize, 0usize); +add_sub_const_decimals!(22usize, 21usize, 43usize, 1usize); +add_sub_const_decimals!(22usize, 20usize, 42usize, 2usize); +add_sub_const_decimals!(22usize, 19usize, 41usize, 3usize); +add_sub_const_decimals!(22usize, 18usize, 40usize, 4usize); +add_sub_const_decimals!(22usize, 17usize, 39usize, 5usize); +add_sub_const_decimals!(22usize, 16usize, 38usize, 6usize); +add_sub_const_decimals!(22usize, 15usize, 37usize, 7usize); +add_sub_const_decimals!(22usize, 14usize, 36usize, 8usize); +add_sub_const_decimals!(22usize, 13usize, 35usize, 9usize); +add_sub_const_decimals!(22usize, 12usize, 34usize, 10usize); +add_sub_const_decimals!(22usize, 11usize, 33usize, 11usize); +add_sub_const_decimals!(22usize, 10usize, 32usize, 12usize); +add_sub_const_decimals!(22usize, 9usize, 31usize, 13usize); +add_sub_const_decimals!(22usize, 8usize, 30usize, 14usize); +add_sub_const_decimals!(22usize, 7usize, 29usize, 15usize); +add_sub_const_decimals!(22usize, 6usize, 28usize, 16usize); +add_sub_const_decimals!(22usize, 5usize, 27usize, 17usize); +add_sub_const_decimals!(22usize, 4usize, 26usize, 18usize); +add_sub_const_decimals!(22usize, 3usize, 25usize, 19usize); +add_sub_const_decimals!(22usize, 2usize, 24usize, 20usize); +add_sub_const_decimals!(22usize, 1usize, 23usize, 21usize); +add_sub_const_decimals!(22usize, 0usize, 22usize, 22usize); +add_sub_const_decimals!(21usize, 64usize, 85usize, 0usize); +add_sub_const_decimals!(21usize, 63usize, 84usize, 0usize); +add_sub_const_decimals!(21usize, 62usize, 83usize, 0usize); +add_sub_const_decimals!(21usize, 61usize, 82usize, 0usize); +add_sub_const_decimals!(21usize, 60usize, 81usize, 0usize); +add_sub_const_decimals!(21usize, 59usize, 80usize, 0usize); +add_sub_const_decimals!(21usize, 58usize, 79usize, 0usize); +add_sub_const_decimals!(21usize, 57usize, 78usize, 0usize); +add_sub_const_decimals!(21usize, 56usize, 77usize, 0usize); +add_sub_const_decimals!(21usize, 55usize, 76usize, 0usize); +add_sub_const_decimals!(21usize, 54usize, 75usize, 0usize); +add_sub_const_decimals!(21usize, 53usize, 74usize, 0usize); +add_sub_const_decimals!(21usize, 52usize, 73usize, 0usize); +add_sub_const_decimals!(21usize, 51usize, 72usize, 0usize); +add_sub_const_decimals!(21usize, 50usize, 71usize, 0usize); +add_sub_const_decimals!(21usize, 49usize, 70usize, 0usize); +add_sub_const_decimals!(21usize, 48usize, 69usize, 0usize); +add_sub_const_decimals!(21usize, 47usize, 68usize, 0usize); +add_sub_const_decimals!(21usize, 46usize, 67usize, 0usize); +add_sub_const_decimals!(21usize, 45usize, 66usize, 0usize); +add_sub_const_decimals!(21usize, 44usize, 65usize, 0usize); +add_sub_const_decimals!(21usize, 43usize, 64usize, 0usize); +add_sub_const_decimals!(21usize, 42usize, 63usize, 0usize); +add_sub_const_decimals!(21usize, 41usize, 62usize, 0usize); +add_sub_const_decimals!(21usize, 40usize, 61usize, 0usize); +add_sub_const_decimals!(21usize, 39usize, 60usize, 0usize); +add_sub_const_decimals!(21usize, 38usize, 59usize, 0usize); +add_sub_const_decimals!(21usize, 37usize, 58usize, 0usize); +add_sub_const_decimals!(21usize, 36usize, 57usize, 0usize); +add_sub_const_decimals!(21usize, 35usize, 56usize, 0usize); +add_sub_const_decimals!(21usize, 34usize, 55usize, 0usize); +add_sub_const_decimals!(21usize, 33usize, 54usize, 0usize); +add_sub_const_decimals!(21usize, 32usize, 53usize, 0usize); +add_sub_const_decimals!(21usize, 31usize, 52usize, 0usize); +add_sub_const_decimals!(21usize, 30usize, 51usize, 0usize); +add_sub_const_decimals!(21usize, 29usize, 50usize, 0usize); +add_sub_const_decimals!(21usize, 28usize, 49usize, 0usize); +add_sub_const_decimals!(21usize, 27usize, 48usize, 0usize); +add_sub_const_decimals!(21usize, 26usize, 47usize, 0usize); +add_sub_const_decimals!(21usize, 25usize, 46usize, 0usize); +add_sub_const_decimals!(21usize, 24usize, 45usize, 0usize); +add_sub_const_decimals!(21usize, 23usize, 44usize, 0usize); +add_sub_const_decimals!(21usize, 22usize, 43usize, 0usize); +add_sub_const_decimals!(21usize, 21usize, 42usize, 0usize); +add_sub_const_decimals!(21usize, 20usize, 41usize, 1usize); +add_sub_const_decimals!(21usize, 19usize, 40usize, 2usize); +add_sub_const_decimals!(21usize, 18usize, 39usize, 3usize); +add_sub_const_decimals!(21usize, 17usize, 38usize, 4usize); +add_sub_const_decimals!(21usize, 16usize, 37usize, 5usize); +add_sub_const_decimals!(21usize, 15usize, 36usize, 6usize); +add_sub_const_decimals!(21usize, 14usize, 35usize, 7usize); +add_sub_const_decimals!(21usize, 13usize, 34usize, 8usize); +add_sub_const_decimals!(21usize, 12usize, 33usize, 9usize); +add_sub_const_decimals!(21usize, 11usize, 32usize, 10usize); +add_sub_const_decimals!(21usize, 10usize, 31usize, 11usize); +add_sub_const_decimals!(21usize, 9usize, 30usize, 12usize); +add_sub_const_decimals!(21usize, 8usize, 29usize, 13usize); +add_sub_const_decimals!(21usize, 7usize, 28usize, 14usize); +add_sub_const_decimals!(21usize, 6usize, 27usize, 15usize); +add_sub_const_decimals!(21usize, 5usize, 26usize, 16usize); +add_sub_const_decimals!(21usize, 4usize, 25usize, 17usize); +add_sub_const_decimals!(21usize, 3usize, 24usize, 18usize); +add_sub_const_decimals!(21usize, 2usize, 23usize, 19usize); +add_sub_const_decimals!(21usize, 1usize, 22usize, 20usize); +add_sub_const_decimals!(21usize, 0usize, 21usize, 21usize); +add_sub_const_decimals!(20usize, 64usize, 84usize, 0usize); +add_sub_const_decimals!(20usize, 63usize, 83usize, 0usize); +add_sub_const_decimals!(20usize, 62usize, 82usize, 0usize); +add_sub_const_decimals!(20usize, 61usize, 81usize, 0usize); +add_sub_const_decimals!(20usize, 60usize, 80usize, 0usize); +add_sub_const_decimals!(20usize, 59usize, 79usize, 0usize); +add_sub_const_decimals!(20usize, 58usize, 78usize, 0usize); +add_sub_const_decimals!(20usize, 57usize, 77usize, 0usize); +add_sub_const_decimals!(20usize, 56usize, 76usize, 0usize); +add_sub_const_decimals!(20usize, 55usize, 75usize, 0usize); +add_sub_const_decimals!(20usize, 54usize, 74usize, 0usize); +add_sub_const_decimals!(20usize, 53usize, 73usize, 0usize); +add_sub_const_decimals!(20usize, 52usize, 72usize, 0usize); +add_sub_const_decimals!(20usize, 51usize, 71usize, 0usize); +add_sub_const_decimals!(20usize, 50usize, 70usize, 0usize); +add_sub_const_decimals!(20usize, 49usize, 69usize, 0usize); +add_sub_const_decimals!(20usize, 48usize, 68usize, 0usize); +add_sub_const_decimals!(20usize, 47usize, 67usize, 0usize); +add_sub_const_decimals!(20usize, 46usize, 66usize, 0usize); +add_sub_const_decimals!(20usize, 45usize, 65usize, 0usize); +add_sub_const_decimals!(20usize, 44usize, 64usize, 0usize); +add_sub_const_decimals!(20usize, 43usize, 63usize, 0usize); +add_sub_const_decimals!(20usize, 42usize, 62usize, 0usize); +add_sub_const_decimals!(20usize, 41usize, 61usize, 0usize); +add_sub_const_decimals!(20usize, 40usize, 60usize, 0usize); +add_sub_const_decimals!(20usize, 39usize, 59usize, 0usize); +add_sub_const_decimals!(20usize, 38usize, 58usize, 0usize); +add_sub_const_decimals!(20usize, 37usize, 57usize, 0usize); +add_sub_const_decimals!(20usize, 36usize, 56usize, 0usize); +add_sub_const_decimals!(20usize, 35usize, 55usize, 0usize); +add_sub_const_decimals!(20usize, 34usize, 54usize, 0usize); +add_sub_const_decimals!(20usize, 33usize, 53usize, 0usize); +add_sub_const_decimals!(20usize, 32usize, 52usize, 0usize); +add_sub_const_decimals!(20usize, 31usize, 51usize, 0usize); +add_sub_const_decimals!(20usize, 30usize, 50usize, 0usize); +add_sub_const_decimals!(20usize, 29usize, 49usize, 0usize); +add_sub_const_decimals!(20usize, 28usize, 48usize, 0usize); +add_sub_const_decimals!(20usize, 27usize, 47usize, 0usize); +add_sub_const_decimals!(20usize, 26usize, 46usize, 0usize); +add_sub_const_decimals!(20usize, 25usize, 45usize, 0usize); +add_sub_const_decimals!(20usize, 24usize, 44usize, 0usize); +add_sub_const_decimals!(20usize, 23usize, 43usize, 0usize); +add_sub_const_decimals!(20usize, 22usize, 42usize, 0usize); +add_sub_const_decimals!(20usize, 21usize, 41usize, 0usize); +add_sub_const_decimals!(20usize, 20usize, 40usize, 0usize); +add_sub_const_decimals!(20usize, 19usize, 39usize, 1usize); +add_sub_const_decimals!(20usize, 18usize, 38usize, 2usize); +add_sub_const_decimals!(20usize, 17usize, 37usize, 3usize); +add_sub_const_decimals!(20usize, 16usize, 36usize, 4usize); +add_sub_const_decimals!(20usize, 15usize, 35usize, 5usize); +add_sub_const_decimals!(20usize, 14usize, 34usize, 6usize); +add_sub_const_decimals!(20usize, 13usize, 33usize, 7usize); +add_sub_const_decimals!(20usize, 12usize, 32usize, 8usize); +add_sub_const_decimals!(20usize, 11usize, 31usize, 9usize); +add_sub_const_decimals!(20usize, 10usize, 30usize, 10usize); +add_sub_const_decimals!(20usize, 9usize, 29usize, 11usize); +add_sub_const_decimals!(20usize, 8usize, 28usize, 12usize); +add_sub_const_decimals!(20usize, 7usize, 27usize, 13usize); +add_sub_const_decimals!(20usize, 6usize, 26usize, 14usize); +add_sub_const_decimals!(20usize, 5usize, 25usize, 15usize); +add_sub_const_decimals!(20usize, 4usize, 24usize, 16usize); +add_sub_const_decimals!(20usize, 3usize, 23usize, 17usize); +add_sub_const_decimals!(20usize, 2usize, 22usize, 18usize); +add_sub_const_decimals!(20usize, 1usize, 21usize, 19usize); +add_sub_const_decimals!(20usize, 0usize, 20usize, 20usize); +add_sub_const_decimals!(19usize, 64usize, 83usize, 0usize); +add_sub_const_decimals!(19usize, 63usize, 82usize, 0usize); +add_sub_const_decimals!(19usize, 62usize, 81usize, 0usize); +add_sub_const_decimals!(19usize, 61usize, 80usize, 0usize); +add_sub_const_decimals!(19usize, 60usize, 79usize, 0usize); +add_sub_const_decimals!(19usize, 59usize, 78usize, 0usize); +add_sub_const_decimals!(19usize, 58usize, 77usize, 0usize); +add_sub_const_decimals!(19usize, 57usize, 76usize, 0usize); +add_sub_const_decimals!(19usize, 56usize, 75usize, 0usize); +add_sub_const_decimals!(19usize, 55usize, 74usize, 0usize); +add_sub_const_decimals!(19usize, 54usize, 73usize, 0usize); +add_sub_const_decimals!(19usize, 53usize, 72usize, 0usize); +add_sub_const_decimals!(19usize, 52usize, 71usize, 0usize); +add_sub_const_decimals!(19usize, 51usize, 70usize, 0usize); +add_sub_const_decimals!(19usize, 50usize, 69usize, 0usize); +add_sub_const_decimals!(19usize, 49usize, 68usize, 0usize); +add_sub_const_decimals!(19usize, 48usize, 67usize, 0usize); +add_sub_const_decimals!(19usize, 47usize, 66usize, 0usize); +add_sub_const_decimals!(19usize, 46usize, 65usize, 0usize); +add_sub_const_decimals!(19usize, 45usize, 64usize, 0usize); +add_sub_const_decimals!(19usize, 44usize, 63usize, 0usize); +add_sub_const_decimals!(19usize, 43usize, 62usize, 0usize); +add_sub_const_decimals!(19usize, 42usize, 61usize, 0usize); +add_sub_const_decimals!(19usize, 41usize, 60usize, 0usize); +add_sub_const_decimals!(19usize, 40usize, 59usize, 0usize); +add_sub_const_decimals!(19usize, 39usize, 58usize, 0usize); +add_sub_const_decimals!(19usize, 38usize, 57usize, 0usize); +add_sub_const_decimals!(19usize, 37usize, 56usize, 0usize); +add_sub_const_decimals!(19usize, 36usize, 55usize, 0usize); +add_sub_const_decimals!(19usize, 35usize, 54usize, 0usize); +add_sub_const_decimals!(19usize, 34usize, 53usize, 0usize); +add_sub_const_decimals!(19usize, 33usize, 52usize, 0usize); +add_sub_const_decimals!(19usize, 32usize, 51usize, 0usize); +add_sub_const_decimals!(19usize, 31usize, 50usize, 0usize); +add_sub_const_decimals!(19usize, 30usize, 49usize, 0usize); +add_sub_const_decimals!(19usize, 29usize, 48usize, 0usize); +add_sub_const_decimals!(19usize, 28usize, 47usize, 0usize); +add_sub_const_decimals!(19usize, 27usize, 46usize, 0usize); +add_sub_const_decimals!(19usize, 26usize, 45usize, 0usize); +add_sub_const_decimals!(19usize, 25usize, 44usize, 0usize); +add_sub_const_decimals!(19usize, 24usize, 43usize, 0usize); +add_sub_const_decimals!(19usize, 23usize, 42usize, 0usize); +add_sub_const_decimals!(19usize, 22usize, 41usize, 0usize); +add_sub_const_decimals!(19usize, 21usize, 40usize, 0usize); +add_sub_const_decimals!(19usize, 20usize, 39usize, 0usize); +add_sub_const_decimals!(19usize, 19usize, 38usize, 0usize); +add_sub_const_decimals!(19usize, 18usize, 37usize, 1usize); +add_sub_const_decimals!(19usize, 17usize, 36usize, 2usize); +add_sub_const_decimals!(19usize, 16usize, 35usize, 3usize); +add_sub_const_decimals!(19usize, 15usize, 34usize, 4usize); +add_sub_const_decimals!(19usize, 14usize, 33usize, 5usize); +add_sub_const_decimals!(19usize, 13usize, 32usize, 6usize); +add_sub_const_decimals!(19usize, 12usize, 31usize, 7usize); +add_sub_const_decimals!(19usize, 11usize, 30usize, 8usize); +add_sub_const_decimals!(19usize, 10usize, 29usize, 9usize); +add_sub_const_decimals!(19usize, 9usize, 28usize, 10usize); +add_sub_const_decimals!(19usize, 8usize, 27usize, 11usize); +add_sub_const_decimals!(19usize, 7usize, 26usize, 12usize); +add_sub_const_decimals!(19usize, 6usize, 25usize, 13usize); +add_sub_const_decimals!(19usize, 5usize, 24usize, 14usize); +add_sub_const_decimals!(19usize, 4usize, 23usize, 15usize); +add_sub_const_decimals!(19usize, 3usize, 22usize, 16usize); +add_sub_const_decimals!(19usize, 2usize, 21usize, 17usize); +add_sub_const_decimals!(19usize, 1usize, 20usize, 18usize); +add_sub_const_decimals!(19usize, 0usize, 19usize, 19usize); +add_sub_const_decimals!(18usize, 64usize, 82usize, 0usize); +add_sub_const_decimals!(18usize, 63usize, 81usize, 0usize); +add_sub_const_decimals!(18usize, 62usize, 80usize, 0usize); +add_sub_const_decimals!(18usize, 61usize, 79usize, 0usize); +add_sub_const_decimals!(18usize, 60usize, 78usize, 0usize); +add_sub_const_decimals!(18usize, 59usize, 77usize, 0usize); +add_sub_const_decimals!(18usize, 58usize, 76usize, 0usize); +add_sub_const_decimals!(18usize, 57usize, 75usize, 0usize); +add_sub_const_decimals!(18usize, 56usize, 74usize, 0usize); +add_sub_const_decimals!(18usize, 55usize, 73usize, 0usize); +add_sub_const_decimals!(18usize, 54usize, 72usize, 0usize); +add_sub_const_decimals!(18usize, 53usize, 71usize, 0usize); +add_sub_const_decimals!(18usize, 52usize, 70usize, 0usize); +add_sub_const_decimals!(18usize, 51usize, 69usize, 0usize); +add_sub_const_decimals!(18usize, 50usize, 68usize, 0usize); +add_sub_const_decimals!(18usize, 49usize, 67usize, 0usize); +add_sub_const_decimals!(18usize, 48usize, 66usize, 0usize); +add_sub_const_decimals!(18usize, 47usize, 65usize, 0usize); +add_sub_const_decimals!(18usize, 46usize, 64usize, 0usize); +add_sub_const_decimals!(18usize, 45usize, 63usize, 0usize); +add_sub_const_decimals!(18usize, 44usize, 62usize, 0usize); +add_sub_const_decimals!(18usize, 43usize, 61usize, 0usize); +add_sub_const_decimals!(18usize, 42usize, 60usize, 0usize); +add_sub_const_decimals!(18usize, 41usize, 59usize, 0usize); +add_sub_const_decimals!(18usize, 40usize, 58usize, 0usize); +add_sub_const_decimals!(18usize, 39usize, 57usize, 0usize); +add_sub_const_decimals!(18usize, 38usize, 56usize, 0usize); +add_sub_const_decimals!(18usize, 37usize, 55usize, 0usize); +add_sub_const_decimals!(18usize, 36usize, 54usize, 0usize); +add_sub_const_decimals!(18usize, 35usize, 53usize, 0usize); +add_sub_const_decimals!(18usize, 34usize, 52usize, 0usize); +add_sub_const_decimals!(18usize, 33usize, 51usize, 0usize); +add_sub_const_decimals!(18usize, 32usize, 50usize, 0usize); +add_sub_const_decimals!(18usize, 31usize, 49usize, 0usize); +add_sub_const_decimals!(18usize, 30usize, 48usize, 0usize); +add_sub_const_decimals!(18usize, 29usize, 47usize, 0usize); +add_sub_const_decimals!(18usize, 28usize, 46usize, 0usize); +add_sub_const_decimals!(18usize, 27usize, 45usize, 0usize); +add_sub_const_decimals!(18usize, 26usize, 44usize, 0usize); +add_sub_const_decimals!(18usize, 25usize, 43usize, 0usize); +add_sub_const_decimals!(18usize, 24usize, 42usize, 0usize); +add_sub_const_decimals!(18usize, 23usize, 41usize, 0usize); +add_sub_const_decimals!(18usize, 22usize, 40usize, 0usize); +add_sub_const_decimals!(18usize, 21usize, 39usize, 0usize); +add_sub_const_decimals!(18usize, 20usize, 38usize, 0usize); +add_sub_const_decimals!(18usize, 19usize, 37usize, 0usize); +add_sub_const_decimals!(18usize, 18usize, 36usize, 0usize); +add_sub_const_decimals!(18usize, 17usize, 35usize, 1usize); +add_sub_const_decimals!(18usize, 16usize, 34usize, 2usize); +add_sub_const_decimals!(18usize, 15usize, 33usize, 3usize); +add_sub_const_decimals!(18usize, 14usize, 32usize, 4usize); +add_sub_const_decimals!(18usize, 13usize, 31usize, 5usize); +add_sub_const_decimals!(18usize, 12usize, 30usize, 6usize); +add_sub_const_decimals!(18usize, 11usize, 29usize, 7usize); +add_sub_const_decimals!(18usize, 10usize, 28usize, 8usize); +add_sub_const_decimals!(18usize, 9usize, 27usize, 9usize); +add_sub_const_decimals!(18usize, 8usize, 26usize, 10usize); +add_sub_const_decimals!(18usize, 7usize, 25usize, 11usize); +add_sub_const_decimals!(18usize, 6usize, 24usize, 12usize); +add_sub_const_decimals!(18usize, 5usize, 23usize, 13usize); +add_sub_const_decimals!(18usize, 4usize, 22usize, 14usize); +add_sub_const_decimals!(18usize, 3usize, 21usize, 15usize); +add_sub_const_decimals!(18usize, 2usize, 20usize, 16usize); +add_sub_const_decimals!(18usize, 1usize, 19usize, 17usize); +add_sub_const_decimals!(18usize, 0usize, 18usize, 18usize); +add_sub_const_decimals!(17usize, 64usize, 81usize, 0usize); +add_sub_const_decimals!(17usize, 63usize, 80usize, 0usize); +add_sub_const_decimals!(17usize, 62usize, 79usize, 0usize); +add_sub_const_decimals!(17usize, 61usize, 78usize, 0usize); +add_sub_const_decimals!(17usize, 60usize, 77usize, 0usize); +add_sub_const_decimals!(17usize, 59usize, 76usize, 0usize); +add_sub_const_decimals!(17usize, 58usize, 75usize, 0usize); +add_sub_const_decimals!(17usize, 57usize, 74usize, 0usize); +add_sub_const_decimals!(17usize, 56usize, 73usize, 0usize); +add_sub_const_decimals!(17usize, 55usize, 72usize, 0usize); +add_sub_const_decimals!(17usize, 54usize, 71usize, 0usize); +add_sub_const_decimals!(17usize, 53usize, 70usize, 0usize); +add_sub_const_decimals!(17usize, 52usize, 69usize, 0usize); +add_sub_const_decimals!(17usize, 51usize, 68usize, 0usize); +add_sub_const_decimals!(17usize, 50usize, 67usize, 0usize); +add_sub_const_decimals!(17usize, 49usize, 66usize, 0usize); +add_sub_const_decimals!(17usize, 48usize, 65usize, 0usize); +add_sub_const_decimals!(17usize, 47usize, 64usize, 0usize); +add_sub_const_decimals!(17usize, 46usize, 63usize, 0usize); +add_sub_const_decimals!(17usize, 45usize, 62usize, 0usize); +add_sub_const_decimals!(17usize, 44usize, 61usize, 0usize); +add_sub_const_decimals!(17usize, 43usize, 60usize, 0usize); +add_sub_const_decimals!(17usize, 42usize, 59usize, 0usize); +add_sub_const_decimals!(17usize, 41usize, 58usize, 0usize); +add_sub_const_decimals!(17usize, 40usize, 57usize, 0usize); +add_sub_const_decimals!(17usize, 39usize, 56usize, 0usize); +add_sub_const_decimals!(17usize, 38usize, 55usize, 0usize); +add_sub_const_decimals!(17usize, 37usize, 54usize, 0usize); +add_sub_const_decimals!(17usize, 36usize, 53usize, 0usize); +add_sub_const_decimals!(17usize, 35usize, 52usize, 0usize); +add_sub_const_decimals!(17usize, 34usize, 51usize, 0usize); +add_sub_const_decimals!(17usize, 33usize, 50usize, 0usize); +add_sub_const_decimals!(17usize, 32usize, 49usize, 0usize); +add_sub_const_decimals!(17usize, 31usize, 48usize, 0usize); +add_sub_const_decimals!(17usize, 30usize, 47usize, 0usize); +add_sub_const_decimals!(17usize, 29usize, 46usize, 0usize); +add_sub_const_decimals!(17usize, 28usize, 45usize, 0usize); +add_sub_const_decimals!(17usize, 27usize, 44usize, 0usize); +add_sub_const_decimals!(17usize, 26usize, 43usize, 0usize); +add_sub_const_decimals!(17usize, 25usize, 42usize, 0usize); +add_sub_const_decimals!(17usize, 24usize, 41usize, 0usize); +add_sub_const_decimals!(17usize, 23usize, 40usize, 0usize); +add_sub_const_decimals!(17usize, 22usize, 39usize, 0usize); +add_sub_const_decimals!(17usize, 21usize, 38usize, 0usize); +add_sub_const_decimals!(17usize, 20usize, 37usize, 0usize); +add_sub_const_decimals!(17usize, 19usize, 36usize, 0usize); +add_sub_const_decimals!(17usize, 18usize, 35usize, 0usize); +add_sub_const_decimals!(17usize, 17usize, 34usize, 0usize); +add_sub_const_decimals!(17usize, 16usize, 33usize, 1usize); +add_sub_const_decimals!(17usize, 15usize, 32usize, 2usize); +add_sub_const_decimals!(17usize, 14usize, 31usize, 3usize); +add_sub_const_decimals!(17usize, 13usize, 30usize, 4usize); +add_sub_const_decimals!(17usize, 12usize, 29usize, 5usize); +add_sub_const_decimals!(17usize, 11usize, 28usize, 6usize); +add_sub_const_decimals!(17usize, 10usize, 27usize, 7usize); +add_sub_const_decimals!(17usize, 9usize, 26usize, 8usize); +add_sub_const_decimals!(17usize, 8usize, 25usize, 9usize); +add_sub_const_decimals!(17usize, 7usize, 24usize, 10usize); +add_sub_const_decimals!(17usize, 6usize, 23usize, 11usize); +add_sub_const_decimals!(17usize, 5usize, 22usize, 12usize); +add_sub_const_decimals!(17usize, 4usize, 21usize, 13usize); +add_sub_const_decimals!(17usize, 3usize, 20usize, 14usize); +add_sub_const_decimals!(17usize, 2usize, 19usize, 15usize); +add_sub_const_decimals!(17usize, 1usize, 18usize, 16usize); +add_sub_const_decimals!(17usize, 0usize, 17usize, 17usize); +add_sub_const_decimals!(16usize, 64usize, 80usize, 0usize); +add_sub_const_decimals!(16usize, 63usize, 79usize, 0usize); +add_sub_const_decimals!(16usize, 62usize, 78usize, 0usize); +add_sub_const_decimals!(16usize, 61usize, 77usize, 0usize); +add_sub_const_decimals!(16usize, 60usize, 76usize, 0usize); +add_sub_const_decimals!(16usize, 59usize, 75usize, 0usize); +add_sub_const_decimals!(16usize, 58usize, 74usize, 0usize); +add_sub_const_decimals!(16usize, 57usize, 73usize, 0usize); +add_sub_const_decimals!(16usize, 56usize, 72usize, 0usize); +add_sub_const_decimals!(16usize, 55usize, 71usize, 0usize); +add_sub_const_decimals!(16usize, 54usize, 70usize, 0usize); +add_sub_const_decimals!(16usize, 53usize, 69usize, 0usize); +add_sub_const_decimals!(16usize, 52usize, 68usize, 0usize); +add_sub_const_decimals!(16usize, 51usize, 67usize, 0usize); +add_sub_const_decimals!(16usize, 50usize, 66usize, 0usize); +add_sub_const_decimals!(16usize, 49usize, 65usize, 0usize); +add_sub_const_decimals!(16usize, 48usize, 64usize, 0usize); +add_sub_const_decimals!(16usize, 47usize, 63usize, 0usize); +add_sub_const_decimals!(16usize, 46usize, 62usize, 0usize); +add_sub_const_decimals!(16usize, 45usize, 61usize, 0usize); +add_sub_const_decimals!(16usize, 44usize, 60usize, 0usize); +add_sub_const_decimals!(16usize, 43usize, 59usize, 0usize); +add_sub_const_decimals!(16usize, 42usize, 58usize, 0usize); +add_sub_const_decimals!(16usize, 41usize, 57usize, 0usize); +add_sub_const_decimals!(16usize, 40usize, 56usize, 0usize); +add_sub_const_decimals!(16usize, 39usize, 55usize, 0usize); +add_sub_const_decimals!(16usize, 38usize, 54usize, 0usize); +add_sub_const_decimals!(16usize, 37usize, 53usize, 0usize); +add_sub_const_decimals!(16usize, 36usize, 52usize, 0usize); +add_sub_const_decimals!(16usize, 35usize, 51usize, 0usize); +add_sub_const_decimals!(16usize, 34usize, 50usize, 0usize); +add_sub_const_decimals!(16usize, 33usize, 49usize, 0usize); +add_sub_const_decimals!(16usize, 32usize, 48usize, 0usize); +add_sub_const_decimals!(16usize, 31usize, 47usize, 0usize); +add_sub_const_decimals!(16usize, 30usize, 46usize, 0usize); +add_sub_const_decimals!(16usize, 29usize, 45usize, 0usize); +add_sub_const_decimals!(16usize, 28usize, 44usize, 0usize); +add_sub_const_decimals!(16usize, 27usize, 43usize, 0usize); +add_sub_const_decimals!(16usize, 26usize, 42usize, 0usize); +add_sub_const_decimals!(16usize, 25usize, 41usize, 0usize); +add_sub_const_decimals!(16usize, 24usize, 40usize, 0usize); +add_sub_const_decimals!(16usize, 23usize, 39usize, 0usize); +add_sub_const_decimals!(16usize, 22usize, 38usize, 0usize); +add_sub_const_decimals!(16usize, 21usize, 37usize, 0usize); +add_sub_const_decimals!(16usize, 20usize, 36usize, 0usize); +add_sub_const_decimals!(16usize, 19usize, 35usize, 0usize); +add_sub_const_decimals!(16usize, 18usize, 34usize, 0usize); +add_sub_const_decimals!(16usize, 17usize, 33usize, 0usize); +add_sub_const_decimals!(16usize, 16usize, 32usize, 0usize); +add_sub_const_decimals!(16usize, 15usize, 31usize, 1usize); +add_sub_const_decimals!(16usize, 14usize, 30usize, 2usize); +add_sub_const_decimals!(16usize, 13usize, 29usize, 3usize); +add_sub_const_decimals!(16usize, 12usize, 28usize, 4usize); +add_sub_const_decimals!(16usize, 11usize, 27usize, 5usize); +add_sub_const_decimals!(16usize, 10usize, 26usize, 6usize); +add_sub_const_decimals!(16usize, 9usize, 25usize, 7usize); +add_sub_const_decimals!(16usize, 8usize, 24usize, 8usize); +add_sub_const_decimals!(16usize, 7usize, 23usize, 9usize); +add_sub_const_decimals!(16usize, 6usize, 22usize, 10usize); +add_sub_const_decimals!(16usize, 5usize, 21usize, 11usize); +add_sub_const_decimals!(16usize, 4usize, 20usize, 12usize); +add_sub_const_decimals!(16usize, 3usize, 19usize, 13usize); +add_sub_const_decimals!(16usize, 2usize, 18usize, 14usize); +add_sub_const_decimals!(16usize, 1usize, 17usize, 15usize); +add_sub_const_decimals!(16usize, 0usize, 16usize, 16usize); +add_sub_const_decimals!(15usize, 64usize, 79usize, 0usize); +add_sub_const_decimals!(15usize, 63usize, 78usize, 0usize); +add_sub_const_decimals!(15usize, 62usize, 77usize, 0usize); +add_sub_const_decimals!(15usize, 61usize, 76usize, 0usize); +add_sub_const_decimals!(15usize, 60usize, 75usize, 0usize); +add_sub_const_decimals!(15usize, 59usize, 74usize, 0usize); +add_sub_const_decimals!(15usize, 58usize, 73usize, 0usize); +add_sub_const_decimals!(15usize, 57usize, 72usize, 0usize); +add_sub_const_decimals!(15usize, 56usize, 71usize, 0usize); +add_sub_const_decimals!(15usize, 55usize, 70usize, 0usize); +add_sub_const_decimals!(15usize, 54usize, 69usize, 0usize); +add_sub_const_decimals!(15usize, 53usize, 68usize, 0usize); +add_sub_const_decimals!(15usize, 52usize, 67usize, 0usize); +add_sub_const_decimals!(15usize, 51usize, 66usize, 0usize); +add_sub_const_decimals!(15usize, 50usize, 65usize, 0usize); +add_sub_const_decimals!(15usize, 49usize, 64usize, 0usize); +add_sub_const_decimals!(15usize, 48usize, 63usize, 0usize); +add_sub_const_decimals!(15usize, 47usize, 62usize, 0usize); +add_sub_const_decimals!(15usize, 46usize, 61usize, 0usize); +add_sub_const_decimals!(15usize, 45usize, 60usize, 0usize); +add_sub_const_decimals!(15usize, 44usize, 59usize, 0usize); +add_sub_const_decimals!(15usize, 43usize, 58usize, 0usize); +add_sub_const_decimals!(15usize, 42usize, 57usize, 0usize); +add_sub_const_decimals!(15usize, 41usize, 56usize, 0usize); +add_sub_const_decimals!(15usize, 40usize, 55usize, 0usize); +add_sub_const_decimals!(15usize, 39usize, 54usize, 0usize); +add_sub_const_decimals!(15usize, 38usize, 53usize, 0usize); +add_sub_const_decimals!(15usize, 37usize, 52usize, 0usize); +add_sub_const_decimals!(15usize, 36usize, 51usize, 0usize); +add_sub_const_decimals!(15usize, 35usize, 50usize, 0usize); +add_sub_const_decimals!(15usize, 34usize, 49usize, 0usize); +add_sub_const_decimals!(15usize, 33usize, 48usize, 0usize); +add_sub_const_decimals!(15usize, 32usize, 47usize, 0usize); +add_sub_const_decimals!(15usize, 31usize, 46usize, 0usize); +add_sub_const_decimals!(15usize, 30usize, 45usize, 0usize); +add_sub_const_decimals!(15usize, 29usize, 44usize, 0usize); +add_sub_const_decimals!(15usize, 28usize, 43usize, 0usize); +add_sub_const_decimals!(15usize, 27usize, 42usize, 0usize); +add_sub_const_decimals!(15usize, 26usize, 41usize, 0usize); +add_sub_const_decimals!(15usize, 25usize, 40usize, 0usize); +add_sub_const_decimals!(15usize, 24usize, 39usize, 0usize); +add_sub_const_decimals!(15usize, 23usize, 38usize, 0usize); +add_sub_const_decimals!(15usize, 22usize, 37usize, 0usize); +add_sub_const_decimals!(15usize, 21usize, 36usize, 0usize); +add_sub_const_decimals!(15usize, 20usize, 35usize, 0usize); +add_sub_const_decimals!(15usize, 19usize, 34usize, 0usize); +add_sub_const_decimals!(15usize, 18usize, 33usize, 0usize); +add_sub_const_decimals!(15usize, 17usize, 32usize, 0usize); +add_sub_const_decimals!(15usize, 16usize, 31usize, 0usize); +add_sub_const_decimals!(15usize, 15usize, 30usize, 0usize); +add_sub_const_decimals!(15usize, 14usize, 29usize, 1usize); +add_sub_const_decimals!(15usize, 13usize, 28usize, 2usize); +add_sub_const_decimals!(15usize, 12usize, 27usize, 3usize); +add_sub_const_decimals!(15usize, 11usize, 26usize, 4usize); +add_sub_const_decimals!(15usize, 10usize, 25usize, 5usize); +add_sub_const_decimals!(15usize, 9usize, 24usize, 6usize); +add_sub_const_decimals!(15usize, 8usize, 23usize, 7usize); +add_sub_const_decimals!(15usize, 7usize, 22usize, 8usize); +add_sub_const_decimals!(15usize, 6usize, 21usize, 9usize); +add_sub_const_decimals!(15usize, 5usize, 20usize, 10usize); +add_sub_const_decimals!(15usize, 4usize, 19usize, 11usize); +add_sub_const_decimals!(15usize, 3usize, 18usize, 12usize); +add_sub_const_decimals!(15usize, 2usize, 17usize, 13usize); +add_sub_const_decimals!(15usize, 1usize, 16usize, 14usize); +add_sub_const_decimals!(15usize, 0usize, 15usize, 15usize); +add_sub_const_decimals!(14usize, 64usize, 78usize, 0usize); +add_sub_const_decimals!(14usize, 63usize, 77usize, 0usize); +add_sub_const_decimals!(14usize, 62usize, 76usize, 0usize); +add_sub_const_decimals!(14usize, 61usize, 75usize, 0usize); +add_sub_const_decimals!(14usize, 60usize, 74usize, 0usize); +add_sub_const_decimals!(14usize, 59usize, 73usize, 0usize); +add_sub_const_decimals!(14usize, 58usize, 72usize, 0usize); +add_sub_const_decimals!(14usize, 57usize, 71usize, 0usize); +add_sub_const_decimals!(14usize, 56usize, 70usize, 0usize); +add_sub_const_decimals!(14usize, 55usize, 69usize, 0usize); +add_sub_const_decimals!(14usize, 54usize, 68usize, 0usize); +add_sub_const_decimals!(14usize, 53usize, 67usize, 0usize); +add_sub_const_decimals!(14usize, 52usize, 66usize, 0usize); +add_sub_const_decimals!(14usize, 51usize, 65usize, 0usize); +add_sub_const_decimals!(14usize, 50usize, 64usize, 0usize); +add_sub_const_decimals!(14usize, 49usize, 63usize, 0usize); +add_sub_const_decimals!(14usize, 48usize, 62usize, 0usize); +add_sub_const_decimals!(14usize, 47usize, 61usize, 0usize); +add_sub_const_decimals!(14usize, 46usize, 60usize, 0usize); +add_sub_const_decimals!(14usize, 45usize, 59usize, 0usize); +add_sub_const_decimals!(14usize, 44usize, 58usize, 0usize); +add_sub_const_decimals!(14usize, 43usize, 57usize, 0usize); +add_sub_const_decimals!(14usize, 42usize, 56usize, 0usize); +add_sub_const_decimals!(14usize, 41usize, 55usize, 0usize); +add_sub_const_decimals!(14usize, 40usize, 54usize, 0usize); +add_sub_const_decimals!(14usize, 39usize, 53usize, 0usize); +add_sub_const_decimals!(14usize, 38usize, 52usize, 0usize); +add_sub_const_decimals!(14usize, 37usize, 51usize, 0usize); +add_sub_const_decimals!(14usize, 36usize, 50usize, 0usize); +add_sub_const_decimals!(14usize, 35usize, 49usize, 0usize); +add_sub_const_decimals!(14usize, 34usize, 48usize, 0usize); +add_sub_const_decimals!(14usize, 33usize, 47usize, 0usize); +add_sub_const_decimals!(14usize, 32usize, 46usize, 0usize); +add_sub_const_decimals!(14usize, 31usize, 45usize, 0usize); +add_sub_const_decimals!(14usize, 30usize, 44usize, 0usize); +add_sub_const_decimals!(14usize, 29usize, 43usize, 0usize); +add_sub_const_decimals!(14usize, 28usize, 42usize, 0usize); +add_sub_const_decimals!(14usize, 27usize, 41usize, 0usize); +add_sub_const_decimals!(14usize, 26usize, 40usize, 0usize); +add_sub_const_decimals!(14usize, 25usize, 39usize, 0usize); +add_sub_const_decimals!(14usize, 24usize, 38usize, 0usize); +add_sub_const_decimals!(14usize, 23usize, 37usize, 0usize); +add_sub_const_decimals!(14usize, 22usize, 36usize, 0usize); +add_sub_const_decimals!(14usize, 21usize, 35usize, 0usize); +add_sub_const_decimals!(14usize, 20usize, 34usize, 0usize); +add_sub_const_decimals!(14usize, 19usize, 33usize, 0usize); +add_sub_const_decimals!(14usize, 18usize, 32usize, 0usize); +add_sub_const_decimals!(14usize, 17usize, 31usize, 0usize); +add_sub_const_decimals!(14usize, 16usize, 30usize, 0usize); +add_sub_const_decimals!(14usize, 15usize, 29usize, 0usize); +add_sub_const_decimals!(14usize, 14usize, 28usize, 0usize); +add_sub_const_decimals!(14usize, 13usize, 27usize, 1usize); +add_sub_const_decimals!(14usize, 12usize, 26usize, 2usize); +add_sub_const_decimals!(14usize, 11usize, 25usize, 3usize); +add_sub_const_decimals!(14usize, 10usize, 24usize, 4usize); +add_sub_const_decimals!(14usize, 9usize, 23usize, 5usize); +add_sub_const_decimals!(14usize, 8usize, 22usize, 6usize); +add_sub_const_decimals!(14usize, 7usize, 21usize, 7usize); +add_sub_const_decimals!(14usize, 6usize, 20usize, 8usize); +add_sub_const_decimals!(14usize, 5usize, 19usize, 9usize); +add_sub_const_decimals!(14usize, 4usize, 18usize, 10usize); +add_sub_const_decimals!(14usize, 3usize, 17usize, 11usize); +add_sub_const_decimals!(14usize, 2usize, 16usize, 12usize); +add_sub_const_decimals!(14usize, 1usize, 15usize, 13usize); +add_sub_const_decimals!(14usize, 0usize, 14usize, 14usize); +add_sub_const_decimals!(13usize, 64usize, 77usize, 0usize); +add_sub_const_decimals!(13usize, 63usize, 76usize, 0usize); +add_sub_const_decimals!(13usize, 62usize, 75usize, 0usize); +add_sub_const_decimals!(13usize, 61usize, 74usize, 0usize); +add_sub_const_decimals!(13usize, 60usize, 73usize, 0usize); +add_sub_const_decimals!(13usize, 59usize, 72usize, 0usize); +add_sub_const_decimals!(13usize, 58usize, 71usize, 0usize); +add_sub_const_decimals!(13usize, 57usize, 70usize, 0usize); +add_sub_const_decimals!(13usize, 56usize, 69usize, 0usize); +add_sub_const_decimals!(13usize, 55usize, 68usize, 0usize); +add_sub_const_decimals!(13usize, 54usize, 67usize, 0usize); +add_sub_const_decimals!(13usize, 53usize, 66usize, 0usize); +add_sub_const_decimals!(13usize, 52usize, 65usize, 0usize); +add_sub_const_decimals!(13usize, 51usize, 64usize, 0usize); +add_sub_const_decimals!(13usize, 50usize, 63usize, 0usize); +add_sub_const_decimals!(13usize, 49usize, 62usize, 0usize); +add_sub_const_decimals!(13usize, 48usize, 61usize, 0usize); +add_sub_const_decimals!(13usize, 47usize, 60usize, 0usize); +add_sub_const_decimals!(13usize, 46usize, 59usize, 0usize); +add_sub_const_decimals!(13usize, 45usize, 58usize, 0usize); +add_sub_const_decimals!(13usize, 44usize, 57usize, 0usize); +add_sub_const_decimals!(13usize, 43usize, 56usize, 0usize); +add_sub_const_decimals!(13usize, 42usize, 55usize, 0usize); +add_sub_const_decimals!(13usize, 41usize, 54usize, 0usize); +add_sub_const_decimals!(13usize, 40usize, 53usize, 0usize); +add_sub_const_decimals!(13usize, 39usize, 52usize, 0usize); +add_sub_const_decimals!(13usize, 38usize, 51usize, 0usize); +add_sub_const_decimals!(13usize, 37usize, 50usize, 0usize); +add_sub_const_decimals!(13usize, 36usize, 49usize, 0usize); +add_sub_const_decimals!(13usize, 35usize, 48usize, 0usize); +add_sub_const_decimals!(13usize, 34usize, 47usize, 0usize); +add_sub_const_decimals!(13usize, 33usize, 46usize, 0usize); +add_sub_const_decimals!(13usize, 32usize, 45usize, 0usize); +add_sub_const_decimals!(13usize, 31usize, 44usize, 0usize); +add_sub_const_decimals!(13usize, 30usize, 43usize, 0usize); +add_sub_const_decimals!(13usize, 29usize, 42usize, 0usize); +add_sub_const_decimals!(13usize, 28usize, 41usize, 0usize); +add_sub_const_decimals!(13usize, 27usize, 40usize, 0usize); +add_sub_const_decimals!(13usize, 26usize, 39usize, 0usize); +add_sub_const_decimals!(13usize, 25usize, 38usize, 0usize); +add_sub_const_decimals!(13usize, 24usize, 37usize, 0usize); +add_sub_const_decimals!(13usize, 23usize, 36usize, 0usize); +add_sub_const_decimals!(13usize, 22usize, 35usize, 0usize); +add_sub_const_decimals!(13usize, 21usize, 34usize, 0usize); +add_sub_const_decimals!(13usize, 20usize, 33usize, 0usize); +add_sub_const_decimals!(13usize, 19usize, 32usize, 0usize); +add_sub_const_decimals!(13usize, 18usize, 31usize, 0usize); +add_sub_const_decimals!(13usize, 17usize, 30usize, 0usize); +add_sub_const_decimals!(13usize, 16usize, 29usize, 0usize); +add_sub_const_decimals!(13usize, 15usize, 28usize, 0usize); +add_sub_const_decimals!(13usize, 14usize, 27usize, 0usize); +add_sub_const_decimals!(13usize, 13usize, 26usize, 0usize); +add_sub_const_decimals!(13usize, 12usize, 25usize, 1usize); +add_sub_const_decimals!(13usize, 11usize, 24usize, 2usize); +add_sub_const_decimals!(13usize, 10usize, 23usize, 3usize); +add_sub_const_decimals!(13usize, 9usize, 22usize, 4usize); +add_sub_const_decimals!(13usize, 8usize, 21usize, 5usize); +add_sub_const_decimals!(13usize, 7usize, 20usize, 6usize); +add_sub_const_decimals!(13usize, 6usize, 19usize, 7usize); +add_sub_const_decimals!(13usize, 5usize, 18usize, 8usize); +add_sub_const_decimals!(13usize, 4usize, 17usize, 9usize); +add_sub_const_decimals!(13usize, 3usize, 16usize, 10usize); +add_sub_const_decimals!(13usize, 2usize, 15usize, 11usize); +add_sub_const_decimals!(13usize, 1usize, 14usize, 12usize); +add_sub_const_decimals!(13usize, 0usize, 13usize, 13usize); +add_sub_const_decimals!(12usize, 64usize, 76usize, 0usize); +add_sub_const_decimals!(12usize, 63usize, 75usize, 0usize); +add_sub_const_decimals!(12usize, 62usize, 74usize, 0usize); +add_sub_const_decimals!(12usize, 61usize, 73usize, 0usize); +add_sub_const_decimals!(12usize, 60usize, 72usize, 0usize); +add_sub_const_decimals!(12usize, 59usize, 71usize, 0usize); +add_sub_const_decimals!(12usize, 58usize, 70usize, 0usize); +add_sub_const_decimals!(12usize, 57usize, 69usize, 0usize); +add_sub_const_decimals!(12usize, 56usize, 68usize, 0usize); +add_sub_const_decimals!(12usize, 55usize, 67usize, 0usize); +add_sub_const_decimals!(12usize, 54usize, 66usize, 0usize); +add_sub_const_decimals!(12usize, 53usize, 65usize, 0usize); +add_sub_const_decimals!(12usize, 52usize, 64usize, 0usize); +add_sub_const_decimals!(12usize, 51usize, 63usize, 0usize); +add_sub_const_decimals!(12usize, 50usize, 62usize, 0usize); +add_sub_const_decimals!(12usize, 49usize, 61usize, 0usize); +add_sub_const_decimals!(12usize, 48usize, 60usize, 0usize); +add_sub_const_decimals!(12usize, 47usize, 59usize, 0usize); +add_sub_const_decimals!(12usize, 46usize, 58usize, 0usize); +add_sub_const_decimals!(12usize, 45usize, 57usize, 0usize); +add_sub_const_decimals!(12usize, 44usize, 56usize, 0usize); +add_sub_const_decimals!(12usize, 43usize, 55usize, 0usize); +add_sub_const_decimals!(12usize, 42usize, 54usize, 0usize); +add_sub_const_decimals!(12usize, 41usize, 53usize, 0usize); +add_sub_const_decimals!(12usize, 40usize, 52usize, 0usize); +add_sub_const_decimals!(12usize, 39usize, 51usize, 0usize); +add_sub_const_decimals!(12usize, 38usize, 50usize, 0usize); +add_sub_const_decimals!(12usize, 37usize, 49usize, 0usize); +add_sub_const_decimals!(12usize, 36usize, 48usize, 0usize); +add_sub_const_decimals!(12usize, 35usize, 47usize, 0usize); +add_sub_const_decimals!(12usize, 34usize, 46usize, 0usize); +add_sub_const_decimals!(12usize, 33usize, 45usize, 0usize); +add_sub_const_decimals!(12usize, 32usize, 44usize, 0usize); +add_sub_const_decimals!(12usize, 31usize, 43usize, 0usize); +add_sub_const_decimals!(12usize, 30usize, 42usize, 0usize); +add_sub_const_decimals!(12usize, 29usize, 41usize, 0usize); +add_sub_const_decimals!(12usize, 28usize, 40usize, 0usize); +add_sub_const_decimals!(12usize, 27usize, 39usize, 0usize); +add_sub_const_decimals!(12usize, 26usize, 38usize, 0usize); +add_sub_const_decimals!(12usize, 25usize, 37usize, 0usize); +add_sub_const_decimals!(12usize, 24usize, 36usize, 0usize); +add_sub_const_decimals!(12usize, 23usize, 35usize, 0usize); +add_sub_const_decimals!(12usize, 22usize, 34usize, 0usize); +add_sub_const_decimals!(12usize, 21usize, 33usize, 0usize); +add_sub_const_decimals!(12usize, 20usize, 32usize, 0usize); +add_sub_const_decimals!(12usize, 19usize, 31usize, 0usize); +add_sub_const_decimals!(12usize, 18usize, 30usize, 0usize); +add_sub_const_decimals!(12usize, 17usize, 29usize, 0usize); +add_sub_const_decimals!(12usize, 16usize, 28usize, 0usize); +add_sub_const_decimals!(12usize, 15usize, 27usize, 0usize); +add_sub_const_decimals!(12usize, 14usize, 26usize, 0usize); +add_sub_const_decimals!(12usize, 13usize, 25usize, 0usize); +add_sub_const_decimals!(12usize, 12usize, 24usize, 0usize); +add_sub_const_decimals!(12usize, 11usize, 23usize, 1usize); +add_sub_const_decimals!(12usize, 10usize, 22usize, 2usize); +add_sub_const_decimals!(12usize, 9usize, 21usize, 3usize); +add_sub_const_decimals!(12usize, 8usize, 20usize, 4usize); +add_sub_const_decimals!(12usize, 7usize, 19usize, 5usize); +add_sub_const_decimals!(12usize, 6usize, 18usize, 6usize); +add_sub_const_decimals!(12usize, 5usize, 17usize, 7usize); +add_sub_const_decimals!(12usize, 4usize, 16usize, 8usize); +add_sub_const_decimals!(12usize, 3usize, 15usize, 9usize); +add_sub_const_decimals!(12usize, 2usize, 14usize, 10usize); +add_sub_const_decimals!(12usize, 1usize, 13usize, 11usize); +add_sub_const_decimals!(12usize, 0usize, 12usize, 12usize); +add_sub_const_decimals!(11usize, 64usize, 75usize, 0usize); +add_sub_const_decimals!(11usize, 63usize, 74usize, 0usize); +add_sub_const_decimals!(11usize, 62usize, 73usize, 0usize); +add_sub_const_decimals!(11usize, 61usize, 72usize, 0usize); +add_sub_const_decimals!(11usize, 60usize, 71usize, 0usize); +add_sub_const_decimals!(11usize, 59usize, 70usize, 0usize); +add_sub_const_decimals!(11usize, 58usize, 69usize, 0usize); +add_sub_const_decimals!(11usize, 57usize, 68usize, 0usize); +add_sub_const_decimals!(11usize, 56usize, 67usize, 0usize); +add_sub_const_decimals!(11usize, 55usize, 66usize, 0usize); +add_sub_const_decimals!(11usize, 54usize, 65usize, 0usize); +add_sub_const_decimals!(11usize, 53usize, 64usize, 0usize); +add_sub_const_decimals!(11usize, 52usize, 63usize, 0usize); +add_sub_const_decimals!(11usize, 51usize, 62usize, 0usize); +add_sub_const_decimals!(11usize, 50usize, 61usize, 0usize); +add_sub_const_decimals!(11usize, 49usize, 60usize, 0usize); +add_sub_const_decimals!(11usize, 48usize, 59usize, 0usize); +add_sub_const_decimals!(11usize, 47usize, 58usize, 0usize); +add_sub_const_decimals!(11usize, 46usize, 57usize, 0usize); +add_sub_const_decimals!(11usize, 45usize, 56usize, 0usize); +add_sub_const_decimals!(11usize, 44usize, 55usize, 0usize); +add_sub_const_decimals!(11usize, 43usize, 54usize, 0usize); +add_sub_const_decimals!(11usize, 42usize, 53usize, 0usize); +add_sub_const_decimals!(11usize, 41usize, 52usize, 0usize); +add_sub_const_decimals!(11usize, 40usize, 51usize, 0usize); +add_sub_const_decimals!(11usize, 39usize, 50usize, 0usize); +add_sub_const_decimals!(11usize, 38usize, 49usize, 0usize); +add_sub_const_decimals!(11usize, 37usize, 48usize, 0usize); +add_sub_const_decimals!(11usize, 36usize, 47usize, 0usize); +add_sub_const_decimals!(11usize, 35usize, 46usize, 0usize); +add_sub_const_decimals!(11usize, 34usize, 45usize, 0usize); +add_sub_const_decimals!(11usize, 33usize, 44usize, 0usize); +add_sub_const_decimals!(11usize, 32usize, 43usize, 0usize); +add_sub_const_decimals!(11usize, 31usize, 42usize, 0usize); +add_sub_const_decimals!(11usize, 30usize, 41usize, 0usize); +add_sub_const_decimals!(11usize, 29usize, 40usize, 0usize); +add_sub_const_decimals!(11usize, 28usize, 39usize, 0usize); +add_sub_const_decimals!(11usize, 27usize, 38usize, 0usize); +add_sub_const_decimals!(11usize, 26usize, 37usize, 0usize); +add_sub_const_decimals!(11usize, 25usize, 36usize, 0usize); +add_sub_const_decimals!(11usize, 24usize, 35usize, 0usize); +add_sub_const_decimals!(11usize, 23usize, 34usize, 0usize); +add_sub_const_decimals!(11usize, 22usize, 33usize, 0usize); +add_sub_const_decimals!(11usize, 21usize, 32usize, 0usize); +add_sub_const_decimals!(11usize, 20usize, 31usize, 0usize); +add_sub_const_decimals!(11usize, 19usize, 30usize, 0usize); +add_sub_const_decimals!(11usize, 18usize, 29usize, 0usize); +add_sub_const_decimals!(11usize, 17usize, 28usize, 0usize); +add_sub_const_decimals!(11usize, 16usize, 27usize, 0usize); +add_sub_const_decimals!(11usize, 15usize, 26usize, 0usize); +add_sub_const_decimals!(11usize, 14usize, 25usize, 0usize); +add_sub_const_decimals!(11usize, 13usize, 24usize, 0usize); +add_sub_const_decimals!(11usize, 12usize, 23usize, 0usize); +add_sub_const_decimals!(11usize, 11usize, 22usize, 0usize); +add_sub_const_decimals!(11usize, 10usize, 21usize, 1usize); +add_sub_const_decimals!(11usize, 9usize, 20usize, 2usize); +add_sub_const_decimals!(11usize, 8usize, 19usize, 3usize); +add_sub_const_decimals!(11usize, 7usize, 18usize, 4usize); +add_sub_const_decimals!(11usize, 6usize, 17usize, 5usize); +add_sub_const_decimals!(11usize, 5usize, 16usize, 6usize); +add_sub_const_decimals!(11usize, 4usize, 15usize, 7usize); +add_sub_const_decimals!(11usize, 3usize, 14usize, 8usize); +add_sub_const_decimals!(11usize, 2usize, 13usize, 9usize); +add_sub_const_decimals!(11usize, 1usize, 12usize, 10usize); +add_sub_const_decimals!(11usize, 0usize, 11usize, 11usize); +add_sub_const_decimals!(10usize, 64usize, 74usize, 0usize); +add_sub_const_decimals!(10usize, 63usize, 73usize, 0usize); +add_sub_const_decimals!(10usize, 62usize, 72usize, 0usize); +add_sub_const_decimals!(10usize, 61usize, 71usize, 0usize); +add_sub_const_decimals!(10usize, 60usize, 70usize, 0usize); +add_sub_const_decimals!(10usize, 59usize, 69usize, 0usize); +add_sub_const_decimals!(10usize, 58usize, 68usize, 0usize); +add_sub_const_decimals!(10usize, 57usize, 67usize, 0usize); +add_sub_const_decimals!(10usize, 56usize, 66usize, 0usize); +add_sub_const_decimals!(10usize, 55usize, 65usize, 0usize); +add_sub_const_decimals!(10usize, 54usize, 64usize, 0usize); +add_sub_const_decimals!(10usize, 53usize, 63usize, 0usize); +add_sub_const_decimals!(10usize, 52usize, 62usize, 0usize); +add_sub_const_decimals!(10usize, 51usize, 61usize, 0usize); +add_sub_const_decimals!(10usize, 50usize, 60usize, 0usize); +add_sub_const_decimals!(10usize, 49usize, 59usize, 0usize); +add_sub_const_decimals!(10usize, 48usize, 58usize, 0usize); +add_sub_const_decimals!(10usize, 47usize, 57usize, 0usize); +add_sub_const_decimals!(10usize, 46usize, 56usize, 0usize); +add_sub_const_decimals!(10usize, 45usize, 55usize, 0usize); +add_sub_const_decimals!(10usize, 44usize, 54usize, 0usize); +add_sub_const_decimals!(10usize, 43usize, 53usize, 0usize); +add_sub_const_decimals!(10usize, 42usize, 52usize, 0usize); +add_sub_const_decimals!(10usize, 41usize, 51usize, 0usize); +add_sub_const_decimals!(10usize, 40usize, 50usize, 0usize); +add_sub_const_decimals!(10usize, 39usize, 49usize, 0usize); +add_sub_const_decimals!(10usize, 38usize, 48usize, 0usize); +add_sub_const_decimals!(10usize, 37usize, 47usize, 0usize); +add_sub_const_decimals!(10usize, 36usize, 46usize, 0usize); +add_sub_const_decimals!(10usize, 35usize, 45usize, 0usize); +add_sub_const_decimals!(10usize, 34usize, 44usize, 0usize); +add_sub_const_decimals!(10usize, 33usize, 43usize, 0usize); +add_sub_const_decimals!(10usize, 32usize, 42usize, 0usize); +add_sub_const_decimals!(10usize, 31usize, 41usize, 0usize); +add_sub_const_decimals!(10usize, 30usize, 40usize, 0usize); +add_sub_const_decimals!(10usize, 29usize, 39usize, 0usize); +add_sub_const_decimals!(10usize, 28usize, 38usize, 0usize); +add_sub_const_decimals!(10usize, 27usize, 37usize, 0usize); +add_sub_const_decimals!(10usize, 26usize, 36usize, 0usize); +add_sub_const_decimals!(10usize, 25usize, 35usize, 0usize); +add_sub_const_decimals!(10usize, 24usize, 34usize, 0usize); +add_sub_const_decimals!(10usize, 23usize, 33usize, 0usize); +add_sub_const_decimals!(10usize, 22usize, 32usize, 0usize); +add_sub_const_decimals!(10usize, 21usize, 31usize, 0usize); +add_sub_const_decimals!(10usize, 20usize, 30usize, 0usize); +add_sub_const_decimals!(10usize, 19usize, 29usize, 0usize); +add_sub_const_decimals!(10usize, 18usize, 28usize, 0usize); +add_sub_const_decimals!(10usize, 17usize, 27usize, 0usize); +add_sub_const_decimals!(10usize, 16usize, 26usize, 0usize); +add_sub_const_decimals!(10usize, 15usize, 25usize, 0usize); +add_sub_const_decimals!(10usize, 14usize, 24usize, 0usize); +add_sub_const_decimals!(10usize, 13usize, 23usize, 0usize); +add_sub_const_decimals!(10usize, 12usize, 22usize, 0usize); +add_sub_const_decimals!(10usize, 11usize, 21usize, 0usize); +add_sub_const_decimals!(10usize, 10usize, 20usize, 0usize); +add_sub_const_decimals!(10usize, 9usize, 19usize, 1usize); +add_sub_const_decimals!(10usize, 8usize, 18usize, 2usize); +add_sub_const_decimals!(10usize, 7usize, 17usize, 3usize); +add_sub_const_decimals!(10usize, 6usize, 16usize, 4usize); +add_sub_const_decimals!(10usize, 5usize, 15usize, 5usize); +add_sub_const_decimals!(10usize, 4usize, 14usize, 6usize); +add_sub_const_decimals!(10usize, 3usize, 13usize, 7usize); +add_sub_const_decimals!(10usize, 2usize, 12usize, 8usize); +add_sub_const_decimals!(10usize, 1usize, 11usize, 9usize); +add_sub_const_decimals!(10usize, 0usize, 10usize, 10usize); +add_sub_const_decimals!(9usize, 64usize, 73usize, 0usize); +add_sub_const_decimals!(9usize, 63usize, 72usize, 0usize); +add_sub_const_decimals!(9usize, 62usize, 71usize, 0usize); +add_sub_const_decimals!(9usize, 61usize, 70usize, 0usize); +add_sub_const_decimals!(9usize, 60usize, 69usize, 0usize); +add_sub_const_decimals!(9usize, 59usize, 68usize, 0usize); +add_sub_const_decimals!(9usize, 58usize, 67usize, 0usize); +add_sub_const_decimals!(9usize, 57usize, 66usize, 0usize); +add_sub_const_decimals!(9usize, 56usize, 65usize, 0usize); +add_sub_const_decimals!(9usize, 55usize, 64usize, 0usize); +add_sub_const_decimals!(9usize, 54usize, 63usize, 0usize); +add_sub_const_decimals!(9usize, 53usize, 62usize, 0usize); +add_sub_const_decimals!(9usize, 52usize, 61usize, 0usize); +add_sub_const_decimals!(9usize, 51usize, 60usize, 0usize); +add_sub_const_decimals!(9usize, 50usize, 59usize, 0usize); +add_sub_const_decimals!(9usize, 49usize, 58usize, 0usize); +add_sub_const_decimals!(9usize, 48usize, 57usize, 0usize); +add_sub_const_decimals!(9usize, 47usize, 56usize, 0usize); +add_sub_const_decimals!(9usize, 46usize, 55usize, 0usize); +add_sub_const_decimals!(9usize, 45usize, 54usize, 0usize); +add_sub_const_decimals!(9usize, 44usize, 53usize, 0usize); +add_sub_const_decimals!(9usize, 43usize, 52usize, 0usize); +add_sub_const_decimals!(9usize, 42usize, 51usize, 0usize); +add_sub_const_decimals!(9usize, 41usize, 50usize, 0usize); +add_sub_const_decimals!(9usize, 40usize, 49usize, 0usize); +add_sub_const_decimals!(9usize, 39usize, 48usize, 0usize); +add_sub_const_decimals!(9usize, 38usize, 47usize, 0usize); +add_sub_const_decimals!(9usize, 37usize, 46usize, 0usize); +add_sub_const_decimals!(9usize, 36usize, 45usize, 0usize); +add_sub_const_decimals!(9usize, 35usize, 44usize, 0usize); +add_sub_const_decimals!(9usize, 34usize, 43usize, 0usize); +add_sub_const_decimals!(9usize, 33usize, 42usize, 0usize); +add_sub_const_decimals!(9usize, 32usize, 41usize, 0usize); +add_sub_const_decimals!(9usize, 31usize, 40usize, 0usize); +add_sub_const_decimals!(9usize, 30usize, 39usize, 0usize); +add_sub_const_decimals!(9usize, 29usize, 38usize, 0usize); +add_sub_const_decimals!(9usize, 28usize, 37usize, 0usize); +add_sub_const_decimals!(9usize, 27usize, 36usize, 0usize); +add_sub_const_decimals!(9usize, 26usize, 35usize, 0usize); +add_sub_const_decimals!(9usize, 25usize, 34usize, 0usize); +add_sub_const_decimals!(9usize, 24usize, 33usize, 0usize); +add_sub_const_decimals!(9usize, 23usize, 32usize, 0usize); +add_sub_const_decimals!(9usize, 22usize, 31usize, 0usize); +add_sub_const_decimals!(9usize, 21usize, 30usize, 0usize); +add_sub_const_decimals!(9usize, 20usize, 29usize, 0usize); +add_sub_const_decimals!(9usize, 19usize, 28usize, 0usize); +add_sub_const_decimals!(9usize, 18usize, 27usize, 0usize); +add_sub_const_decimals!(9usize, 17usize, 26usize, 0usize); +add_sub_const_decimals!(9usize, 16usize, 25usize, 0usize); +add_sub_const_decimals!(9usize, 15usize, 24usize, 0usize); +add_sub_const_decimals!(9usize, 14usize, 23usize, 0usize); +add_sub_const_decimals!(9usize, 13usize, 22usize, 0usize); +add_sub_const_decimals!(9usize, 12usize, 21usize, 0usize); +add_sub_const_decimals!(9usize, 11usize, 20usize, 0usize); +add_sub_const_decimals!(9usize, 10usize, 19usize, 0usize); +add_sub_const_decimals!(9usize, 9usize, 18usize, 0usize); +add_sub_const_decimals!(9usize, 8usize, 17usize, 1usize); +add_sub_const_decimals!(9usize, 7usize, 16usize, 2usize); +add_sub_const_decimals!(9usize, 6usize, 15usize, 3usize); +add_sub_const_decimals!(9usize, 5usize, 14usize, 4usize); +add_sub_const_decimals!(9usize, 4usize, 13usize, 5usize); +add_sub_const_decimals!(9usize, 3usize, 12usize, 6usize); +add_sub_const_decimals!(9usize, 2usize, 11usize, 7usize); +add_sub_const_decimals!(9usize, 1usize, 10usize, 8usize); +add_sub_const_decimals!(9usize, 0usize, 9usize, 9usize); +add_sub_const_decimals!(8usize, 64usize, 72usize, 0usize); +add_sub_const_decimals!(8usize, 63usize, 71usize, 0usize); +add_sub_const_decimals!(8usize, 62usize, 70usize, 0usize); +add_sub_const_decimals!(8usize, 61usize, 69usize, 0usize); +add_sub_const_decimals!(8usize, 60usize, 68usize, 0usize); +add_sub_const_decimals!(8usize, 59usize, 67usize, 0usize); +add_sub_const_decimals!(8usize, 58usize, 66usize, 0usize); +add_sub_const_decimals!(8usize, 57usize, 65usize, 0usize); +add_sub_const_decimals!(8usize, 56usize, 64usize, 0usize); +add_sub_const_decimals!(8usize, 55usize, 63usize, 0usize); +add_sub_const_decimals!(8usize, 54usize, 62usize, 0usize); +add_sub_const_decimals!(8usize, 53usize, 61usize, 0usize); +add_sub_const_decimals!(8usize, 52usize, 60usize, 0usize); +add_sub_const_decimals!(8usize, 51usize, 59usize, 0usize); +add_sub_const_decimals!(8usize, 50usize, 58usize, 0usize); +add_sub_const_decimals!(8usize, 49usize, 57usize, 0usize); +add_sub_const_decimals!(8usize, 48usize, 56usize, 0usize); +add_sub_const_decimals!(8usize, 47usize, 55usize, 0usize); +add_sub_const_decimals!(8usize, 46usize, 54usize, 0usize); +add_sub_const_decimals!(8usize, 45usize, 53usize, 0usize); +add_sub_const_decimals!(8usize, 44usize, 52usize, 0usize); +add_sub_const_decimals!(8usize, 43usize, 51usize, 0usize); +add_sub_const_decimals!(8usize, 42usize, 50usize, 0usize); +add_sub_const_decimals!(8usize, 41usize, 49usize, 0usize); +add_sub_const_decimals!(8usize, 40usize, 48usize, 0usize); +add_sub_const_decimals!(8usize, 39usize, 47usize, 0usize); +add_sub_const_decimals!(8usize, 38usize, 46usize, 0usize); +add_sub_const_decimals!(8usize, 37usize, 45usize, 0usize); +add_sub_const_decimals!(8usize, 36usize, 44usize, 0usize); +add_sub_const_decimals!(8usize, 35usize, 43usize, 0usize); +add_sub_const_decimals!(8usize, 34usize, 42usize, 0usize); +add_sub_const_decimals!(8usize, 33usize, 41usize, 0usize); +add_sub_const_decimals!(8usize, 32usize, 40usize, 0usize); +add_sub_const_decimals!(8usize, 31usize, 39usize, 0usize); +add_sub_const_decimals!(8usize, 30usize, 38usize, 0usize); +add_sub_const_decimals!(8usize, 29usize, 37usize, 0usize); +add_sub_const_decimals!(8usize, 28usize, 36usize, 0usize); +add_sub_const_decimals!(8usize, 27usize, 35usize, 0usize); +add_sub_const_decimals!(8usize, 26usize, 34usize, 0usize); +add_sub_const_decimals!(8usize, 25usize, 33usize, 0usize); +add_sub_const_decimals!(8usize, 24usize, 32usize, 0usize); +add_sub_const_decimals!(8usize, 23usize, 31usize, 0usize); +add_sub_const_decimals!(8usize, 22usize, 30usize, 0usize); +add_sub_const_decimals!(8usize, 21usize, 29usize, 0usize); +add_sub_const_decimals!(8usize, 20usize, 28usize, 0usize); +add_sub_const_decimals!(8usize, 19usize, 27usize, 0usize); +add_sub_const_decimals!(8usize, 18usize, 26usize, 0usize); +add_sub_const_decimals!(8usize, 17usize, 25usize, 0usize); +add_sub_const_decimals!(8usize, 16usize, 24usize, 0usize); +add_sub_const_decimals!(8usize, 15usize, 23usize, 0usize); +add_sub_const_decimals!(8usize, 14usize, 22usize, 0usize); +add_sub_const_decimals!(8usize, 13usize, 21usize, 0usize); +add_sub_const_decimals!(8usize, 12usize, 20usize, 0usize); +add_sub_const_decimals!(8usize, 11usize, 19usize, 0usize); +add_sub_const_decimals!(8usize, 10usize, 18usize, 0usize); +add_sub_const_decimals!(8usize, 9usize, 17usize, 0usize); +add_sub_const_decimals!(8usize, 8usize, 16usize, 0usize); +add_sub_const_decimals!(8usize, 7usize, 15usize, 1usize); +add_sub_const_decimals!(8usize, 6usize, 14usize, 2usize); +add_sub_const_decimals!(8usize, 5usize, 13usize, 3usize); +add_sub_const_decimals!(8usize, 4usize, 12usize, 4usize); +add_sub_const_decimals!(8usize, 3usize, 11usize, 5usize); +add_sub_const_decimals!(8usize, 2usize, 10usize, 6usize); +add_sub_const_decimals!(8usize, 1usize, 9usize, 7usize); +add_sub_const_decimals!(8usize, 0usize, 8usize, 8usize); +add_sub_const_decimals!(7usize, 64usize, 71usize, 0usize); +add_sub_const_decimals!(7usize, 63usize, 70usize, 0usize); +add_sub_const_decimals!(7usize, 62usize, 69usize, 0usize); +add_sub_const_decimals!(7usize, 61usize, 68usize, 0usize); +add_sub_const_decimals!(7usize, 60usize, 67usize, 0usize); +add_sub_const_decimals!(7usize, 59usize, 66usize, 0usize); +add_sub_const_decimals!(7usize, 58usize, 65usize, 0usize); +add_sub_const_decimals!(7usize, 57usize, 64usize, 0usize); +add_sub_const_decimals!(7usize, 56usize, 63usize, 0usize); +add_sub_const_decimals!(7usize, 55usize, 62usize, 0usize); +add_sub_const_decimals!(7usize, 54usize, 61usize, 0usize); +add_sub_const_decimals!(7usize, 53usize, 60usize, 0usize); +add_sub_const_decimals!(7usize, 52usize, 59usize, 0usize); +add_sub_const_decimals!(7usize, 51usize, 58usize, 0usize); +add_sub_const_decimals!(7usize, 50usize, 57usize, 0usize); +add_sub_const_decimals!(7usize, 49usize, 56usize, 0usize); +add_sub_const_decimals!(7usize, 48usize, 55usize, 0usize); +add_sub_const_decimals!(7usize, 47usize, 54usize, 0usize); +add_sub_const_decimals!(7usize, 46usize, 53usize, 0usize); +add_sub_const_decimals!(7usize, 45usize, 52usize, 0usize); +add_sub_const_decimals!(7usize, 44usize, 51usize, 0usize); +add_sub_const_decimals!(7usize, 43usize, 50usize, 0usize); +add_sub_const_decimals!(7usize, 42usize, 49usize, 0usize); +add_sub_const_decimals!(7usize, 41usize, 48usize, 0usize); +add_sub_const_decimals!(7usize, 40usize, 47usize, 0usize); +add_sub_const_decimals!(7usize, 39usize, 46usize, 0usize); +add_sub_const_decimals!(7usize, 38usize, 45usize, 0usize); +add_sub_const_decimals!(7usize, 37usize, 44usize, 0usize); +add_sub_const_decimals!(7usize, 36usize, 43usize, 0usize); +add_sub_const_decimals!(7usize, 35usize, 42usize, 0usize); +add_sub_const_decimals!(7usize, 34usize, 41usize, 0usize); +add_sub_const_decimals!(7usize, 33usize, 40usize, 0usize); +add_sub_const_decimals!(7usize, 32usize, 39usize, 0usize); +add_sub_const_decimals!(7usize, 31usize, 38usize, 0usize); +add_sub_const_decimals!(7usize, 30usize, 37usize, 0usize); +add_sub_const_decimals!(7usize, 29usize, 36usize, 0usize); +add_sub_const_decimals!(7usize, 28usize, 35usize, 0usize); +add_sub_const_decimals!(7usize, 27usize, 34usize, 0usize); +add_sub_const_decimals!(7usize, 26usize, 33usize, 0usize); +add_sub_const_decimals!(7usize, 25usize, 32usize, 0usize); +add_sub_const_decimals!(7usize, 24usize, 31usize, 0usize); +add_sub_const_decimals!(7usize, 23usize, 30usize, 0usize); +add_sub_const_decimals!(7usize, 22usize, 29usize, 0usize); +add_sub_const_decimals!(7usize, 21usize, 28usize, 0usize); +add_sub_const_decimals!(7usize, 20usize, 27usize, 0usize); +add_sub_const_decimals!(7usize, 19usize, 26usize, 0usize); +add_sub_const_decimals!(7usize, 18usize, 25usize, 0usize); +add_sub_const_decimals!(7usize, 17usize, 24usize, 0usize); +add_sub_const_decimals!(7usize, 16usize, 23usize, 0usize); +add_sub_const_decimals!(7usize, 15usize, 22usize, 0usize); +add_sub_const_decimals!(7usize, 14usize, 21usize, 0usize); +add_sub_const_decimals!(7usize, 13usize, 20usize, 0usize); +add_sub_const_decimals!(7usize, 12usize, 19usize, 0usize); +add_sub_const_decimals!(7usize, 11usize, 18usize, 0usize); +add_sub_const_decimals!(7usize, 10usize, 17usize, 0usize); +add_sub_const_decimals!(7usize, 9usize, 16usize, 0usize); +add_sub_const_decimals!(7usize, 8usize, 15usize, 0usize); +add_sub_const_decimals!(7usize, 7usize, 14usize, 0usize); +add_sub_const_decimals!(7usize, 6usize, 13usize, 1usize); +add_sub_const_decimals!(7usize, 5usize, 12usize, 2usize); +add_sub_const_decimals!(7usize, 4usize, 11usize, 3usize); +add_sub_const_decimals!(7usize, 3usize, 10usize, 4usize); +add_sub_const_decimals!(7usize, 2usize, 9usize, 5usize); +add_sub_const_decimals!(7usize, 1usize, 8usize, 6usize); +add_sub_const_decimals!(7usize, 0usize, 7usize, 7usize); +add_sub_const_decimals!(6usize, 64usize, 70usize, 0usize); +add_sub_const_decimals!(6usize, 63usize, 69usize, 0usize); +add_sub_const_decimals!(6usize, 62usize, 68usize, 0usize); +add_sub_const_decimals!(6usize, 61usize, 67usize, 0usize); +add_sub_const_decimals!(6usize, 60usize, 66usize, 0usize); +add_sub_const_decimals!(6usize, 59usize, 65usize, 0usize); +add_sub_const_decimals!(6usize, 58usize, 64usize, 0usize); +add_sub_const_decimals!(6usize, 57usize, 63usize, 0usize); +add_sub_const_decimals!(6usize, 56usize, 62usize, 0usize); +add_sub_const_decimals!(6usize, 55usize, 61usize, 0usize); +add_sub_const_decimals!(6usize, 54usize, 60usize, 0usize); +add_sub_const_decimals!(6usize, 53usize, 59usize, 0usize); +add_sub_const_decimals!(6usize, 52usize, 58usize, 0usize); +add_sub_const_decimals!(6usize, 51usize, 57usize, 0usize); +add_sub_const_decimals!(6usize, 50usize, 56usize, 0usize); +add_sub_const_decimals!(6usize, 49usize, 55usize, 0usize); +add_sub_const_decimals!(6usize, 48usize, 54usize, 0usize); +add_sub_const_decimals!(6usize, 47usize, 53usize, 0usize); +add_sub_const_decimals!(6usize, 46usize, 52usize, 0usize); +add_sub_const_decimals!(6usize, 45usize, 51usize, 0usize); +add_sub_const_decimals!(6usize, 44usize, 50usize, 0usize); +add_sub_const_decimals!(6usize, 43usize, 49usize, 0usize); +add_sub_const_decimals!(6usize, 42usize, 48usize, 0usize); +add_sub_const_decimals!(6usize, 41usize, 47usize, 0usize); +add_sub_const_decimals!(6usize, 40usize, 46usize, 0usize); +add_sub_const_decimals!(6usize, 39usize, 45usize, 0usize); +add_sub_const_decimals!(6usize, 38usize, 44usize, 0usize); +add_sub_const_decimals!(6usize, 37usize, 43usize, 0usize); +add_sub_const_decimals!(6usize, 36usize, 42usize, 0usize); +add_sub_const_decimals!(6usize, 35usize, 41usize, 0usize); +add_sub_const_decimals!(6usize, 34usize, 40usize, 0usize); +add_sub_const_decimals!(6usize, 33usize, 39usize, 0usize); +add_sub_const_decimals!(6usize, 32usize, 38usize, 0usize); +add_sub_const_decimals!(6usize, 31usize, 37usize, 0usize); +add_sub_const_decimals!(6usize, 30usize, 36usize, 0usize); +add_sub_const_decimals!(6usize, 29usize, 35usize, 0usize); +add_sub_const_decimals!(6usize, 28usize, 34usize, 0usize); +add_sub_const_decimals!(6usize, 27usize, 33usize, 0usize); +add_sub_const_decimals!(6usize, 26usize, 32usize, 0usize); +add_sub_const_decimals!(6usize, 25usize, 31usize, 0usize); +add_sub_const_decimals!(6usize, 24usize, 30usize, 0usize); +add_sub_const_decimals!(6usize, 23usize, 29usize, 0usize); +add_sub_const_decimals!(6usize, 22usize, 28usize, 0usize); +add_sub_const_decimals!(6usize, 21usize, 27usize, 0usize); +add_sub_const_decimals!(6usize, 20usize, 26usize, 0usize); +add_sub_const_decimals!(6usize, 19usize, 25usize, 0usize); +add_sub_const_decimals!(6usize, 18usize, 24usize, 0usize); +add_sub_const_decimals!(6usize, 17usize, 23usize, 0usize); +add_sub_const_decimals!(6usize, 16usize, 22usize, 0usize); +add_sub_const_decimals!(6usize, 15usize, 21usize, 0usize); +add_sub_const_decimals!(6usize, 14usize, 20usize, 0usize); +add_sub_const_decimals!(6usize, 13usize, 19usize, 0usize); +add_sub_const_decimals!(6usize, 12usize, 18usize, 0usize); +add_sub_const_decimals!(6usize, 11usize, 17usize, 0usize); +add_sub_const_decimals!(6usize, 10usize, 16usize, 0usize); +add_sub_const_decimals!(6usize, 9usize, 15usize, 0usize); +add_sub_const_decimals!(6usize, 8usize, 14usize, 0usize); +add_sub_const_decimals!(6usize, 7usize, 13usize, 0usize); +add_sub_const_decimals!(6usize, 6usize, 12usize, 0usize); +add_sub_const_decimals!(6usize, 5usize, 11usize, 1usize); +add_sub_const_decimals!(6usize, 4usize, 10usize, 2usize); +add_sub_const_decimals!(6usize, 3usize, 9usize, 3usize); +add_sub_const_decimals!(6usize, 2usize, 8usize, 4usize); +add_sub_const_decimals!(6usize, 1usize, 7usize, 5usize); +add_sub_const_decimals!(6usize, 0usize, 6usize, 6usize); +add_sub_const_decimals!(5usize, 64usize, 69usize, 0usize); +add_sub_const_decimals!(5usize, 63usize, 68usize, 0usize); +add_sub_const_decimals!(5usize, 62usize, 67usize, 0usize); +add_sub_const_decimals!(5usize, 61usize, 66usize, 0usize); +add_sub_const_decimals!(5usize, 60usize, 65usize, 0usize); +add_sub_const_decimals!(5usize, 59usize, 64usize, 0usize); +add_sub_const_decimals!(5usize, 58usize, 63usize, 0usize); +add_sub_const_decimals!(5usize, 57usize, 62usize, 0usize); +add_sub_const_decimals!(5usize, 56usize, 61usize, 0usize); +add_sub_const_decimals!(5usize, 55usize, 60usize, 0usize); +add_sub_const_decimals!(5usize, 54usize, 59usize, 0usize); +add_sub_const_decimals!(5usize, 53usize, 58usize, 0usize); +add_sub_const_decimals!(5usize, 52usize, 57usize, 0usize); +add_sub_const_decimals!(5usize, 51usize, 56usize, 0usize); +add_sub_const_decimals!(5usize, 50usize, 55usize, 0usize); +add_sub_const_decimals!(5usize, 49usize, 54usize, 0usize); +add_sub_const_decimals!(5usize, 48usize, 53usize, 0usize); +add_sub_const_decimals!(5usize, 47usize, 52usize, 0usize); +add_sub_const_decimals!(5usize, 46usize, 51usize, 0usize); +add_sub_const_decimals!(5usize, 45usize, 50usize, 0usize); +add_sub_const_decimals!(5usize, 44usize, 49usize, 0usize); +add_sub_const_decimals!(5usize, 43usize, 48usize, 0usize); +add_sub_const_decimals!(5usize, 42usize, 47usize, 0usize); +add_sub_const_decimals!(5usize, 41usize, 46usize, 0usize); +add_sub_const_decimals!(5usize, 40usize, 45usize, 0usize); +add_sub_const_decimals!(5usize, 39usize, 44usize, 0usize); +add_sub_const_decimals!(5usize, 38usize, 43usize, 0usize); +add_sub_const_decimals!(5usize, 37usize, 42usize, 0usize); +add_sub_const_decimals!(5usize, 36usize, 41usize, 0usize); +add_sub_const_decimals!(5usize, 35usize, 40usize, 0usize); +add_sub_const_decimals!(5usize, 34usize, 39usize, 0usize); +add_sub_const_decimals!(5usize, 33usize, 38usize, 0usize); +add_sub_const_decimals!(5usize, 32usize, 37usize, 0usize); +add_sub_const_decimals!(5usize, 31usize, 36usize, 0usize); +add_sub_const_decimals!(5usize, 30usize, 35usize, 0usize); +add_sub_const_decimals!(5usize, 29usize, 34usize, 0usize); +add_sub_const_decimals!(5usize, 28usize, 33usize, 0usize); +add_sub_const_decimals!(5usize, 27usize, 32usize, 0usize); +add_sub_const_decimals!(5usize, 26usize, 31usize, 0usize); +add_sub_const_decimals!(5usize, 25usize, 30usize, 0usize); +add_sub_const_decimals!(5usize, 24usize, 29usize, 0usize); +add_sub_const_decimals!(5usize, 23usize, 28usize, 0usize); +add_sub_const_decimals!(5usize, 22usize, 27usize, 0usize); +add_sub_const_decimals!(5usize, 21usize, 26usize, 0usize); +add_sub_const_decimals!(5usize, 20usize, 25usize, 0usize); +add_sub_const_decimals!(5usize, 19usize, 24usize, 0usize); +add_sub_const_decimals!(5usize, 18usize, 23usize, 0usize); +add_sub_const_decimals!(5usize, 17usize, 22usize, 0usize); +add_sub_const_decimals!(5usize, 16usize, 21usize, 0usize); +add_sub_const_decimals!(5usize, 15usize, 20usize, 0usize); +add_sub_const_decimals!(5usize, 14usize, 19usize, 0usize); +add_sub_const_decimals!(5usize, 13usize, 18usize, 0usize); +add_sub_const_decimals!(5usize, 12usize, 17usize, 0usize); +add_sub_const_decimals!(5usize, 11usize, 16usize, 0usize); +add_sub_const_decimals!(5usize, 10usize, 15usize, 0usize); +add_sub_const_decimals!(5usize, 9usize, 14usize, 0usize); +add_sub_const_decimals!(5usize, 8usize, 13usize, 0usize); +add_sub_const_decimals!(5usize, 7usize, 12usize, 0usize); +add_sub_const_decimals!(5usize, 6usize, 11usize, 0usize); +add_sub_const_decimals!(5usize, 5usize, 10usize, 0usize); +add_sub_const_decimals!(5usize, 4usize, 9usize, 1usize); +add_sub_const_decimals!(5usize, 3usize, 8usize, 2usize); +add_sub_const_decimals!(5usize, 2usize, 7usize, 3usize); +add_sub_const_decimals!(5usize, 1usize, 6usize, 4usize); +add_sub_const_decimals!(5usize, 0usize, 5usize, 5usize); +add_sub_const_decimals!(4usize, 64usize, 68usize, 0usize); +add_sub_const_decimals!(4usize, 63usize, 67usize, 0usize); +add_sub_const_decimals!(4usize, 62usize, 66usize, 0usize); +add_sub_const_decimals!(4usize, 61usize, 65usize, 0usize); +add_sub_const_decimals!(4usize, 60usize, 64usize, 0usize); +add_sub_const_decimals!(4usize, 59usize, 63usize, 0usize); +add_sub_const_decimals!(4usize, 58usize, 62usize, 0usize); +add_sub_const_decimals!(4usize, 57usize, 61usize, 0usize); +add_sub_const_decimals!(4usize, 56usize, 60usize, 0usize); +add_sub_const_decimals!(4usize, 55usize, 59usize, 0usize); +add_sub_const_decimals!(4usize, 54usize, 58usize, 0usize); +add_sub_const_decimals!(4usize, 53usize, 57usize, 0usize); +add_sub_const_decimals!(4usize, 52usize, 56usize, 0usize); +add_sub_const_decimals!(4usize, 51usize, 55usize, 0usize); +add_sub_const_decimals!(4usize, 50usize, 54usize, 0usize); +add_sub_const_decimals!(4usize, 49usize, 53usize, 0usize); +add_sub_const_decimals!(4usize, 48usize, 52usize, 0usize); +add_sub_const_decimals!(4usize, 47usize, 51usize, 0usize); +add_sub_const_decimals!(4usize, 46usize, 50usize, 0usize); +add_sub_const_decimals!(4usize, 45usize, 49usize, 0usize); +add_sub_const_decimals!(4usize, 44usize, 48usize, 0usize); +add_sub_const_decimals!(4usize, 43usize, 47usize, 0usize); +add_sub_const_decimals!(4usize, 42usize, 46usize, 0usize); +add_sub_const_decimals!(4usize, 41usize, 45usize, 0usize); +add_sub_const_decimals!(4usize, 40usize, 44usize, 0usize); +add_sub_const_decimals!(4usize, 39usize, 43usize, 0usize); +add_sub_const_decimals!(4usize, 38usize, 42usize, 0usize); +add_sub_const_decimals!(4usize, 37usize, 41usize, 0usize); +add_sub_const_decimals!(4usize, 36usize, 40usize, 0usize); +add_sub_const_decimals!(4usize, 35usize, 39usize, 0usize); +add_sub_const_decimals!(4usize, 34usize, 38usize, 0usize); +add_sub_const_decimals!(4usize, 33usize, 37usize, 0usize); +add_sub_const_decimals!(4usize, 32usize, 36usize, 0usize); +add_sub_const_decimals!(4usize, 31usize, 35usize, 0usize); +add_sub_const_decimals!(4usize, 30usize, 34usize, 0usize); +add_sub_const_decimals!(4usize, 29usize, 33usize, 0usize); +add_sub_const_decimals!(4usize, 28usize, 32usize, 0usize); +add_sub_const_decimals!(4usize, 27usize, 31usize, 0usize); +add_sub_const_decimals!(4usize, 26usize, 30usize, 0usize); +add_sub_const_decimals!(4usize, 25usize, 29usize, 0usize); +add_sub_const_decimals!(4usize, 24usize, 28usize, 0usize); +add_sub_const_decimals!(4usize, 23usize, 27usize, 0usize); +add_sub_const_decimals!(4usize, 22usize, 26usize, 0usize); +add_sub_const_decimals!(4usize, 21usize, 25usize, 0usize); +add_sub_const_decimals!(4usize, 20usize, 24usize, 0usize); +add_sub_const_decimals!(4usize, 19usize, 23usize, 0usize); +add_sub_const_decimals!(4usize, 18usize, 22usize, 0usize); +add_sub_const_decimals!(4usize, 17usize, 21usize, 0usize); +add_sub_const_decimals!(4usize, 16usize, 20usize, 0usize); +add_sub_const_decimals!(4usize, 15usize, 19usize, 0usize); +add_sub_const_decimals!(4usize, 14usize, 18usize, 0usize); +add_sub_const_decimals!(4usize, 13usize, 17usize, 0usize); +add_sub_const_decimals!(4usize, 12usize, 16usize, 0usize); +add_sub_const_decimals!(4usize, 11usize, 15usize, 0usize); +add_sub_const_decimals!(4usize, 10usize, 14usize, 0usize); +add_sub_const_decimals!(4usize, 9usize, 13usize, 0usize); +add_sub_const_decimals!(4usize, 8usize, 12usize, 0usize); +add_sub_const_decimals!(4usize, 7usize, 11usize, 0usize); +add_sub_const_decimals!(4usize, 6usize, 10usize, 0usize); +add_sub_const_decimals!(4usize, 5usize, 9usize, 0usize); +add_sub_const_decimals!(4usize, 4usize, 8usize, 0usize); +add_sub_const_decimals!(4usize, 3usize, 7usize, 1usize); +add_sub_const_decimals!(4usize, 2usize, 6usize, 2usize); +add_sub_const_decimals!(4usize, 1usize, 5usize, 3usize); +add_sub_const_decimals!(4usize, 0usize, 4usize, 4usize); +add_sub_const_decimals!(3usize, 64usize, 67usize, 0usize); +add_sub_const_decimals!(3usize, 63usize, 66usize, 0usize); +add_sub_const_decimals!(3usize, 62usize, 65usize, 0usize); +add_sub_const_decimals!(3usize, 61usize, 64usize, 0usize); +add_sub_const_decimals!(3usize, 60usize, 63usize, 0usize); +add_sub_const_decimals!(3usize, 59usize, 62usize, 0usize); +add_sub_const_decimals!(3usize, 58usize, 61usize, 0usize); +add_sub_const_decimals!(3usize, 57usize, 60usize, 0usize); +add_sub_const_decimals!(3usize, 56usize, 59usize, 0usize); +add_sub_const_decimals!(3usize, 55usize, 58usize, 0usize); +add_sub_const_decimals!(3usize, 54usize, 57usize, 0usize); +add_sub_const_decimals!(3usize, 53usize, 56usize, 0usize); +add_sub_const_decimals!(3usize, 52usize, 55usize, 0usize); +add_sub_const_decimals!(3usize, 51usize, 54usize, 0usize); +add_sub_const_decimals!(3usize, 50usize, 53usize, 0usize); +add_sub_const_decimals!(3usize, 49usize, 52usize, 0usize); +add_sub_const_decimals!(3usize, 48usize, 51usize, 0usize); +add_sub_const_decimals!(3usize, 47usize, 50usize, 0usize); +add_sub_const_decimals!(3usize, 46usize, 49usize, 0usize); +add_sub_const_decimals!(3usize, 45usize, 48usize, 0usize); +add_sub_const_decimals!(3usize, 44usize, 47usize, 0usize); +add_sub_const_decimals!(3usize, 43usize, 46usize, 0usize); +add_sub_const_decimals!(3usize, 42usize, 45usize, 0usize); +add_sub_const_decimals!(3usize, 41usize, 44usize, 0usize); +add_sub_const_decimals!(3usize, 40usize, 43usize, 0usize); +add_sub_const_decimals!(3usize, 39usize, 42usize, 0usize); +add_sub_const_decimals!(3usize, 38usize, 41usize, 0usize); +add_sub_const_decimals!(3usize, 37usize, 40usize, 0usize); +add_sub_const_decimals!(3usize, 36usize, 39usize, 0usize); +add_sub_const_decimals!(3usize, 35usize, 38usize, 0usize); +add_sub_const_decimals!(3usize, 34usize, 37usize, 0usize); +add_sub_const_decimals!(3usize, 33usize, 36usize, 0usize); +add_sub_const_decimals!(3usize, 32usize, 35usize, 0usize); +add_sub_const_decimals!(3usize, 31usize, 34usize, 0usize); +add_sub_const_decimals!(3usize, 30usize, 33usize, 0usize); +add_sub_const_decimals!(3usize, 29usize, 32usize, 0usize); +add_sub_const_decimals!(3usize, 28usize, 31usize, 0usize); +add_sub_const_decimals!(3usize, 27usize, 30usize, 0usize); +add_sub_const_decimals!(3usize, 26usize, 29usize, 0usize); +add_sub_const_decimals!(3usize, 25usize, 28usize, 0usize); +add_sub_const_decimals!(3usize, 24usize, 27usize, 0usize); +add_sub_const_decimals!(3usize, 23usize, 26usize, 0usize); +add_sub_const_decimals!(3usize, 22usize, 25usize, 0usize); +add_sub_const_decimals!(3usize, 21usize, 24usize, 0usize); +add_sub_const_decimals!(3usize, 20usize, 23usize, 0usize); +add_sub_const_decimals!(3usize, 19usize, 22usize, 0usize); +add_sub_const_decimals!(3usize, 18usize, 21usize, 0usize); +add_sub_const_decimals!(3usize, 17usize, 20usize, 0usize); +add_sub_const_decimals!(3usize, 16usize, 19usize, 0usize); +add_sub_const_decimals!(3usize, 15usize, 18usize, 0usize); +add_sub_const_decimals!(3usize, 14usize, 17usize, 0usize); +add_sub_const_decimals!(3usize, 13usize, 16usize, 0usize); +add_sub_const_decimals!(3usize, 12usize, 15usize, 0usize); +add_sub_const_decimals!(3usize, 11usize, 14usize, 0usize); +add_sub_const_decimals!(3usize, 10usize, 13usize, 0usize); +add_sub_const_decimals!(3usize, 9usize, 12usize, 0usize); +add_sub_const_decimals!(3usize, 8usize, 11usize, 0usize); +add_sub_const_decimals!(3usize, 7usize, 10usize, 0usize); +add_sub_const_decimals!(3usize, 6usize, 9usize, 0usize); +add_sub_const_decimals!(3usize, 5usize, 8usize, 0usize); +add_sub_const_decimals!(3usize, 4usize, 7usize, 0usize); +add_sub_const_decimals!(3usize, 3usize, 6usize, 0usize); +add_sub_const_decimals!(3usize, 2usize, 5usize, 1usize); +add_sub_const_decimals!(3usize, 1usize, 4usize, 2usize); +add_sub_const_decimals!(3usize, 0usize, 3usize, 3usize); +add_sub_const_decimals!(2usize, 64usize, 66usize, 0usize); +add_sub_const_decimals!(2usize, 63usize, 65usize, 0usize); +add_sub_const_decimals!(2usize, 62usize, 64usize, 0usize); +add_sub_const_decimals!(2usize, 61usize, 63usize, 0usize); +add_sub_const_decimals!(2usize, 60usize, 62usize, 0usize); +add_sub_const_decimals!(2usize, 59usize, 61usize, 0usize); +add_sub_const_decimals!(2usize, 58usize, 60usize, 0usize); +add_sub_const_decimals!(2usize, 57usize, 59usize, 0usize); +add_sub_const_decimals!(2usize, 56usize, 58usize, 0usize); +add_sub_const_decimals!(2usize, 55usize, 57usize, 0usize); +add_sub_const_decimals!(2usize, 54usize, 56usize, 0usize); +add_sub_const_decimals!(2usize, 53usize, 55usize, 0usize); +add_sub_const_decimals!(2usize, 52usize, 54usize, 0usize); +add_sub_const_decimals!(2usize, 51usize, 53usize, 0usize); +add_sub_const_decimals!(2usize, 50usize, 52usize, 0usize); +add_sub_const_decimals!(2usize, 49usize, 51usize, 0usize); +add_sub_const_decimals!(2usize, 48usize, 50usize, 0usize); +add_sub_const_decimals!(2usize, 47usize, 49usize, 0usize); +add_sub_const_decimals!(2usize, 46usize, 48usize, 0usize); +add_sub_const_decimals!(2usize, 45usize, 47usize, 0usize); +add_sub_const_decimals!(2usize, 44usize, 46usize, 0usize); +add_sub_const_decimals!(2usize, 43usize, 45usize, 0usize); +add_sub_const_decimals!(2usize, 42usize, 44usize, 0usize); +add_sub_const_decimals!(2usize, 41usize, 43usize, 0usize); +add_sub_const_decimals!(2usize, 40usize, 42usize, 0usize); +add_sub_const_decimals!(2usize, 39usize, 41usize, 0usize); +add_sub_const_decimals!(2usize, 38usize, 40usize, 0usize); +add_sub_const_decimals!(2usize, 37usize, 39usize, 0usize); +add_sub_const_decimals!(2usize, 36usize, 38usize, 0usize); +add_sub_const_decimals!(2usize, 35usize, 37usize, 0usize); +add_sub_const_decimals!(2usize, 34usize, 36usize, 0usize); +add_sub_const_decimals!(2usize, 33usize, 35usize, 0usize); +add_sub_const_decimals!(2usize, 32usize, 34usize, 0usize); +add_sub_const_decimals!(2usize, 31usize, 33usize, 0usize); +add_sub_const_decimals!(2usize, 30usize, 32usize, 0usize); +add_sub_const_decimals!(2usize, 29usize, 31usize, 0usize); +add_sub_const_decimals!(2usize, 28usize, 30usize, 0usize); +add_sub_const_decimals!(2usize, 27usize, 29usize, 0usize); +add_sub_const_decimals!(2usize, 26usize, 28usize, 0usize); +add_sub_const_decimals!(2usize, 25usize, 27usize, 0usize); +add_sub_const_decimals!(2usize, 24usize, 26usize, 0usize); +add_sub_const_decimals!(2usize, 23usize, 25usize, 0usize); +add_sub_const_decimals!(2usize, 22usize, 24usize, 0usize); +add_sub_const_decimals!(2usize, 21usize, 23usize, 0usize); +add_sub_const_decimals!(2usize, 20usize, 22usize, 0usize); +add_sub_const_decimals!(2usize, 19usize, 21usize, 0usize); +add_sub_const_decimals!(2usize, 18usize, 20usize, 0usize); +add_sub_const_decimals!(2usize, 17usize, 19usize, 0usize); +add_sub_const_decimals!(2usize, 16usize, 18usize, 0usize); +add_sub_const_decimals!(2usize, 15usize, 17usize, 0usize); +add_sub_const_decimals!(2usize, 14usize, 16usize, 0usize); +add_sub_const_decimals!(2usize, 13usize, 15usize, 0usize); +add_sub_const_decimals!(2usize, 12usize, 14usize, 0usize); +add_sub_const_decimals!(2usize, 11usize, 13usize, 0usize); +add_sub_const_decimals!(2usize, 10usize, 12usize, 0usize); +add_sub_const_decimals!(2usize, 9usize, 11usize, 0usize); +add_sub_const_decimals!(2usize, 8usize, 10usize, 0usize); +add_sub_const_decimals!(2usize, 7usize, 9usize, 0usize); +add_sub_const_decimals!(2usize, 6usize, 8usize, 0usize); +add_sub_const_decimals!(2usize, 5usize, 7usize, 0usize); +add_sub_const_decimals!(2usize, 4usize, 6usize, 0usize); +add_sub_const_decimals!(2usize, 3usize, 5usize, 0usize); +add_sub_const_decimals!(2usize, 2usize, 4usize, 0usize); +add_sub_const_decimals!(2usize, 1usize, 3usize, 1usize); +add_sub_const_decimals!(2usize, 0usize, 2usize, 2usize); +add_sub_const_decimals!(1usize, 64usize, 65usize, 0usize); +add_sub_const_decimals!(1usize, 63usize, 64usize, 0usize); +add_sub_const_decimals!(1usize, 62usize, 63usize, 0usize); +add_sub_const_decimals!(1usize, 61usize, 62usize, 0usize); +add_sub_const_decimals!(1usize, 60usize, 61usize, 0usize); +add_sub_const_decimals!(1usize, 59usize, 60usize, 0usize); +add_sub_const_decimals!(1usize, 58usize, 59usize, 0usize); +add_sub_const_decimals!(1usize, 57usize, 58usize, 0usize); +add_sub_const_decimals!(1usize, 56usize, 57usize, 0usize); +add_sub_const_decimals!(1usize, 55usize, 56usize, 0usize); +add_sub_const_decimals!(1usize, 54usize, 55usize, 0usize); +add_sub_const_decimals!(1usize, 53usize, 54usize, 0usize); +add_sub_const_decimals!(1usize, 52usize, 53usize, 0usize); +add_sub_const_decimals!(1usize, 51usize, 52usize, 0usize); +add_sub_const_decimals!(1usize, 50usize, 51usize, 0usize); +add_sub_const_decimals!(1usize, 49usize, 50usize, 0usize); +add_sub_const_decimals!(1usize, 48usize, 49usize, 0usize); +add_sub_const_decimals!(1usize, 47usize, 48usize, 0usize); +add_sub_const_decimals!(1usize, 46usize, 47usize, 0usize); +add_sub_const_decimals!(1usize, 45usize, 46usize, 0usize); +add_sub_const_decimals!(1usize, 44usize, 45usize, 0usize); +add_sub_const_decimals!(1usize, 43usize, 44usize, 0usize); +add_sub_const_decimals!(1usize, 42usize, 43usize, 0usize); +add_sub_const_decimals!(1usize, 41usize, 42usize, 0usize); +add_sub_const_decimals!(1usize, 40usize, 41usize, 0usize); +add_sub_const_decimals!(1usize, 39usize, 40usize, 0usize); +add_sub_const_decimals!(1usize, 38usize, 39usize, 0usize); +add_sub_const_decimals!(1usize, 37usize, 38usize, 0usize); +add_sub_const_decimals!(1usize, 36usize, 37usize, 0usize); +add_sub_const_decimals!(1usize, 35usize, 36usize, 0usize); +add_sub_const_decimals!(1usize, 34usize, 35usize, 0usize); +add_sub_const_decimals!(1usize, 33usize, 34usize, 0usize); +add_sub_const_decimals!(1usize, 32usize, 33usize, 0usize); +add_sub_const_decimals!(1usize, 31usize, 32usize, 0usize); +add_sub_const_decimals!(1usize, 30usize, 31usize, 0usize); +add_sub_const_decimals!(1usize, 29usize, 30usize, 0usize); +add_sub_const_decimals!(1usize, 28usize, 29usize, 0usize); +add_sub_const_decimals!(1usize, 27usize, 28usize, 0usize); +add_sub_const_decimals!(1usize, 26usize, 27usize, 0usize); +add_sub_const_decimals!(1usize, 25usize, 26usize, 0usize); +add_sub_const_decimals!(1usize, 24usize, 25usize, 0usize); +add_sub_const_decimals!(1usize, 23usize, 24usize, 0usize); +add_sub_const_decimals!(1usize, 22usize, 23usize, 0usize); +add_sub_const_decimals!(1usize, 21usize, 22usize, 0usize); +add_sub_const_decimals!(1usize, 20usize, 21usize, 0usize); +add_sub_const_decimals!(1usize, 19usize, 20usize, 0usize); +add_sub_const_decimals!(1usize, 18usize, 19usize, 0usize); +add_sub_const_decimals!(1usize, 17usize, 18usize, 0usize); +add_sub_const_decimals!(1usize, 16usize, 17usize, 0usize); +add_sub_const_decimals!(1usize, 15usize, 16usize, 0usize); +add_sub_const_decimals!(1usize, 14usize, 15usize, 0usize); +add_sub_const_decimals!(1usize, 13usize, 14usize, 0usize); +add_sub_const_decimals!(1usize, 12usize, 13usize, 0usize); +add_sub_const_decimals!(1usize, 11usize, 12usize, 0usize); +add_sub_const_decimals!(1usize, 10usize, 11usize, 0usize); +add_sub_const_decimals!(1usize, 9usize, 10usize, 0usize); +add_sub_const_decimals!(1usize, 8usize, 9usize, 0usize); +add_sub_const_decimals!(1usize, 7usize, 8usize, 0usize); +add_sub_const_decimals!(1usize, 6usize, 7usize, 0usize); +add_sub_const_decimals!(1usize, 5usize, 6usize, 0usize); +add_sub_const_decimals!(1usize, 4usize, 5usize, 0usize); +add_sub_const_decimals!(1usize, 3usize, 4usize, 0usize); +add_sub_const_decimals!(1usize, 2usize, 3usize, 0usize); +add_sub_const_decimals!(1usize, 1usize, 2usize, 0usize); +add_sub_const_decimals!(1usize, 0usize, 1usize, 1usize); +add_sub_const_decimals!(0usize, 64usize, 64usize, 0usize); +add_sub_const_decimals!(0usize, 63usize, 63usize, 0usize); +add_sub_const_decimals!(0usize, 62usize, 62usize, 0usize); +add_sub_const_decimals!(0usize, 61usize, 61usize, 0usize); +add_sub_const_decimals!(0usize, 60usize, 60usize, 0usize); +add_sub_const_decimals!(0usize, 59usize, 59usize, 0usize); +add_sub_const_decimals!(0usize, 58usize, 58usize, 0usize); +add_sub_const_decimals!(0usize, 57usize, 57usize, 0usize); +add_sub_const_decimals!(0usize, 56usize, 56usize, 0usize); +add_sub_const_decimals!(0usize, 55usize, 55usize, 0usize); +add_sub_const_decimals!(0usize, 54usize, 54usize, 0usize); +add_sub_const_decimals!(0usize, 53usize, 53usize, 0usize); +add_sub_const_decimals!(0usize, 52usize, 52usize, 0usize); +add_sub_const_decimals!(0usize, 51usize, 51usize, 0usize); +add_sub_const_decimals!(0usize, 50usize, 50usize, 0usize); +add_sub_const_decimals!(0usize, 49usize, 49usize, 0usize); +add_sub_const_decimals!(0usize, 48usize, 48usize, 0usize); +add_sub_const_decimals!(0usize, 47usize, 47usize, 0usize); +add_sub_const_decimals!(0usize, 46usize, 46usize, 0usize); +add_sub_const_decimals!(0usize, 45usize, 45usize, 0usize); +add_sub_const_decimals!(0usize, 44usize, 44usize, 0usize); +add_sub_const_decimals!(0usize, 43usize, 43usize, 0usize); +add_sub_const_decimals!(0usize, 42usize, 42usize, 0usize); +add_sub_const_decimals!(0usize, 41usize, 41usize, 0usize); +add_sub_const_decimals!(0usize, 40usize, 40usize, 0usize); +add_sub_const_decimals!(0usize, 39usize, 39usize, 0usize); +add_sub_const_decimals!(0usize, 38usize, 38usize, 0usize); +add_sub_const_decimals!(0usize, 37usize, 37usize, 0usize); +add_sub_const_decimals!(0usize, 36usize, 36usize, 0usize); +add_sub_const_decimals!(0usize, 35usize, 35usize, 0usize); +add_sub_const_decimals!(0usize, 34usize, 34usize, 0usize); +add_sub_const_decimals!(0usize, 33usize, 33usize, 0usize); +add_sub_const_decimals!(0usize, 32usize, 32usize, 0usize); +add_sub_const_decimals!(0usize, 31usize, 31usize, 0usize); +add_sub_const_decimals!(0usize, 30usize, 30usize, 0usize); +add_sub_const_decimals!(0usize, 29usize, 29usize, 0usize); +add_sub_const_decimals!(0usize, 28usize, 28usize, 0usize); +add_sub_const_decimals!(0usize, 27usize, 27usize, 0usize); +add_sub_const_decimals!(0usize, 26usize, 26usize, 0usize); +add_sub_const_decimals!(0usize, 25usize, 25usize, 0usize); +add_sub_const_decimals!(0usize, 24usize, 24usize, 0usize); +add_sub_const_decimals!(0usize, 23usize, 23usize, 0usize); +add_sub_const_decimals!(0usize, 22usize, 22usize, 0usize); +add_sub_const_decimals!(0usize, 21usize, 21usize, 0usize); +add_sub_const_decimals!(0usize, 20usize, 20usize, 0usize); +add_sub_const_decimals!(0usize, 19usize, 19usize, 0usize); +add_sub_const_decimals!(0usize, 18usize, 18usize, 0usize); +add_sub_const_decimals!(0usize, 17usize, 17usize, 0usize); +add_sub_const_decimals!(0usize, 16usize, 16usize, 0usize); +add_sub_const_decimals!(0usize, 15usize, 15usize, 0usize); +add_sub_const_decimals!(0usize, 14usize, 14usize, 0usize); +add_sub_const_decimals!(0usize, 13usize, 13usize, 0usize); +add_sub_const_decimals!(0usize, 12usize, 12usize, 0usize); +add_sub_const_decimals!(0usize, 11usize, 11usize, 0usize); +add_sub_const_decimals!(0usize, 10usize, 10usize, 0usize); +add_sub_const_decimals!(0usize, 9usize, 9usize, 0usize); +add_sub_const_decimals!(0usize, 8usize, 8usize, 0usize); +add_sub_const_decimals!(0usize, 7usize, 7usize, 0usize); +add_sub_const_decimals!(0usize, 6usize, 6usize, 0usize); +add_sub_const_decimals!(0usize, 5usize, 5usize, 0usize); +add_sub_const_decimals!(0usize, 4usize, 4usize, 0usize); +add_sub_const_decimals!(0usize, 3usize, 3usize, 0usize); +add_sub_const_decimals!(0usize, 2usize, 2usize, 0usize); +add_sub_const_decimals!(0usize, 1usize, 1usize, 0usize); +add_sub_const_decimals!(0usize, 0usize, 0usize, 0usize); diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_add.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_add.rs new file mode 100644 index 0000000000..5129a18dee --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_add.rs @@ -0,0 +1,78 @@ +use crate::{ + api::ManagedTypeApi, + types::{ConstDecimals, Decimals, ManagedDecimal, NumDecimals}, +}; + +use core::ops::{Add, AddAssign}; + +impl AddAssign<&ManagedDecimal> + for ManagedDecimal +{ + fn add_assign(&mut self, rhs: &ManagedDecimal) { + let scaled_data = rhs.rescale_data(self.scale().num_decimals()); + self.data += scaled_data; + } +} + +impl AddAssign> + for ManagedDecimal +{ + #[inline] + fn add_assign(&mut self, rhs: ManagedDecimal) { + self.add_assign(&rhs); + } +} + +// const + const +impl Add>> + for ManagedDecimal> +{ + type Output = Self; + + fn add(mut self, rhs: ManagedDecimal>) -> Self::Output { + self.data += rhs.data; + self + } +} + +// var + var +impl Add> for ManagedDecimal { + type Output = Self; + + fn add(mut self, rhs: ManagedDecimal) -> Self::Output { + match self.decimals.cmp(&rhs.decimals) { + core::cmp::Ordering::Less => { + self = self.rescale(rhs.decimals); + self.data += rhs.data; + }, + core::cmp::Ordering::Equal => self.data += rhs.data, + core::cmp::Ordering::Greater => { + let rhs_data = rhs.rescale_data(self.decimals); + self.data += rhs_data; + }, + } + self + } +} + +// var + const +impl Add>> + for ManagedDecimal +{ + type Output = ManagedDecimal; + + fn add(self, rhs: ManagedDecimal>) -> Self::Output { + self + rhs.into_var_decimals() + } +} + +// const + var +impl Add> + for ManagedDecimal> +{ + type Output = ManagedDecimal; + + fn add(self, rhs: ManagedDecimal) -> Self::Output { + self.into_var_decimals() + rhs + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_add_signed.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_add_signed.rs new file mode 100644 index 0000000000..20247e3c38 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_add_signed.rs @@ -0,0 +1,81 @@ +use crate::{ + api::ManagedTypeApi, + types::{ConstDecimals, Decimals, ManagedDecimalSigned, NumDecimals}, +}; + +use core::ops::{Add, AddAssign}; + +impl AddAssign<&ManagedDecimalSigned> + for ManagedDecimalSigned +{ + fn add_assign(&mut self, rhs: &ManagedDecimalSigned) { + let scaled_data = rhs.rescale_data(self.scale().num_decimals()); + self.data += scaled_data; + } +} + +impl AddAssign> + for ManagedDecimalSigned +{ + #[inline] + fn add_assign(&mut self, rhs: ManagedDecimalSigned) { + self.add_assign(&rhs); + } +} + +// const + const +impl + Add>> + for ManagedDecimalSigned> +{ + type Output = Self; + + fn add(mut self, rhs: ManagedDecimalSigned>) -> Self::Output { + self.data += rhs.data; + self + } +} + +// var + var +impl Add> + for ManagedDecimalSigned +{ + type Output = Self; + + fn add(mut self, rhs: ManagedDecimalSigned) -> Self::Output { + match self.decimals.cmp(&rhs.decimals) { + core::cmp::Ordering::Less => { + self = self.rescale(rhs.decimals); + self.data += rhs.data; + }, + core::cmp::Ordering::Equal => self.data += rhs.data, + core::cmp::Ordering::Greater => { + let rhs_data = rhs.rescale_data(self.decimals); + self.data += rhs_data; + }, + } + self + } +} + +// var + const +impl Add>> + for ManagedDecimalSigned +{ + type Output = ManagedDecimalSigned; + + fn add(self, rhs: ManagedDecimalSigned>) -> Self::Output { + self + rhs.into_var_decimals() + } +} + +// const + var +impl Add> + for ManagedDecimalSigned> +{ + type Output = ManagedDecimalSigned; + + fn add(self, rhs: ManagedDecimalSigned) -> Self::Output { + self.into_var_decimals() + rhs + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_div.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_div.rs new file mode 100644 index 0000000000..50870dc9f4 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_div.rs @@ -0,0 +1,51 @@ +use crate::{ + api::ManagedTypeApi, + types::{BigUint, Decimals, ManagedDecimal, NumDecimals}, +}; + +use core::ops::{Deref, Div, DivAssign, Sub}; + +impl DivAssign<&ManagedDecimal> + for ManagedDecimal +{ + fn div_assign(&mut self, rhs: &ManagedDecimal) { + self.data *= rhs.scaling_factor().deref(); + self.data /= &rhs.data; + } +} + +impl DivAssign> + for ManagedDecimal +{ + #[inline] + fn div_assign(&mut self, rhs: ManagedDecimal) { + self.div_assign(&rhs); + } +} + +impl Div for ManagedDecimal { + type Output = Self; + + fn div(self, other: NumDecimals) -> Self::Output { + ManagedDecimal { + data: self.data / BigUint::from(other), + decimals: self.decimals, + } + } +} + +impl Div> + for ManagedDecimal +where + D1: Sub, + >::Output: Decimals, +{ + type Output = ManagedDecimal>::Output>; + + fn div(self, other: ManagedDecimal) -> Self::Output { + ManagedDecimal { + data: self.data / other.data, + decimals: self.decimals - other.decimals, + } + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_div_signed.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_div_signed.rs new file mode 100644 index 0000000000..c5c5b21775 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_div_signed.rs @@ -0,0 +1,51 @@ +use crate::{ + api::ManagedTypeApi, + types::{BigUint, Decimals, ManagedDecimalSigned, NumDecimals}, +}; + +use core::ops::{Div, DivAssign, Sub}; + +impl DivAssign<&ManagedDecimalSigned> + for ManagedDecimalSigned +{ + fn div_assign(&mut self, rhs: &ManagedDecimalSigned) { + self.data *= rhs.scaling_factor().as_big_int(); + self.data /= &rhs.data; + } +} + +impl DivAssign> + for ManagedDecimalSigned +{ + #[inline] + fn div_assign(&mut self, rhs: ManagedDecimalSigned) { + self.div_assign(&rhs); + } +} + +impl Div for ManagedDecimalSigned { + type Output = Self; + + fn div(self, other: NumDecimals) -> Self::Output { + ManagedDecimalSigned { + data: self.data / BigUint::from(other), + decimals: self.decimals, + } + } +} + +impl Div> + for ManagedDecimalSigned +where + D1: Sub, + >::Output: Decimals, +{ + type Output = ManagedDecimalSigned>::Output>; + + fn div(self, other: ManagedDecimalSigned) -> Self::Output { + ManagedDecimalSigned { + data: self.data / other.data, + decimals: self.decimals - other.decimals, + } + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_mul.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_mul.rs new file mode 100644 index 0000000000..758b57e3b2 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_mul.rs @@ -0,0 +1,54 @@ +use crate::{ + api::ManagedTypeApi, + types::{Decimals, ManagedDecimal}, +}; + +use core::ops::{Add, Deref, Mul, MulAssign}; + +impl MulAssign<&ManagedDecimal> + for ManagedDecimal +{ + fn mul_assign(&mut self, rhs: &ManagedDecimal) { + self.data *= &rhs.data; + self.data /= rhs.scaling_factor().deref(); + } +} + +impl MulAssign> + for ManagedDecimal +{ + #[inline] + fn mul_assign(&mut self, rhs: ManagedDecimal) { + self.mul_assign(&rhs); + } +} + +impl Mul> + for ManagedDecimal +where + D1: Add, + >::Output: Decimals, +{ + type Output = ManagedDecimal>::Output>; + + fn mul(self, other: ManagedDecimal) -> Self::Output { + ManagedDecimal { + data: self.data * other.data, + decimals: self.decimals + other.decimals, + } + } +} + +impl ManagedDecimal { + pub fn mul_with_precision( + self, + other: ManagedDecimal, + precision: T, + ) -> ManagedDecimal { + let result = ManagedDecimal { + data: self.data * other.data, + decimals: self.decimals.num_decimals() + other.decimals.num_decimals(), + }; + result.rescale(precision) + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_mul_signed.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_mul_signed.rs new file mode 100644 index 0000000000..be8a3f7145 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_mul_signed.rs @@ -0,0 +1,54 @@ +use crate::{ + api::ManagedTypeApi, + types::{Decimals, ManagedDecimalSigned}, +}; + +use core::ops::{Add, Mul, MulAssign}; + +impl MulAssign<&ManagedDecimalSigned> + for ManagedDecimalSigned +{ + fn mul_assign(&mut self, rhs: &ManagedDecimalSigned) { + self.data *= &rhs.data; + self.data /= rhs.scaling_factor().as_big_int(); + } +} + +impl MulAssign> + for ManagedDecimalSigned +{ + #[inline] + fn mul_assign(&mut self, rhs: ManagedDecimalSigned) { + self.mul_assign(&rhs); + } +} + +impl Mul> + for ManagedDecimalSigned +where + D1: Add, + >::Output: Decimals, +{ + type Output = ManagedDecimalSigned>::Output>; + + fn mul(self, other: ManagedDecimalSigned) -> Self::Output { + ManagedDecimalSigned { + data: self.data * other.data, + decimals: self.decimals + other.decimals, + } + } +} + +impl ManagedDecimalSigned { + pub fn mul_with_precision( + self, + other: ManagedDecimalSigned, + precision: T, + ) -> ManagedDecimalSigned { + let result = ManagedDecimalSigned { + data: self.data * other.data, + decimals: self.decimals.num_decimals() + other.decimals.num_decimals(), + }; + result.rescale(precision) + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_sub.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_sub.rs new file mode 100644 index 0000000000..76dbe1b2b2 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_sub.rs @@ -0,0 +1,78 @@ +use crate::{ + api::ManagedTypeApi, + types::{ConstDecimals, Decimals, ManagedDecimal, NumDecimals}, +}; + +use core::ops::{Sub, SubAssign}; + +impl SubAssign<&ManagedDecimal> + for ManagedDecimal +{ + fn sub_assign(&mut self, rhs: &ManagedDecimal) { + let scaled_data = rhs.rescale_data(self.scale().num_decimals()); + self.data -= scaled_data; + } +} + +impl SubAssign> + for ManagedDecimal +{ + #[inline] + fn sub_assign(&mut self, rhs: ManagedDecimal) { + self.sub_assign(&rhs); + } +} + +// const + const +impl Sub>> + for ManagedDecimal> +{ + type Output = Self; + + fn sub(mut self, rhs: ManagedDecimal>) -> Self::Output { + self.data -= rhs.data; + self + } +} + +// var + var +impl Sub> for ManagedDecimal { + type Output = Self; + + fn sub(mut self, rhs: ManagedDecimal) -> Self::Output { + match self.decimals.cmp(&rhs.decimals) { + core::cmp::Ordering::Less => { + self = self.rescale(rhs.decimals); + self.data -= rhs.data; + }, + core::cmp::Ordering::Equal => self.data -= rhs.data, + core::cmp::Ordering::Greater => { + let rhs_data = rhs.rescale_data(self.decimals); + self.data -= rhs_data; + }, + } + self + } +} + +// var + const +impl Sub>> + for ManagedDecimal +{ + type Output = ManagedDecimal; + + fn sub(self, rhs: ManagedDecimal>) -> Self::Output { + self - rhs.into_var_decimals() + } +} + +// const + var +impl Sub> + for ManagedDecimal> +{ + type Output = ManagedDecimal; + + fn sub(self, rhs: ManagedDecimal) -> Self::Output { + self.into_var_decimals() - rhs + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_sub_signed.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_sub_signed.rs new file mode 100644 index 0000000000..14ad72e1c1 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_op_sub_signed.rs @@ -0,0 +1,81 @@ +use crate::{ + api::ManagedTypeApi, + types::{ConstDecimals, Decimals, ManagedDecimalSigned, NumDecimals}, +}; + +use core::ops::{Sub, SubAssign}; + +impl SubAssign<&ManagedDecimalSigned> + for ManagedDecimalSigned +{ + fn sub_assign(&mut self, rhs: &ManagedDecimalSigned) { + let scaled_data = rhs.rescale_data(self.scale().num_decimals()); + self.data -= scaled_data; + } +} + +impl SubAssign> + for ManagedDecimalSigned +{ + #[inline] + fn sub_assign(&mut self, rhs: ManagedDecimalSigned) { + self.sub_assign(&rhs); + } +} + +// const + const +impl + Sub>> + for ManagedDecimalSigned> +{ + type Output = Self; + + fn sub(mut self, rhs: ManagedDecimalSigned>) -> Self::Output { + self.data -= rhs.data; + self + } +} + +// var + var +impl Sub> + for ManagedDecimalSigned +{ + type Output = Self; + + fn sub(mut self, rhs: ManagedDecimalSigned) -> Self::Output { + match self.decimals.cmp(&rhs.decimals) { + core::cmp::Ordering::Less => { + self = self.rescale(rhs.decimals); + self.data -= rhs.data; + }, + core::cmp::Ordering::Equal => self.data -= rhs.data, + core::cmp::Ordering::Greater => { + let rhs_data = rhs.rescale_data(self.decimals); + self.data -= rhs_data; + }, + } + self + } +} + +// var + const +impl Sub>> + for ManagedDecimalSigned +{ + type Output = ManagedDecimalSigned; + + fn sub(self, rhs: ManagedDecimalSigned>) -> Self::Output { + self - rhs.into_var_decimals() + } +} + +// const + var +impl Sub> + for ManagedDecimalSigned> +{ + type Output = ManagedDecimalSigned; + + fn sub(self, rhs: ManagedDecimalSigned) -> Self::Output { + self.into_var_decimals() - rhs + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs new file mode 100644 index 0000000000..c8ee403f37 --- /dev/null +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs @@ -0,0 +1,408 @@ +use crate::{ + abi::{TypeAbi, TypeAbiFrom, TypeName}, + api::{ + const_handles, use_raw_handle, BigFloatApiImpl, BigIntApiImpl, HandleConstraints, + ManagedBufferApiImpl, ManagedTypeApi, + }, + err_msg, + formatter::{FormatBuffer, FormatByteReceiver, SCDisplay}, + types::{BigFloat, BigInt, BigUint, ManagedBuffer, ManagedType, Sign}, +}; + +use alloc::string::ToString; +use multiversx_sc_codec::{ + DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, + NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, +}; + +use core::{cmp::Ordering, ops::Deref}; + +use super::{ + decimals::{ConstDecimals, Decimals, NumDecimals}, + ManagedDecimal, +}; +use super::{ManagedBufferCachedBuilder, ManagedRef}; + +/// Fixed-point decimal numbers that accept either a constant or variable number of decimals. +/// +/// Unlike for `ManagedDecimal`, ngative numbers are also allowed. +#[derive(Clone)] +pub struct ManagedDecimalSigned { + pub(crate) data: BigInt, + pub(crate) decimals: D, +} + +impl ManagedDecimalSigned { + pub fn trunc(&self) -> BigInt { + &self.data / self.decimals.scaling_factor().deref() + } + + pub fn into_raw_units(&self) -> &BigInt { + &self.data + } + + pub fn from_raw_units(data: BigInt, decimals: D) -> Self { + ManagedDecimalSigned { data, decimals } + } + + pub fn scale(&self) -> usize { + self.decimals.num_decimals() + } + + pub fn scaling_factor(&self) -> ManagedRef<'static, M, BigUint> { + self.decimals.scaling_factor() + } + + pub(crate) fn rescale_data(&self, scale_to_num_decimals: NumDecimals) -> BigInt { + let from_num_decimals = self.decimals.num_decimals(); + + match from_num_decimals.cmp(&scale_to_num_decimals) { + Ordering::Less => { + let delta_decimals = scale_to_num_decimals - from_num_decimals; + let scaling_factor: &BigUint = &delta_decimals.scaling_factor(); + &self.data * &scaling_factor.value + }, + Ordering::Equal => self.data.clone(), + Ordering::Greater => { + let delta_decimals = from_num_decimals - scale_to_num_decimals; + let scaling_factor: &BigUint = &delta_decimals.scaling_factor(); + &self.data * &scaling_factor.value + }, + } + } + + pub fn rescale(&self, scale_to: T) -> ManagedDecimalSigned { + let scale_to_num_decimals = scale_to.num_decimals(); + ManagedDecimalSigned::from_raw_units(self.rescale_data(scale_to_num_decimals), scale_to) + } + + pub fn into_unsigned_or_fail(self) -> ManagedDecimal { + ManagedDecimal { + data: self + .data + .into_big_uint() + .unwrap_or_sc_panic(err_msg::UNSIGNED_NEGATIVE), + decimals: self.decimals, + } + } + + pub fn sign(&self) -> Sign { + self.data.sign() + } +} + +impl + ManagedDecimalSigned> +{ + pub fn const_decimals_from_raw(data: BigInt) -> Self { + ManagedDecimalSigned { + data, + decimals: ConstDecimals, + } + } + + /// Converts from constant (compile-time) number of decimals to a variable number of decimals. + pub fn into_var_decimals(self) -> ManagedDecimalSigned { + ManagedDecimalSigned { + data: self.data, + decimals: DECIMALS, + } + } +} + +impl From> + for ManagedDecimalSigned> +{ + fn from(mut value: BigInt) -> Self { + let decimals = ConstDecimals; + value *= decimals.scaling_factor().as_big_int(); + ManagedDecimalSigned { + data: value, + decimals, + } + } +} + +impl From + for ManagedDecimalSigned> +{ + fn from(value: i64) -> Self { + Self::from(BigInt::from(value)) + } +} + +impl ManagedDecimalSigned { + pub fn to_big_float(&self) -> BigFloat { + let result = BigFloat::from_big_int(&self.data); + let temp_handle: M::BigFloatHandle = use_raw_handle(const_handles::BIG_FLOAT_TEMPORARY); + let denominator = self.decimals.scaling_factor::(); + M::managed_type_impl().bf_set_bi(temp_handle.clone(), denominator.handle); + M::managed_type_impl().bf_div(result.handle.clone(), result.handle.clone(), temp_handle); + result + } + + pub fn from_big_float( + big_float: &BigFloat, + num_decimals: T, + ) -> ManagedDecimalSigned { + let scaling_factor: &BigUint = &num_decimals.scaling_factor(); + + let scaled = &BigFloat::from(scaling_factor) * big_float; + let fixed_big_int = scaled.trunc(); + + ManagedDecimalSigned::from_raw_units(fixed_big_int, num_decimals) + } +} + +impl From<&BigFloat> + for ManagedDecimalSigned> +{ + fn from(value: &BigFloat) -> Self { + Self::from_big_float(value, ConstDecimals) + } +} + +impl From> + for ManagedDecimalSigned> +{ + #[inline] + fn from(value: BigFloat) -> Self { + Self::from(&value) + } +} + +impl From + for ManagedDecimalSigned> +{ + fn from(x: f64) -> Self { + Self::from(BigFloat::from(x)) + } +} + +impl From + for ManagedDecimalSigned> +{ + fn from(x: f32) -> Self { + Self::from(x as f64) + } +} + +impl TopEncode + for ManagedDecimalSigned> +{ + #[inline] + fn top_encode_or_handle_err(&self, output: O, h: H) -> Result<(), H::HandledErr> + where + O: TopEncodeOutput, + H: EncodeErrorHandler, + { + self.data.top_encode_or_handle_err(output, h) + } +} + +impl TopDecode + for ManagedDecimalSigned> +{ + fn top_decode_or_handle_err(input: I, h: H) -> Result + where + I: TopDecodeInput, + H: DecodeErrorHandler, + { + Ok(ManagedDecimalSigned::const_decimals_from_raw( + BigInt::top_decode_or_handle_err(input, h)?, + )) + } +} + +impl NestedEncode + for ManagedDecimalSigned> +{ + fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> + where + O: NestedEncodeOutput, + H: EncodeErrorHandler, + { + NestedEncode::dep_encode_or_handle_err(&self.data, dest, h)?; + + Result::Ok(()) + } +} + +impl NestedDecode + for ManagedDecimalSigned> +{ + fn dep_decode_or_handle_err(input: &mut I, h: H) -> Result + where + I: NestedDecodeInput, + H: DecodeErrorHandler, + { + Result::Ok(ManagedDecimalSigned::const_decimals_from_raw( + as NestedDecode>::dep_decode_or_handle_err(input, h)?, + )) + } +} + +impl NestedEncode for ManagedDecimalSigned { + fn dep_encode_or_handle_err(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr> + where + O: NestedEncodeOutput, + H: EncodeErrorHandler, + { + NestedEncode::dep_encode_or_handle_err(&self.data, dest, h)?; + NestedEncode::dep_encode_or_handle_err(&self.decimals, dest, h)?; + + Result::Ok(()) + } +} + +impl TopEncode for ManagedDecimalSigned { + 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 dest = &mut buffer; + NestedEncode::dep_encode_or_handle_err(&self.data, dest, h)?; + NestedEncode::dep_encode_or_handle_err(&self.decimals, dest, h)?; + + output.finalize_nested_encode(buffer); + Result::Ok(()) + } +} + +impl NestedDecode for ManagedDecimalSigned { + fn dep_decode_or_handle_err(input: &mut I, h: H) -> Result + where + I: NestedDecodeInput, + H: DecodeErrorHandler, + { + Result::Ok(ManagedDecimalSigned::from_raw_units( + as NestedDecode>::dep_decode_or_handle_err(input, h)?, + ::dep_decode_or_handle_err(input, h)?, + )) + } +} + +impl TopDecode for ManagedDecimalSigned { + fn top_decode_or_handle_err(top_input: I, h: H) -> Result + where + I: TopDecodeInput, + H: DecodeErrorHandler, + { + let mut nested_buffer = top_input.into_nested_buffer(); + let result = ManagedDecimalSigned::from_raw_units( + as NestedDecode>::dep_decode_or_handle_err(&mut nested_buffer, h)?, + ::dep_decode_or_handle_err(&mut nested_buffer, h)?, + ); + if !NestedDecodeInput::is_depleted(&nested_buffer) { + return Result::Err(h.handle_error(DecodeError::INPUT_TOO_LONG)); + } + Result::Ok(result) + } +} + +impl TypeAbiFrom for ManagedDecimalSigned {} + +impl TypeAbi for ManagedDecimalSigned { + type Unmanaged = Self; + + fn type_name() -> TypeName { + TypeName::from("ManagedDecimalSigned") + } + + fn is_variadic() -> bool { + false + } +} + +impl TypeAbiFrom + for ManagedDecimalSigned> +{ +} + +impl TypeAbi + for ManagedDecimalSigned> +{ + type Unmanaged = Self; + + fn type_name() -> TypeName { + TypeName::from(alloc::format!("ManagedDecimalSigned<{}>", DECIMALS)) + } + + fn type_name_rust() -> TypeName { + TypeName::from(alloc::format!( + "ManagedDecimalSigned<$API, ConstDecimals<{}>>", + DECIMALS + )) + } + + fn is_variadic() -> bool { + false + } +} + +pub(super) fn managed_decimal_fmt( + value: &BigInt, + num_dec: NumDecimals, + f: &mut F, +) { + let full_str_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); + M::managed_type_impl().bi_to_string(value.handle.clone(), full_str_handle.clone()); + let len = M::managed_type_impl().mb_len(full_str_handle.clone()); + + if len > num_dec { + let temp_str_handle: M::ManagedBufferHandle = + use_raw_handle(const_handles::MBUF_TEMPORARY_2); + let _ = M::managed_type_impl().mb_copy_slice( + full_str_handle.clone(), + 0, + len - num_dec, + temp_str_handle.clone(), + ); + f.append_managed_buffer(&ManagedBuffer::from_raw_handle( + temp_str_handle.get_raw_handle(), + )); + f.append_bytes(b"."); + let _ = M::managed_type_impl().mb_copy_slice( + full_str_handle.clone(), + len - num_dec, + num_dec, + temp_str_handle.clone(), + ); + f.append_managed_buffer(&ManagedBuffer::from_raw_handle( + temp_str_handle.get_raw_handle(), + )); + } else { + f.append_bytes(b"0."); + for _ in len..num_dec { + f.append_bytes(b"0"); + } + f.append_managed_buffer(&ManagedBuffer::from_raw_handle( + full_str_handle.get_raw_handle(), + )); + } +} + +impl SCDisplay for ManagedDecimalSigned { + fn fmt(&self, f: &mut F) { + managed_decimal_fmt(&self.data, self.decimals.num_decimals(), f); + } +} + +impl core::fmt::Display for ManagedDecimalSigned { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut result = ManagedBufferCachedBuilder::::new_from_slice(&[]); + result.append_display(self); + core::fmt::Display::fmt(&result.into_managed_buffer(), f) + } +} + +impl core::fmt::Debug for ManagedDecimalSigned { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("ManagedDecimalSigned") + .field("handle", &self.data.handle.clone()) + .field("number", &self.to_string()) + .finish() + } +} diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index 64766f43db..eb17ae81e4 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,48 @@ 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 { + TypeName::from(alloc::format!( + "ManagedOption<$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_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 12bbb94034..e37dd872d5 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -1,5 +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, @@ -11,10 +12,15 @@ use crate::{ ManagedVecRefIterator, MultiValueEncoded, MultiValueManagedVec, }, }; -use alloc::vec::Vec; -use core::{borrow::Borrow, cmp::Ordering, fmt::Debug, iter::FromIterator, marker::PhantomData}; - -use super::EncodedManagedVecItem; +use alloc::{format, vec::Vec}; +use core::{ + borrow::Borrow, + cmp::Ordering, + fmt::Debug, + iter::FromIterator, + marker::PhantomData, + mem::{transmute_copy, ManuallyDrop, MaybeUninit}, +}; pub(crate) const INDEX_OUT_OF_RANGE_MSG: &[u8] = b"ManagedVec index out of range"; @@ -117,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] @@ -126,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| { @@ -147,12 +153,14 @@ where return None; } - let mut result_uninit = core::mem::MaybeUninit::>::uninit_array(); + let mut result_uninit = + unsafe { MaybeUninit::<[MaybeUninit>; N]>::uninit().assume_init() }; + for (index, value) in self.iter().enumerate() { result_uninit[index].write(value); } - let result = unsafe { core::mem::MaybeUninit::array_assume_init(result_uninit) }; + let result = unsafe { transmute_copy(&ManuallyDrop::new(result_uninit)) }; Some(result) } @@ -170,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); @@ -183,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) } @@ -229,6 +237,12 @@ where self.buffer.append(&part_after.buffer); } + pub fn take(&mut self, index: usize) -> T { + let item = unsafe { self.get_unsafe(index) }; + self.remove(index); + item + } + /// New `ManagedVec` instance with 1 element in it. pub fn from_single_item(item: T) -> Self { let mut result = ManagedVec::new(); @@ -300,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) }) @@ -312,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) }); } @@ -343,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| { @@ -384,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 @@ -397,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())); @@ -409,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())); @@ -418,24 +424,29 @@ where } pub fn is_sorted(&self) -> bool { - self.with_self_as_slice(|slice| slice.is_sorted()) - } - - pub fn is_sorted_by(&self, mut compare: F) -> bool - where - F: FnMut(&T, &T) -> Option, - { self.with_self_as_slice(|slice| { - slice.is_sorted_by(|a, b| compare(&a.decode(), &b.decode())) - }) - } + let mut slice_iter = slice.iter(); + #[inline] + fn check<'a, T>( + last: &'a mut T, + mut compare: impl FnMut(&T, &T) -> Option + 'a, + ) -> impl FnMut(T) -> bool + 'a { + move |curr| { + if let Some(Ordering::Greater) | None = compare(last, &curr) { + return false; + } + *last = curr; + true + } + } - pub fn is_sorted_by_key(&self, mut f: F) -> bool - where - F: FnMut(&T) -> K, - K: Ord, - { - self.with_self_as_slice(|slice| slice.is_sorted_by_key(|a| f(&a.decode()))) + let mut last = match slice_iter.next() { + Some(e) => e, + None => return true, + }; + + slice_iter.all(check(&mut last, PartialOrd::partial_cmp)) + }) } } @@ -444,12 +455,34 @@ 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 (dedup, _) = slice.partition_dedup(); + let same_bucket = |a, b| a == b; + let len = slice.len(); + if len <= 1 { + return slice; + } + + let ptr = slice.as_mut_ptr(); + let mut next_read: usize = 1; + let mut next_write: usize = 1; + unsafe { + // Avoid bounds checks by using raw pointers. + while next_read < len { + let ptr_read = ptr.add(next_read); + let prev_ptr_write = ptr.add(next_write - 1); + if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) { + if next_read != next_write { + let ptr_write = prev_ptr_write.add(1); + core::ptr::swap(ptr_read, ptr_write); + } + next_write += 1; + } + next_read += 1; + } + } + + let (dedup, _) = slice.split_at_mut(next_write); dedup }) } @@ -495,7 +528,7 @@ where if self_item != other_item { return false; } - byte_index += T::PAYLOAD_SIZE; + byte_index += T::payload_size(); } true } @@ -634,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..9f21a13de4 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 @@ -29,9 +31,14 @@ pub trait ManagedVecItem: 'static { /// - For items with Copy semantics, it should be the type itself. /// - For managed types, ManagedRef does the job. /// - For any other types, `Self` is currently used, although this is technically unsafe. + /// /// 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 +57,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 +86,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 +109,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 +133,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 +160,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 +209,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 +233,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 8ac485fa38..1874dc48b0 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -1,3 +1,7 @@ +mod big_uint; +mod big_uint_cmp; +mod big_uint_operators; +mod builder; mod egld_or_esdt_token_identifier; mod egld_or_esdt_token_payment; mod egld_or_multi_esdt_payment; @@ -5,35 +9,51 @@ mod encoded_managed_vec_item; mod esdt_token_data; mod esdt_token_payment; mod managed_address; -mod managed_buffer_cached_builder; +mod managed_buffer_read_to_end; mod managed_byte_array; +mod managed_decimal; 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 big_uint::BigUint; +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 use managed_buffer_read_to_end::*; pub(crate) use managed_byte_array::ManagedBufferSizeContext; pub use managed_byte_array::ManagedByteArray; +pub use managed_decimal::{ + ConstDecimals, Decimals, ManagedDecimal, ManagedDecimalSigned, NumDecimals, +}; 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 329b3f2b3d..1e66615199 100644 --- a/framework/base/src/types/managed/wrapped/token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/token_identifier.rs @@ -1,5 +1,7 @@ +use alloc::string::ToString; + use crate::{ - abi::{TypeAbi, TypeName}, + abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ErrorApi, ErrorApiImpl, HandleConstraints, ManagedTypeApi, ManagedTypeApiImpl}, codec::*, err_msg, @@ -69,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()) + }) } } @@ -96,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 { @@ -109,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, ) } } @@ -161,16 +170,22 @@ impl TopDecode for TokenIdentifier { } } -impl CodecFromSelf for TokenIdentifier where M: ManagedTypeApi {} - -impl CodecFrom<&[u8]> for TokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom<&[u8]> for TokenIdentifier where M: ManagedTypeApi {} +impl TypeAbiFrom> 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 { @@ -199,7 +214,6 @@ impl core::fmt::Display for TokenIdentifier { impl core::fmt::Debug for TokenIdentifier { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - use crate::alloc::string::ToString; f.debug_tuple("TokenIdentifier") .field(&self.to_string()) .finish() 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/math_util.rs b/framework/base/src/types/math_util.rs new file mode 100644 index 0000000000..9322ee93ac --- /dev/null +++ b/framework/base/src/types/math_util.rs @@ -0,0 +1 @@ +pub mod logarithm_i64; diff --git a/framework/base/src/types/math_util/logarithm_i64.rs b/framework/base/src/types/math_util/logarithm_i64.rs new file mode 100644 index 0000000000..240e3b310d --- /dev/null +++ b/framework/base/src/types/math_util/logarithm_i64.rs @@ -0,0 +1,72 @@ +const DENOMINATOR: i64 = 1_000_000_000; + +const LN_OF_2_SCALE_9: I64Decimal9 = 693147180; // 0.69314718 +const LN_OF_10_SCALE_9: I64Decimal9 = 2302585093; // 2.3025850929940456840... +const LOG2_OF_10_SCALE_9: I64Decimal9 = 3321928095; // 3.3219280948873623478... + +/// Indicates that a number is interpreted as a decimal number with 9 decimals. +pub type I64Decimal9 = i64; + +/// Approximates the logarithm between 1 and 2 with a polynomial. +/// +/// The polynomial is: `-1.7417939 + x * (2.8212026 + (-1.4699568 + (0.44717955 - 0.056570851 * x) * x) * x)` +pub fn ln_polynomial(x: I64Decimal9) -> I64Decimal9 { + // x normalized to [1.0, 2.0] + debug_assert!(x >= DENOMINATOR); + debug_assert!(x <= 2 * DENOMINATOR); + + let mut result: i64 = -56570851; // -0.056570851 + result *= x; + result /= DENOMINATOR; + result += 447179550; // 0.44717955 + result *= x; + result /= DENOMINATOR; + result += -1469956800; // -1.4699568 + result *= x; + result /= DENOMINATOR; + result += 2821202600; // 2.8212026 + result *= x; + result /= DENOMINATOR; + result += -1741793900; // -1.7417939 + + result +} + +/// Just took the coeficients from ln and dividem them all by ln(2). +pub fn log2_polynomial(x: I64Decimal9) -> I64Decimal9 { + // x normalized to [1.0, 2.0] + debug_assert!(x >= DENOMINATOR); + debug_assert!(x <= 2 * DENOMINATOR); + + let mut result: i64 = -81614486; // -0.08161448626 + result *= x; + result /= DENOMINATOR; + result += 645143719; // 0.645143719 + result *= x; + result /= DENOMINATOR; + result += -2120699387; // -2.120699387 + result *= x; + result /= DENOMINATOR; + result += 4070135003; // 4.070135003 + result *= x; + result /= DENOMINATOR; + result += -2512877423; // -2.512877423 + + result +} + +pub fn ln_add_bit_log2(result: &mut I64Decimal9, bit_log2: u32) { + *result += bit_log2 as i64 * LN_OF_2_SCALE_9; +} + +pub fn log2_add_bit_log2(result: &mut I64Decimal9, bit_log2: u32) { + *result += bit_log2 as i64 * DENOMINATOR; +} + +pub fn ln_sub_decimals(result: &mut I64Decimal9, num_decimals: usize) { + *result -= num_decimals as i64 * LN_OF_10_SCALE_9; +} + +pub fn log2_sub_decimals(result: &mut I64Decimal9, num_decimals: usize) { + *result -= num_decimals as i64 * LOG2_OF_10_SCALE_9; +} 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 aa9b4c8c5a..f33cc53196 100644 --- a/framework/derive/Cargo.toml +++ b/framework/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-derive" -version = "0.44.0" +version = "0.53.0" edition = "2021" authors = ["Andrei Marinica ", "MultiversX "] @@ -14,11 +14,11 @@ keywords = ["multiversx", "blockchain", "contract"] categories = ["cryptography::cryptocurrencies", "development-tools::procedural-macro-helpers"] [dependencies] -proc-macro2 = "1.0.66" -quote = "1.0.33" -syn = "1.0" -hex = "0.4" -radix_trie = "0.2.1" +proc-macro2 = "=1.0.86" +quote = "=1.0.37" +syn = "=2.0.77" +hex = "=0.4.3" +radix_trie = "=0.2.1" [features] default = ["syn/full", "syn/parsing", "syn/extra-traits"] 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/managed_decimal_macro.rs b/framework/derive/src/format/managed_decimal_macro.rs new file mode 100644 index 0000000000..c65adf56d5 --- /dev/null +++ b/framework/derive/src/format/managed_decimal_macro.rs @@ -0,0 +1,11 @@ +pub fn extract_number_data(input: syn::LitStr) -> (u64, usize) { + let value_str = input.value(); + + let parts: Vec<&str> = value_str.split('.').collect(); + let raw_val = parts.join(""); + let raw_int = raw_val.parse::().expect("Invalid integer value"); + + let decimals = if parts.len() > 1 { parts[1].len() } else { 0 }; + + (raw_int, decimals) +} diff --git a/framework/derive/src/format/mod.rs b/framework/derive/src/format/mod.rs index f5d942704d..555c0c356e 100644 --- a/framework/derive/src/format/mod.rs +++ b/framework/derive/src/format/mod.rs @@ -1,6 +1,10 @@ mod format_args_macro; mod format_parts; mod format_tokenize; +mod managed_decimal_macro; +mod semver_tuple; pub use format_args_macro::*; pub use format_parts::*; +pub use managed_decimal_macro::*; +pub use semver_tuple::*; diff --git a/framework/derive/src/format/semver_tuple.rs b/framework/derive/src/format/semver_tuple.rs new file mode 100644 index 0000000000..f10036a973 --- /dev/null +++ b/framework/derive/src/format/semver_tuple.rs @@ -0,0 +1,38 @@ +use quote::quote; + +use crate::format::format_tokenize; + +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_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.rs b/framework/derive/src/generate/auto_impl.rs index 628a7af0e1..1d76e50e28 100644 --- a/framework/derive/src/generate/auto_impl.rs +++ b/framework/derive/src/generate/auto_impl.rs @@ -4,8 +4,8 @@ use super::{ auto_impl_event::generate_event_impl, auto_impl_proxy::generate_proxy_getter_impl, auto_impl_storage::{ - generate_clear_impl, generate_getter_impl, generate_is_empty_impl, generate_mapper_impl, - generate_setter_impl, + generate_clear_impl, generate_getter_impl, generate_is_empty_impl, + generate_mapper_from_address_impl, generate_mapper_impl, generate_setter_impl, }, }; @@ -33,6 +33,9 @@ fn generate_auto_impl(m: &Method, auto_impl: &AutoImpl) -> proc_macro2::TokenStr AutoImpl::StorageGetter { identifier } => generate_getter_impl(m, identifier), AutoImpl::StorageSetter { identifier } => generate_setter_impl(m, identifier), AutoImpl::StorageMapper { identifier } => generate_mapper_impl(m, identifier), + AutoImpl::StorageMapperFromAddress { identifier } => { + generate_mapper_from_address_impl(m, identifier) + }, AutoImpl::StorageIsEmpty { identifier } => generate_is_empty_impl(m, identifier), AutoImpl::StorageClear { identifier } => generate_clear_impl(m, identifier), AutoImpl::ProxyGetter => generate_proxy_getter_impl(m), diff --git a/framework/derive/src/generate/auto_impl_proxy.rs b/framework/derive/src/generate/auto_impl_proxy.rs index a60c97832d..33c36724ca 100644 --- a/framework/derive/src/generate/auto_impl_proxy.rs +++ b/framework/derive/src/generate/auto_impl_proxy.rs @@ -3,10 +3,11 @@ use crate::{ model::{AutoImpl, ContractTrait, Method, MethodImpl}, parse::split_path_last, }; -use syn::{punctuated::Punctuated, token::Colon2}; +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; +pub type ProxyModulePath = Punctuated; pub struct ProxyGetterReturnType { pub module_path: ProxyModulePath, @@ -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/auto_impl_storage.rs b/framework/derive/src/generate/auto_impl_storage.rs index 94e7affa23..bb0c83d699 100644 --- a/framework/derive/src/generate/auto_impl_storage.rs +++ b/framework/derive/src/generate/auto_impl_storage.rs @@ -82,6 +82,31 @@ pub fn generate_mapper_impl(m: &Method, identifier: &str) -> proc_macro2::TokenS } } +pub fn generate_mapper_from_address_impl(m: &Method, identifier: &str) -> proc_macro2::TokenStream { + let msig = method_gen::generate_sig_with_attributes(m); + assert!( + !m.method_args.is_empty(), + "mapper from address must have at least one argument, for the value" + ); + let address_arg = &m.method_args[0]; + let address_pat = address_arg.pat.to_owned(); + let key_snippet = generate_key_snippet(&m.method_args[1..], identifier); + match m.return_type.clone() { + syn::ReturnType::Default => panic!("getter from address should return some value"), + syn::ReturnType::Type(_, ty) => { + quote! { + #msig { + #key_snippet + <#ty as multiversx_sc::storage::mappers::StorageMapperFromAddress>::new_from_address( + #address_pat, + ___key___ + ) + } + } + }, + } +} + pub fn generate_is_empty_impl(m: &Method, identifier: &str) -> proc_macro2::TokenStream { let msig = method_gen::generate_sig_with_attributes(m); let key_snippet = generate_key_snippet(m.method_args.as_slice(), identifier); 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..4bba840a90 100644 --- a/framework/derive/src/generate/endpoints_mod_gen.rs +++ b/framework/derive/src/generate/endpoints_mod_gen.rs @@ -15,7 +15,7 @@ pub fn generate_endpoints_mod( let module_path = &supertrait.module_path; let endpoints_alias = generate_endpoints_mod_alias(index); quote! { - pub use #module_path endpoints as #endpoints_alias; + pub use #module_path __wasm__endpoints__ as #endpoints_alias; } }) .collect(); @@ -49,7 +49,7 @@ pub fn generate_endpoints_mod( #(#endpoint_aliases_decl)* #[allow(non_snake_case)] - pub mod endpoints { + pub mod __wasm__endpoints__ { use super::EndpointWrappers; #(#endpoint_aliases_use)* @@ -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 08c5b19cd1..515aa3fc7d 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,19 +46,78 @@ 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(input).into() +} - type_abi_derive::type_abi_derive(&ast) +#[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)] pub fn managed_vec_item_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let ast = syn::parse(input).unwrap(); - managed_vec_item_derive::managed_vec_item_derive(&ast) } #[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.into()).into() +} + +#[proc_macro] +pub fn const_managed_decimal(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as syn::LitStr); + let (raw_int, decimals) = format::extract_number_data(input); + + let expanded = quote! { + multiversx_sc::types::ManagedDecimal::<::Api, multiversx_sc::types::ConstDecimals<#decimals>>::const_decimals_from_raw(multiversx_sc::types::BigUint::from(#raw_int)) + }; + + proc_macro::TokenStream::from(expanded) +} + +#[proc_macro] +pub fn managed_decimal(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as syn::LitStr); + let (raw_int, decimals) = format::extract_number_data(input); + + let expanded = quote! { + multiversx_sc::types::ManagedDecimal::<::Api, usize>::from_raw_units(multiversx_sc::types::BigUint::from(#raw_int), #decimals) + }; + + proc_macro::TokenStream::from(expanded) +} + +#[proc_macro] +pub fn debug_const_managed_decimal(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as syn::LitStr); + let (raw_int, decimals) = format::extract_number_data(input); + + let expanded = quote! { + multiversx_sc::types::ManagedDecimal::>::const_decimals_from_raw(multiversx_sc::types::BigUint::from(#raw_int)) + }; + + proc_macro::TokenStream::from(expanded) +} + +#[proc_macro] +pub fn debug_managed_decimal(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as syn::LitStr); + let (raw_int, decimals) = format::extract_number_data(input); + + let expanded = quote! { + multiversx_sc::types::ManagedDecimal::::from_raw_units(multiversx_sc::types::BigUint::from(#raw_int), #decimals) + }; + + proc_macro::TokenStream::from(expanded) } diff --git a/framework/derive/src/macro_contract.rs b/framework/derive/src/macro_contract.rs index 1333a4310b..06a3be7d03 100644 --- a/framework/derive/src/macro_contract.rs +++ b/framework/derive/src/macro_contract.rs @@ -8,10 +8,10 @@ pub fn process_contract( input: proc_macro::TokenStream, ) -> proc_macro::TokenStream { let new_input = trait_preprocessing(input); - let args_input = parse_macro_input!(args as syn::AttributeArgs); - let proc_input = &parse_macro_input!(new_input as syn::ItemTrait); + let proc_input = parse_macro_input!(new_input as syn::ItemTrait); + + let contract = parse_contract_trait(args, &proc_input); - let contract = parse_contract_trait(args_input, proc_input); validate_contract(&contract); let contract_impl = contract_implementation(&contract, true); diff --git a/framework/derive/src/macro_module.rs b/framework/derive/src/macro_module.rs index 9c696e2387..68ea095f0a 100644 --- a/framework/derive/src/macro_module.rs +++ b/framework/derive/src/macro_module.rs @@ -8,10 +8,9 @@ pub fn process_module( input: proc_macro::TokenStream, ) -> proc_macro::TokenStream { let new_input = trait_preprocessing(input); - let args_input = parse_macro_input!(args as syn::AttributeArgs); let proc_input = &parse_macro_input!(new_input as syn::ItemTrait); - let contract = parse_contract_trait(args_input, proc_input); + let contract = parse_contract_trait(args, proc_input); validate_contract(&contract); let contract_impl = contract_implementation(&contract, false); diff --git a/framework/derive/src/macro_proxy.rs b/framework/derive/src/macro_proxy.rs index 9612167bc6..d88f3116fc 100644 --- a/framework/derive/src/macro_proxy.rs +++ b/framework/derive/src/macro_proxy.rs @@ -11,10 +11,9 @@ pub fn process_proxy( input: proc_macro::TokenStream, ) -> proc_macro::TokenStream { let new_input = trait_preprocessing(input); - let args_input = parse_macro_input!(args as syn::AttributeArgs); let proc_input = parse_macro_input!(new_input as syn::ItemTrait); - let contract = parse_contract_trait(args_input, &proc_input); + let contract = parse_contract_trait(args, &proc_input); validate_contract(&contract); let proxy_impl = proxy_implementation(&contract, true); 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..22acf8eb78 100644 --- a/framework/derive/src/model/method.rs +++ b/framework/derive/src/model/method.rs @@ -7,6 +7,7 @@ pub enum AutoImpl { StorageGetter { identifier: String }, StorageSetter { identifier: String }, StorageMapper { identifier: String }, + StorageMapperFromAddress { identifier: String }, StorageIsEmpty { identifier: String }, StorageClear { identifier: String }, ProxyGetter, @@ -77,6 +78,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 +90,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 +102,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 34a413a9b1..e5aad040c4 100644 --- a/framework/derive/src/model/supertrait.rs +++ b/framework/derive/src/model/supertrait.rs @@ -1,11 +1,12 @@ -use syn::{punctuated::Punctuated, token::Colon2}; +use syn::{punctuated::Punctuated, token::PathSep}; /// Path to a Rust module containing a contract module. -pub type ModulePath = Punctuated; +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/argument_parse.rs b/framework/derive/src/parse/argument_parse.rs index 9e18e94040..b3bd37912c 100644 --- a/framework/derive/src/parse/argument_parse.rs +++ b/framework/derive/src/parse/argument_parse.rs @@ -1,7 +1,7 @@ use super::attributes::*; use crate::model::{ArgMetadata, ArgPaymentMetadata, MethodArgument}; -pub fn extract_method_args(m: &syn::TraitItemMethod) -> Vec { +pub fn extract_method_args(m: &syn::TraitItemFn) -> Vec { if m.sig.inputs.is_empty() { missing_self_panic(m); } @@ -29,7 +29,7 @@ pub fn extract_method_args(m: &syn::TraitItemMethod) -> Vec { .collect() } -fn missing_self_panic(m: &syn::TraitItemMethod) -> ! { +fn missing_self_panic(m: &syn::TraitItemFn) -> ! { panic!( "Trait method `{}` must have `&self` as its first argument.", m.sig.ident diff --git a/framework/derive/src/parse/attributes/attr_names.rs b/framework/derive/src/parse/attributes/attr_names.rs index 0b9bcf9c3c..29784fc1c3 100644 --- a/framework/derive/src/parse/attributes/attr_names.rs +++ b/framework/derive/src/parse/attributes/attr_names.rs @@ -21,8 +21,10 @@ pub(super) static ATTR_CALLBACK_CALL_RESULT: &str = "call_result"; pub(super) static ATTR_STORAGE_GET: &str = "storage_get"; pub(super) static ATTR_STORAGE_SET: &str = "storage_set"; pub(super) static ATTR_STORAGE_MAPPER: &str = "storage_mapper"; +pub(super) static ATTR_STORAGE_MAPPER_FROM_ADDRESS: &str = "storage_mapper_from_address"; pub(super) static ATTR_STORAGE_IS_EMPTY: &str = "storage_is_empty"; pub(super) static ATTR_STORAGE_CLEAR: &str = "storage_clear"; pub(super) static ATTR_PROXY: &str = "proxy"; pub(super) static ATTR_LABEL: &str = "label"; pub(super) static ATTR_ALLOW_MULTIPLE_VAR_ARGS: &str = "allow_multiple_var_args"; +pub(super) static ATTR_UPGRADE: &str = "upgrade"; diff --git a/framework/derive/src/parse/attributes/doc_attr.rs b/framework/derive/src/parse/attributes/doc_attr.rs index 57c7fcdd2d..5c5ed4d41b 100644 --- a/framework/derive/src/parse/attributes/doc_attr.rs +++ b/framework/derive/src/parse/attributes/doc_attr.rs @@ -1,3 +1,5 @@ +use quote::ToTokens; + use super::{attr_names::*, util::*}; /// unlike the others, this is standard Rust, @@ -10,45 +12,62 @@ pub fn extract_doc(attrs: &[syn::Attribute]) -> Vec { attrs .iter() .filter(|attr| { - if let Some(first_seg) = attr.path.segments.first() { + if let Some(first_seg) = attr.path().segments.first() { first_seg.ident == ATTR_DOC } else { false } }) - .map(|attr| { - let mut tokens_iter = attr.clone().tokens.into_iter(); - - // checking punctuation, the first token is '=' - if let Some(proc_macro2::TokenTree::Punct(punct)) = tokens_iter.next() { - assert_eq!(punct.as_char(), '='); - } else { - panic!("malformed doc attribute"); - } - - if let Some(proc_macro2::TokenTree::Literal(lit)) = tokens_iter.next() { - let lit_str = lit.to_string(); - let mut message_slice = lit_str.as_str(); + .map(|attr| match attr.meta.clone() { + syn::Meta::Path(_) => panic!("wrong format. expected name value, received path"), + syn::Meta::List(_) => panic!("wrong format. expected name value, received list"), + syn::Meta::NameValue(meta_name_value) => { + if let syn::Expr::Lit(lit_str) = meta_name_value.value { + if meta_name_value.path.is_ident("doc") { + let value = lit_str.lit; + if let Some(tuple) = value + .to_token_stream() + .to_string() + .split_once(char::is_whitespace) + { + remove_backslashes(tuple.1) + } else { + String::new() + } + } else { + panic!("Attribute doesn't have the 'doc' identifier"); + } + } else { + panic!("Value is not a string literal"); + } + }, + }) + .collect() +} - // the useful part of the message is between quotes - assert!( - message_slice.starts_with('\"') && message_slice.ends_with('\"'), - "malformed doc attribute: string literal expected" - ); - message_slice = &message_slice[1..message_slice.len() - 1]; +pub fn extract_macro_attributes(attrs: &[syn::Attribute]) -> Vec { + let mut macro_attributes = Vec::new(); - // most doc comments start with a space, so remove that too - if message_slice.starts_with(' ') { - message_slice = &message_slice[1..]; + 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()); + } } - - // also unescape escaped single and double quotes - message_slice.replace("\\\"", "\"").replace("\\'", "'") - } else { - panic!("malformed doc attribute"); } - }) - .collect() + } + } + + macro_attributes +} + +fn remove_backslashes(input: &str) -> String { + input + .trim_matches('\"') + .replace("\\\"", "\"") + .replace("\\'", "'") } pub struct OutputNameAttribute { diff --git a/framework/derive/src/parse/attributes/endpoint_attr.rs b/framework/derive/src/parse/attributes/endpoint_attr.rs index 0e8f7b6840..678675b202 100644 --- a/framework/derive/src/parse/attributes/endpoint_attr.rs +++ b/framework/derive/src/parse/attributes/endpoint_attr.rs @@ -28,6 +28,10 @@ pub fn is_allow_multiple_var_args(attr: &syn::Attribute) -> bool { is_attribute_with_no_args(attr, ATTR_ALLOW_MULTIPLE_VAR_ARGS) } +pub fn is_upgrade(attr: &syn::Attribute) -> bool { + is_attribute_with_no_args(attr, ATTR_UPGRADE) +} + #[derive(Clone, Debug)] pub struct EndpointAttribute { pub endpoint_name: Option, 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/attributes/payable_attr.rs b/framework/derive/src/parse/attributes/payable_attr.rs index 0c84bfbca4..73293719d0 100644 --- a/framework/derive/src/parse/attributes/payable_attr.rs +++ b/framework/derive/src/parse/attributes/payable_attr.rs @@ -1,3 +1,5 @@ +use crate::parse::attributes::util::{clean_string, is_first_char_numeric}; + use super::attr_names::*; pub struct PayableAttribute { @@ -6,7 +8,7 @@ pub struct PayableAttribute { impl PayableAttribute { pub fn parse(attr: &syn::Attribute) -> Option { - if let Some(first_seg) = attr.path.segments.first() { + if let Some(first_seg) = attr.path().segments.first() { if first_seg.ident == ATTR_PAYABLE { Some(PayableAttribute { identifier: extract_token_identifier(attr), @@ -23,35 +25,45 @@ impl PayableAttribute { /// Current implementation only works with 1 token name. /// Might be extended in the future. fn extract_token_identifier(attr: &syn::Attribute) -> Option { - let mut iter = attr.clone().tokens.into_iter(); - let result_str = match iter.next() { - Some(proc_macro2::TokenTree::Group(group)) => { - assert!( - group.delimiter() == proc_macro2::Delimiter::Parenthesis, - "payable token name must be specified in parantheses" - ); - let mut iter2 = group.stream().into_iter(); - match iter2.next() { - Some(proc_macro2::TokenTree::Literal(lit)) => { - let str_val = lit.to_string(); + match attr.meta.clone() { + syn::Meta::Path(_) => { + panic!("attribute needs 1 string argument: Replace with #[payable(\"*\")] or #[payable(\"EGLD\")]") + }, + syn::Meta::List(list) => { + let mut iter = list.tokens.into_iter(); + let ticker = match iter.next() { + Some(proc_macro2::TokenTree::Literal(literal)) => { + let clean = clean_string(literal.to_string()); assert!( - str_val.starts_with('\"') && str_val.ends_with('\"'), - "string literal expected as attribute argument" + !clean.is_empty(), + "ticker can not be empty. attribute needs 1 string argument: Replace with #[payable(\"*\")] or #[payable(\"EGLD\")" ); - let substr = &str_val[1..str_val.len() - 1]; - Some(substr.to_string()) - }, - _ => panic!("literal expected as event identifier"), - } - }, - None => None, - _ => panic!("unexpected payable attribute format"), - }; - assert!( - iter.next().is_none(), - "event too many tokens in event attribute" - ); + assert!(!is_first_char_numeric(&clean), "argument can not be a number"); - result_str + if clean + .chars() + .next() + .is_some_and(|s| + s == '*' + ) { + assert!(clean.len() == 1usize, "attribute needs 1 string argument: \"*\", \"EGLD\" or token identifier"); + } + + clean + }, + Some(_) => panic!("expected a string as argument"), + None => panic!("argument can not be empty. attribute needs 1 string argument: Replace with #[payable(\"*\")] or #[payable(\"EGLD\")"), + }; + + assert!( + iter.next().is_none(), + "too many tokens in attribute argument" + ); + Some(ticker) + }, + syn::Meta::NameValue(_) => panic!( + "attribute can not be name value. attribute needs 1 string argument: \"*\" or \"EGLD\"" + ), + } } diff --git a/framework/derive/src/parse/attributes/storage_attr.rs b/framework/derive/src/parse/attributes/storage_attr.rs index 8a3e0d22c7..eebca83916 100644 --- a/framework/derive/src/parse/attributes/storage_attr.rs +++ b/framework/derive/src/parse/attributes/storage_attr.rs @@ -36,6 +36,20 @@ impl StorageMapperAttribute { } } +pub struct StorageMapperFromAddressAttribute { + pub identifier: String, +} + +impl StorageMapperFromAddressAttribute { + pub fn parse(attr: &syn::Attribute) -> Option { + is_attr_one_string_arg(attr, ATTR_STORAGE_MAPPER_FROM_ADDRESS).map(|arg_str| { + StorageMapperFromAddressAttribute { + identifier: arg_str, + } + }) + } +} + pub struct StorageIsEmptyAttribute { pub identifier: String, } diff --git a/framework/derive/src/parse/attributes/util.rs b/framework/derive/src/parse/attributes/util.rs index f10865717f..4b38ea6cf4 100644 --- a/framework/derive/src/parse/attributes/util.rs +++ b/framework/derive/src/parse/attributes/util.rs @@ -1,11 +1,10 @@ use crate::model::EsdtAttribute; -use proc_macro2::TokenTree; pub(super) fn is_attribute_with_no_args(attr: &syn::Attribute, name: &str) -> bool { - if let Some(first_seg) = attr.path.segments.first() { + if let Some(first_seg) = attr.path().segments.first() { if first_seg.ident == name { assert!( - attr.path.segments.len() == 1, + attr.meta.require_path_only().is_ok(), "no arguments allowed for attribute `{name}`" ); return true; @@ -19,51 +18,56 @@ pub(super) fn get_attribute_with_one_type_arg( attr: &syn::Attribute, name: &str, ) -> Option { - let attr_path = &attr.path; + let attr_path = &attr.path(); if let Some(first_seg) = attr_path.segments.first() { if first_seg.ident == name { - let mut tokens = attr.tokens.clone().into_iter(); - let group = match tokens.next() { - Some(TokenTree::Group(group_val)) => group_val, - _ => panic!("Expected a group as attribute argument"), - }; - - let mut iter = group.stream().into_iter(); - - let first_literal = match iter.next() { - Some(TokenTree::Literal(literal)) => literal.to_string(), - _ => panic!("Expected a literal as the first token in the attribute argument"), - }; - - let symbol = first_literal.trim_matches('\"').to_string(); - - let _ = match iter.next() { - Some(TokenTree::Punct(punct)) => punct, - _ => panic!("Expected a punctuation token after the literal"), + let (ticker, ty) = match attr.meta.clone() { + syn::Meta::Path(_) => { + panic!("attribute needs 2 arguments: ticker (string) and type") + }, + syn::Meta::List(list) => { + assert!(!list.tokens.is_empty(), "argument can not be empty. attribute needs 2 arguments: ticker (string) and type"); + + let mut iter = list.tokens.into_iter(); + + let first_literal = match iter.next() { + Some(proc_macro2::TokenTree::Literal(literal)) => literal.to_string(), + _ => { + panic!("expected a string as the first token in the attribute argument") + }, + }; + + let ticker = clean_string(first_literal); + + let _ = match iter.next() { + Some(proc_macro2::TokenTree::Punct(punct)) => punct, + _ => panic!("expected a punctuation token after the first literal"), + }; + + let mut ty = proc_macro2::TokenStream::new(); + + for token in &mut iter { + match token { + proc_macro2::TokenTree::Punct(punct) => { + ty.extend(quote! { #punct }); + }, + proc_macro2::TokenTree::Ident(ident) => { + ty.extend(quote! { #ident }); + }, + _ => break, + } + } + + if ticker.trim().is_empty() { + panic!("ticker field can't be empty"); + } + + (ticker, ty) + }, + syn::Meta::NameValue(_) => panic!("arguments can not be name value"), }; - let mut chosen_type = proc_macro2::TokenStream::new(); - - for token in &mut iter { - match token { - TokenTree::Punct(punct) => { - chosen_type.extend(quote! { #punct }); - }, - TokenTree::Ident(ident) => { - chosen_type.extend(quote! { #ident }); - }, - _ => break, - } - } - - if symbol.is_empty() { - panic!("Ticker field can't be empty"); - } - - let esdt_attribute = EsdtAttribute { - ticker: symbol, - ty: chosen_type, - }; + let esdt_attribute = EsdtAttribute { ticker, ty }; return Some(esdt_attribute); } @@ -73,41 +77,67 @@ pub(super) fn get_attribute_with_one_type_arg( } pub(super) fn attr_one_string_arg(attr: &syn::Attribute) -> String { - let result_str: String; - let mut iter = attr.clone().tokens.into_iter(); - match iter.next() { - Some(proc_macro2::TokenTree::Group(group)) => { + match attr.meta.clone() { + syn::Meta::Path(path) => { + let mut iter = path.segments.into_iter(); + match iter.next() { + Some(syn::PathSegment { + ident: _, + arguments: syn::PathArguments::None, + }) => String::new(), + Some(_) => panic!("unexpected attribute argument tokens"), + None => panic!("unexpected attribute argument tokens"), + } + }, + syn::Meta::List(list) => { assert!( - group.delimiter() == proc_macro2::Delimiter::Parenthesis, - "annotation paranthesis expected (check events and storage)" + list.delimiter == syn::MacroDelimiter::Paren(syn::token::Paren::default()), + "attribute paranthesis expected" ); - let mut iter2 = group.stream().into_iter(); - match iter2.next() { - Some(proc_macro2::TokenTree::Literal(lit)) => { - let str_val = lit.to_string(); + + assert!( + !list.tokens.is_empty(), + "attribute needs to have at least one argument" + ); + + let mut iter = list.tokens.into_iter(); + let arg_token_tree = match iter.next() { + Some(proc_macro2::TokenTree::Literal(literal)) => { + let clean = clean_string(literal.to_string()); + + assert!( + !is_first_char_numeric(&clean), + "argument can not be a number" + ); + + assert!( + !is_first_char_punctuation(&clean), + "argument can not start with punctuation" + ); + assert!( - str_val.starts_with('\"') && str_val.ends_with('\"'), - "string literal expected as attribute argument (check events and storage)" + !clean.is_empty(), + "the argument can not be an empty string or whitespace" ); - let substr = &str_val[1..str_val.len() - 1]; - result_str = substr.to_string(); + clean }, - _ => panic!("literal expected as annotation identifier (check events and storage)"), - } + Some(_) => { + panic!("unexpected attribute argument tokens: attribute has to be a string") + }, + None => panic!("attribute needs to have at least one argument"), + }; + + assert!(iter.next().is_none(), "too many tokens in attribute"); + arg_token_tree + }, + syn::Meta::NameValue(_) => { + panic!("unexpected attribute argument tokens: argument can not be name value") }, - _ => panic!("missing annotation identifier (check events and storage)"), } - - assert!( - iter.next().is_none(), - "too many tokens in attribute (check events and storage)" - ); - - result_str } pub(super) fn is_attr_one_string_arg(attr: &syn::Attribute, attr_name: &str) -> Option { - if let Some(first_seg) = attr.path.segments.first() { + if let Some(first_seg) = attr.path().segments.first() { if first_seg.ident == attr_name { Some(attr_one_string_arg(attr)) } else { @@ -119,26 +149,45 @@ pub(super) fn is_attr_one_string_arg(attr: &syn::Attribute, attr_name: &str) -> } fn attr_one_opt_token_tree_arg(attr: &syn::Attribute) -> Option { - let mut iter = attr.clone().tokens.into_iter(); - let arg_token_tree: Option = match iter.next() { - Some(proc_macro2::TokenTree::Group(group)) => { + match attr.clone().meta { + syn::Meta::Path(val) => { + let mut iter = val.segments.into_iter(); + let arg_token_tree: Option = match iter.next() { + Some(syn::PathSegment { + ident: _, + arguments: syn::PathArguments::None, + }) => None, + Some(_) => panic!("unexpected attribute argument tokens"), + None => None, + }; + + arg_token_tree + }, + syn::Meta::List(val) => { assert!( - group.delimiter() == proc_macro2::Delimiter::Parenthesis, + val.delimiter == syn::MacroDelimiter::Paren(syn::token::Paren::default()), "attribute paranthesis expected" ); - let mut iter2 = group.stream().into_iter(); - match iter2.next() { - Some(token_tree) => Some(token_tree), - _ => panic!("attribute argument expected"), - } - }, - Some(_) => panic!("unexpected attribute argument tokens"), - None => None, - }; - assert!(iter.next().is_none(), "too many tokens in attribute"); + assert!( + !val.tokens.is_empty(), + "attribute needs to have at least one argument" + ); - arg_token_tree + let mut iter = val.tokens.into_iter(); + let arg_token_tree: Option = match iter.next() { + Some(proc_macro2::TokenTree::Ident(ident)) => { + Some(proc_macro2::TokenTree::Ident(ident)) + }, + Some(_) => panic!("unexpected attribute argument tokens"), + None => None, + }; + + assert!(iter.next().is_none(), "too many tokens in attribute"); + arg_token_tree + }, + syn::Meta::NameValue(_) => panic!("unexpected attribute argument tokens"), + } } /// Finds a method attribute with given name and 1 single optional argument. @@ -147,7 +196,7 @@ pub(super) fn is_attr_with_one_opt_token_tree_arg( attr: &syn::Attribute, attr_name: &str, ) -> Option> { - if let Some(first_seg) = attr.path.segments.first() { + if let Some(first_seg) = attr.path().segments.first() { if first_seg.ident == attr_name { Some(attr_one_opt_token_tree_arg(attr)) } else { @@ -157,3 +206,15 @@ pub(super) fn is_attr_with_one_opt_token_tree_arg( None } } + +pub fn clean_string(s: String) -> String { + s.trim_matches('\"').trim_matches('"').trim().to_string() +} + +pub fn is_first_char_numeric(s: &str) -> bool { + s.chars().next().is_some_and(|s| s.is_numeric()) +} + +pub fn is_first_char_punctuation(s: &str) -> bool { + s.chars().next().is_some_and(|s| s.is_ascii_punctuation()) +} diff --git a/framework/derive/src/parse/auto_impl_parse.rs b/framework/derive/src/parse/auto_impl_parse.rs index 11553794cd..eb19cc83a3 100644 --- a/framework/derive/src/parse/auto_impl_parse.rs +++ b/framework/derive/src/parse/auto_impl_parse.rs @@ -4,17 +4,18 @@ 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_mapper_from_address]`, ", + "`#[storage_is_empty]`, ", + "`#[storage_clear]`, ", + "`#[proxy]`, ", + "`#[module]`, ", + "`#[event]`." + ) } pub fn process_event_attribute(attr: &syn::Attribute, method: &mut Method) -> bool { @@ -72,6 +73,20 @@ pub fn process_storage_mapper_attribute(attr: &syn::Attribute, method: &mut Meth .is_some() } +pub fn process_storage_mapper_from_address_attribute( + attr: &syn::Attribute, + method: &mut Method, +) -> bool { + StorageMapperFromAddressAttribute::parse(attr) + .map(|storage_mapper_from_address| { + assert_no_other_auto_impl(&*method); + method.implementation = MethodImpl::Generated(AutoImpl::StorageMapperFromAddress { + identifier: storage_mapper_from_address.identifier, + }); + }) + .is_some() +} + pub fn process_storage_is_empty_attribute(attr: &syn::Attribute, method: &mut Method) -> bool { StorageIsEmptyAttribute::parse(attr) .map(|storage_is_empty| { diff --git a/framework/derive/src/parse/contract_trait_parse.rs b/framework/derive/src/parse/contract_trait_parse.rs index 91c6f2c487..2600b21fb4 100644 --- a/framework/derive/src/parse/contract_trait_parse.rs +++ b/framework/derive/src/parse/contract_trait_parse.rs @@ -8,7 +8,7 @@ use crate::{ }; pub fn parse_contract_trait( - args: syn::AttributeArgs, + args: proc_macro::TokenStream, contract_trait: &syn::ItemTrait, ) -> ContractTrait { validate_attribute_args(args); @@ -34,7 +34,7 @@ pub fn parse_contract_trait( .items .iter() .map(|itm| match itm { - syn::TraitItem::Method(m) => process_method(m, &trait_attributes), + syn::TraitItem::Fn(m) => process_method(m, &trait_attributes), _ => panic!("Only methods allowed in contract traits"), }) .collect(); diff --git a/framework/derive/src/parse/endpoint_parse.rs b/framework/derive/src/parse/endpoint_parse.rs index 8c90f86717..5edc30ad08 100644 --- a/framework/derive/src/parse/endpoint_parse.rs +++ b/framework/derive/src/parse/endpoint_parse.rs @@ -6,16 +6,17 @@ use crate::model::{ use super::{ attributes::{ is_allow_multiple_var_args, is_callback_raw, is_init, is_only_admin, is_only_owner, - is_only_user_account, CallbackAttribute, EndpointAttribute, ExternalViewAttribute, - LabelAttribute, OutputNameAttribute, PromisesCallbackAttribute, ViewAttribute, + is_only_user_account, is_upgrade, CallbackAttribute, EndpointAttribute, + ExternalViewAttribute, LabelAttribute, OutputNameAttribute, PromisesCallbackAttribute, + ViewAttribute, }, MethodAttributesPass1, }; 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]`." - ); + "Can only annotate with one of the following arguments: `#[init]`, `#[endpoint]`, `#[view]`, `#[callback]`, `#[callback_raw]`, `#[upgrade]`." + ); } pub fn process_init_attribute( @@ -35,6 +36,24 @@ pub fn process_init_attribute( } } +pub fn process_upgrade_attribute( + attr: &syn::Attribute, + first_pass_data: &MethodAttributesPass1, + method: &mut Method, +) -> bool { + let has_attr = is_upgrade(attr); + if has_attr { + check_single_role(&*method); + method.public_role = PublicRole::Upgrade(InitMetadata { + payable: first_pass_data.payable.clone(), + allow_multiple_var_args: first_pass_data.allow_multiple_var_args, + }); + true + } else { + false + } +} + pub fn process_allow_multiple_var_args_attribute( attr: &syn::Attribute, pass_1_data: &mut MethodAttributesPass1, diff --git a/framework/derive/src/parse/method_parse.rs b/framework/derive/src/parse/method_parse.rs index 62eeed2470..481638068a 100644 --- a/framework/derive/src/parse/method_parse.rs +++ b/framework/derive/src/parse/method_parse.rs @@ -5,14 +5,15 @@ use super::{ auto_impl_parse::{ process_event_attribute, process_proxy_attribute, process_storage_clear_attribute, process_storage_get_attribute, process_storage_is_empty_attribute, - process_storage_mapper_attribute, process_storage_set_attribute, + process_storage_mapper_attribute, process_storage_mapper_from_address_attribute, + process_storage_set_attribute, }, extract_method_args, process_allow_multiple_var_args_attribute, process_callback_attribute, process_callback_raw_attribute, process_endpoint_attribute, process_external_view_attribute, process_init_attribute, process_label_names_attribute, process_only_admin_attribute, process_only_owner_attribute, process_only_user_account_attribute, process_output_names_attribute, process_payable_attribute, process_promises_callback_attribute, - process_view_attribute, + process_upgrade_attribute, process_view_attribute, }; pub struct MethodAttributesPass1 { pub method_name: String, @@ -23,7 +24,7 @@ pub struct MethodAttributesPass1 { pub allow_multiple_var_args: bool, } -pub fn process_method(m: &syn::TraitItemMethod, trait_attributes: &TraitProperties) -> Method { +pub fn process_method(m: &syn::TraitItemFn, trait_attributes: &TraitProperties) -> Method { let method_args = extract_method_args(m); let implementation = if let Some(body) = m.default.clone() { @@ -116,6 +117,7 @@ fn process_attribute_second_pass( ) -> bool { process_init_attribute(attr, first_pass_data, method) || process_endpoint_attribute(attr, first_pass_data, method) + || process_upgrade_attribute(attr, first_pass_data, method) || process_view_attribute(attr, first_pass_data, method) || process_external_view_attribute(attr, first_pass_data, method) || process_callback_raw_attribute(attr, method) @@ -126,6 +128,7 @@ fn process_attribute_second_pass( || process_storage_get_attribute(attr, method) || process_storage_set_attribute(attr, method) || process_storage_mapper_attribute(attr, method) + || process_storage_mapper_from_address_attribute(attr, method) || process_storage_is_empty_attribute(attr, method) || process_storage_clear_attribute(attr, method) || process_output_names_attribute(attr, method) @@ -136,8 +139,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/parse_util.rs b/framework/derive/src/parse/parse_util.rs index 45d834ac8a..ddc47c6c8f 100644 --- a/framework/derive/src/parse/parse_util.rs +++ b/framework/derive/src/parse/parse_util.rs @@ -1,4 +1,4 @@ -pub fn validate_attribute_args(args: syn::AttributeArgs) { +pub fn validate_attribute_args(args: proc_macro::TokenStream) { assert!( args.is_empty(), "No arguments expected in contract, module or proxy annotation." 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/parse/split_path.rs b/framework/derive/src/parse/split_path.rs index 23e7db26c3..f80c2c89f6 100644 --- a/framework/derive/src/parse/split_path.rs +++ b/framework/derive/src/parse/split_path.rs @@ -1,4 +1,4 @@ -use syn::{punctuated::Punctuated, token::Colon2}; +use syn::{punctuated::Punctuated, token::PathSep}; /// Splits off the last part of a path from the rest. /// e.g. `some::module::Item` will be split into `some::module::` and `Item`. @@ -7,7 +7,7 @@ use syn::{punctuated::Punctuated, token::Colon2}; /// The method is designed for contexts where explicit module specification is required. pub fn split_path_last( path: &syn::Path, -) -> Option<(Punctuated, syn::PathSegment)> { +) -> Option<(Punctuated, syn::PathSegment)> { if path.segments.len() >= 2 { let mut leading_segments = path.segments.clone(); let last_segment = leading_segments.pop().unwrap().into_value(); diff --git a/framework/derive/src/preprocessing/substitution_list.rs b/framework/derive/src/preprocessing/substitution_list.rs index 8084651a49..ec1b330239 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)); @@ -109,6 +109,7 @@ fn add_storage_mappers(substitutions: &mut SubstitutionsMap) { add_storage_mapper_single_generic_arg(substitutions, "e!(TokenAttributesMapper)); add_storage_mapper_single_generic_arg(substitutions, "e!(UniqueIdMapper)); add_storage_mapper_single_generic_arg(substitutions, "e!(UserMapper)); + add_storage_mapper_single_generic_arg(substitutions, "e!(AddressToIdMapper)); add_storage_mapper(substitutions, "e!(BiDiMapper)); add_storage_mapper(substitutions, "e!(LinkedListMapper)); diff --git a/framework/derive/src/type_abi_derive.rs b/framework/derive/src/type_abi_derive.rs index d64c932e22..8c70b56af8 100644 --- a/framework/derive/src/type_abi_derive.rs +++ b/framework/derive/src/type_abi_derive.rs @@ -1,7 +1,13 @@ +use crate::parse::attributes::extract_macro_attributes; + use super::parse::attributes::extract_doc; -use proc_macro::TokenStream; use quote::quote; +pub struct ExplicitDiscriminant { + pub variant_index: usize, + pub value: usize, +} + fn field_snippet(index: usize, field: &syn::Field) -> proc_macro2::TokenStream { let field_docs = extract_doc(field.attrs.as_slice()); let field_name_str = if let Some(ident) = &field.ident { @@ -14,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); } @@ -38,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),* ], ), ); } @@ -63,6 +73,7 @@ pub fn type_abi_derive(ast: &syn::DeriveInput) -> TokenStream { } }, syn::Data::Enum(data_enum) => { + let mut previous_disc: Vec = Vec::new(); let enum_variant_snippets: Vec = data_enum .variants .iter() @@ -71,13 +82,15 @@ pub fn type_abi_derive(ast: &syn::DeriveInput) -> TokenStream { let variant_docs = extract_doc(variant.attrs.as_slice()); let variant_name_str = variant.ident.to_string(); let variant_field_snippets = fields_snippets(&variant.fields); + let variant_discriminant = + get_discriminant(variant_index, variant, &mut previous_disc); quote! { let mut field_descriptions = multiversx_sc::types::heap::Vec::new(); #(#variant_field_snippets)* variant_descriptions.push(multiversx_sc::abi::EnumVariantDescription::new( &[ #(#variant_docs),* ], #variant_name_str, - #variant_index, + #variant_discriminant, field_descriptions, )); } @@ -85,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),* ], ), ); } @@ -108,14 +122,69 @@ 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 } + } +} + +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( + variant_index: usize, + variant: &syn::Variant, + previous_disc: &mut Vec, +) -> proc_macro2::TokenStream { + // if it has explicit discriminant + if let Some((_, syn::Expr::Lit(expr))) = &variant.discriminant { + let lit = match &expr.lit { + syn::Lit::Int(val) => { + let value = val.base10_parse().unwrap_or_else(|_| { + panic!("Can not unwrap int value from explicit discriminant") + }); + previous_disc.push(ExplicitDiscriminant { + variant_index, + value, + }); + value + }, + _ => panic!("Only integer values as discriminants"), // theoretically covered by the compiler + }; + return quote! { #lit}; + } + + // if no explicit discriminant, check previous discriminants + // get previous explicit + 1 if there has been any explicit before + let next_value = match previous_disc.last() { + // there are previous explicit discriminants + Some(ExplicitDiscriminant { + variant_index: prev_index, + value: prev_value, + }) if *prev_index < variant_index - 1 => prev_value + variant_index - prev_index, + Some(ExplicitDiscriminant { + variant_index: _, + value: prev_value, + }) => prev_value + 1, + + // vec is empty, return index + None => variant_index, }; - type_abi_impl.into() + + quote! { #next_value} } 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..8e9209fa9a --- /dev/null +++ b/framework/meta-lib/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "multiversx-sc-meta-lib" +version = "0.53.0" +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.216" +wasmprinter = "0.216" +semver = "1.0.20" + +[dependencies.multiversx-sc] +version = "=0.53.0" +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 86% rename from framework/meta/src/abi_json/contract_abi_json.rs rename to framework/meta-lib/src/abi_json/contract_abi_json.rs index 6bb5dfeecf..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, @@ -47,7 +51,11 @@ impl From<&ContractAbi> for ContractAbiJson { build_info: Some(BuildInfoAbiJson::from(&abi.build_info)), docs: abi.docs.iter().map(|d| d.to_string()).collect(), name: abi.name.to_string(), - constructor: abi.constructors.get(0).map(ConstructorAbiJson::from), + 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 89% rename from framework/meta/src/cargo_toml_contents.rs rename to framework/meta-lib/src/cargo_toml_contents.rs index a1faa076d9..ac6f851ba3 100644 --- a/framework/meta/src/cargo_toml_contents.rs +++ b/framework/meta-lib/src/cargo_toml_contents.rs @@ -6,12 +6,13 @@ 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"; -const AUTO_GENERATED: &str = - "# Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. +pub const PACKAGE: &str = "package"; +pub const AUTHORS: &str = "authors"; +const AUTO_GENERATED: &str = "# Code generated by the multiversx-sc build system. DO NOT EDIT. # ########################################## # ############## AUTO-GENERATED ############# @@ -70,7 +71,7 @@ impl CargoTomlContents { pub fn package_name(&self) -> String { self.toml_value - .get("package") + .get(PACKAGE) .expect("missing package in Cargo.toml") .get("name") .expect("missing package name in Cargo.toml") @@ -81,7 +82,7 @@ impl CargoTomlContents { pub fn package_edition(&self) -> String { self.toml_value - .get("package") + .get(PACKAGE) .expect("missing package in Cargo.toml") .get("edition") .expect("missing package name in Cargo.toml") @@ -159,6 +160,24 @@ impl CargoTomlContents { self.toml_value.get(CARGO_TOML_DEV_DEPENDENCIES).is_some() } + pub fn change_author(&mut self, authors: String) -> bool { + let package = self + .toml_value + .get_mut(PACKAGE) + .unwrap_or_else(|| panic!("no dependencies found in crate {}", self.path.display())) + .as_table_mut() + .expect("missing package in Cargo.toml"); + + package.remove(AUTHORS); + + package.insert( + AUTHORS.to_owned(), + toml::Value::Array(vec![toml::Value::String(authors)]), + ); + + true + } + pub fn dev_dependencies_mut(&mut self) -> &mut Table { self.toml_value .get_mut(CARGO_TOML_DEV_DEPENDENCIES) @@ -214,10 +233,20 @@ impl CargoTomlContents { "panic".to_string(), Value::String(contract_profile.panic.to_owned()), ); + profile_props.insert( + "overflow-checks".to_string(), + 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/code_report_json.rs b/framework/meta-lib/src/code_report_json.rs new file mode 100644 index 0000000000..a0b997bb6e --- /dev/null +++ b/framework/meta-lib/src/code_report_json.rs @@ -0,0 +1,30 @@ +use serde::{Deserialize, Serialize}; + +use crate::tools::report_creator::ReportCreator; + +#[derive(Serialize, Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub struct CodeReportJson { + #[serde(default)] + pub path: String, + + #[serde(default)] + pub size: usize, + + #[serde(default)] + pub has_allocator: bool, + + #[serde(default)] + pub has_panic: String, +} + +impl CodeReportJson { + pub fn new(report: &ReportCreator, size: usize) -> CodeReportJson { + CodeReportJson { + path: report.path.clone(), + size, + has_allocator: report.has_allocator, + has_panic: report.has_panic.clone(), + } + } +} 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..4977e41d30 --- /dev/null +++ b/framework/meta-lib/src/contract/generate_proxy/proxy_gen_main.rs @@ -0,0 +1,54 @@ +use colored::Colorize; +use std::fs; + +use crate::contract::sc_config::proxy_config::ProxyConfig; + +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) { + if self.sc_config.proxy_configs.is_empty() { + let proxy_config_default = + ProxyConfig::new_with_default_path(self.original_contract_abi.clone()); + write_proxy_with_explicit_path(&proxy_config_default, self); + return; + } + + for proxy_config in &self.sc_config.proxy_configs { + write_proxy_with_explicit_path(proxy_config, self); + } + } + + pub fn compare_proxy(&mut self) { + for proxy_config in &self.sc_config.proxy_configs { + compare_proxy_explicit_path(proxy_config, self); + } + } +} + +fn compare_proxy_explicit_path(proxy_config: &ProxyConfig, meta_config: &MetaConfig) { + let mut temp = Vec::::new(); + let mut proxy_generator = ProxyGenerator::new(meta_config, &mut temp, proxy_config); + proxy_generator.write_proxy_to_file(); + + let existent_proxy_path = format!("../{}", proxy_config.path); + let existent_proxy = fs::read_to_string(existent_proxy_path); + + if let Ok(existent_proxy) = existent_proxy { + 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: &ProxyConfig, meta_config: &MetaConfig) { + let mut file = create_file(&proxy_config.path); + let mut proxy_generator = ProxyGenerator::new(meta_config, &mut file, proxy_config); + proxy_generator.write_proxy_to_file(); +} 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..dbbc3f7bb0 --- /dev/null +++ b/framework/meta-lib/src/contract/generate_proxy/proxy_generator.rs @@ -0,0 +1,688 @@ +use std::fmt::Display; + +use multiversx_sc::abi::{ + EndpointAbi, EnumVariantDescription, InputAbi, OutputAbi, StructFieldDescription, TypeContents, + TypeDescription, +}; + +use crate::contract::{meta_config::MetaConfig, sc_config::proxy_config::ProxyConfig}; + +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 ProxyConfig, +} + +impl<'a> ProxyGenerator<'a> { + pub fn new( + meta_config: &'a MetaConfig, + file: &'a mut dyn std::io::Write, + proxy_config: &'a ProxyConfig, + ) -> Self { + Self { + meta_config, + file: Some(file), + proxy_config, + } + } + + 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); + + if self.proxy_config.override_import.is_empty() { + self.writeln(IMPORTS); + return; + } + + self.writeln(self.proxy_config.override_import.to_owned()); + } + + fn write_tx_proxy_type_def(&mut self) { + let proxy_type_name = proxy_type_name(&self.proxy_config.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.proxy_config.abi.name); + let proxy_methods_type_name = proxy_methods_type_name(&self.proxy_config.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.proxy_config.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.proxy_config.abi.constructors.is_empty() { + self.write_constructors(); + } + + if !self.proxy_config.abi.upgrade_constructors.is_empty() { + self.write_upgrades(); + } + + if !self.proxy_config.abi.endpoints.is_empty() { + self.write_endpoints(); + } + } + + fn write_types(&mut self) { + for (_, type_description) in &self.proxy_config.abi.type_descriptions.0 { + if self.proxy_config.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.proxy_config.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 + .proxy_config + .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.proxy_config.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.proxy_config.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.proxy_config.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.proxy_config.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(); + + for path_rename in &self.proxy_config.path_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.proxy_config.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::proxy_config::ProxyConfig}; + + 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.clone(), false); + let mut proxy_generator = ProxyGenerator { + meta_config: &meta_config, + file: None, + proxy_config: &ProxyConfig::new_with_default_path(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.clone(), false); + let mut proxy_generator = ProxyGenerator { + meta_config: &meta_config, + file: None, + proxy_config: &ProxyConfig::new_with_default_path(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 5b61c1e4f6..0b9d9485e1 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 = "interactor/src/proxy.rs" + "#; +static PROXY_PATH: &str = "interactor/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.44.0" +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 58% 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 d85c1cc48c..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!("\"file:../output/{crate_name}.wasm\""); + 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 56% 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..d450decd82 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,33 @@ 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( +const DEFAULT_GAS: &str = "30_000_000u64"; + +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 +35,45 @@ 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 upgrade_abi in &abi.upgrade_constructors { + write_upgrade_endpoint_impl(file, upgrade_abi, &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) + .gas({DEFAULT_GAS}) + .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 +83,47 @@ s write_newline(file); } -fn write_endpoint_impl(file: &mut File, endpoint_abi: &EndpointAbi) { +fn write_upgrade_endpoint_impl(file: &mut File, upgrade_abi: &EndpointAbi, name: &String) { + write_method_declaration(file, "upgrade"); + write_endpoint_args_declaration(file, &upgrade_abi.inputs); + let proxy_name = format!("{}Proxy", name); + + writeln!( + file, + r#" let response = self + .interactor + .tx() + .to(self.state.current_address()) + .from(&self.wallet_address) + .gas({DEFAULT_GAS}) + .typed(proxy::{}) + .upgrade({}) + .code(&self.contract_code) + .code_metadata(CodeMetadata::UPGRADEABLE) + .returns(ReturnsNewAddress) + .prepare_async() + .run() + .await; + + println!("Result: {{response:?}}");"#, + proxy_name, + endpoint_args_when_called(upgrade_abi.inputs.as_slice()), + ) + .unwrap(); + + // close method block brackets + writeln!(file, " }}").unwrap(); + write_newline(file); +} + +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 +153,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 +170,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 +194,32 @@ 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()) + .gas({DEFAULT_GAS}) + .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 +227,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..a7e7a41f1d --- /dev/null +++ b/framework/meta-lib/src/contract/generate_snippets/snippet_template_gen.rs @@ -0,0 +1,158 @@ +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::gateway::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 upgrade_endpoint in &abi.upgrade_constructors { + writeln!( + file, + r#" "{}" => interact.{}().await,"#, + upgrade_endpoint.name, upgrade_endpoint.rust_method_name + ) + .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 73% 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..e48794ba27 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 @@ -5,7 +5,7 @@ const INNER_TYPE_END: char = '>'; pub static STATIC_API_SUFFIX: &str = ""; pub static PLACEHOLDER_INPUT_TYPE_NAME: &str = "PlaceholderInput"; -#[derive(Clone, Default)] +#[derive(Clone, Default, Debug)] pub struct RustTypeString { type_name: String, // used for return types default_value_expr: String, // used for arguments @@ -13,16 +13,8 @@ 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 - } else { - PLACEHOLDER_INPUT_TYPE_NAME - } + &self.default_value_expr } } @@ -183,12 +175,14 @@ 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) => { // most user-defined types contain managed types - type_string.type_name += &(user_type + STATIC_API_SUFFIX); + type_string.type_name += &format!("{}{}", user_type, STATIC_API_SUFFIX); + type_string.default_value_expr += + &format!("{}::{}::default()", user_type, STATIC_API_SUFFIX); type_string.contains_custom_types = true; }, AbiType::Basic(basic_type) => { @@ -208,12 +202,24 @@ fn handle_abi_type(type_string: &mut RustTypeString, abi_type_str: String) { fn handle_variadic_type(type_string: &mut RustTypeString, inner_types: String) { type_string.type_name += "MultiValueVec<"; - type_string.default_value_expr += "MultiValueVec::from(vec!["; + let mut inner_type_string = RustTypeString::default(); - handle_abi_type(type_string, inner_types); + handle_abi_type(&mut inner_type_string, inner_types); + type_string.type_name += &inner_type_string.type_name; type_string.type_name += ">"; - type_string.default_value_expr += "])"; + + if inner_type_string.contains_custom_types { + type_string.default_value_expr += "MultiValueVec::<"; + type_string.default_value_expr += &inner_type_string.type_name; + type_string.default_value_expr += ">::new()"; + } else { + type_string.default_value_expr += "MultiValueVec::from(vec!["; + type_string.default_value_expr += &inner_type_string.default_value_expr; + type_string.default_value_expr += "])"; + } + + type_string.contains_custom_types |= inner_type_string.contains_custom_types; } fn handle_optional_type(type_string: &mut RustTypeString, inner_types: String) { @@ -228,40 +234,71 @@ fn handle_optional_type(type_string: &mut RustTypeString, inner_types: String) { fn handle_multi_type(type_string: &mut RustTypeString, inner_types: String) { let multi_type_end_index = inner_types.find(INNER_TYPE_END).unwrap(); - let mut inner_multi_types: Vec<&str> = inner_types[..multi_type_end_index].split(',').collect(); + let inner_multi_types: Vec<&str> = inner_types[..multi_type_end_index].split(',').collect(); let inner_multi_types_len = inner_multi_types.len(); - type_string.type_name += "MultiValue"; - type_string.type_name += &inner_multi_types_len.to_string(); - type_string.type_name += "<"; - - // "MultiValueN::from((x, y, z))" - type_string.default_value_expr += "MultiValue"; - type_string.default_value_expr += &inner_multi_types_len.to_string(); - type_string.default_value_expr += "::from(("; + // "MultiValueN::::from((x, y, z))" + let mut type_name_parts = Vec::new(); + let mut default_value_expr_parts = Vec::new(); + let mut contains_custom_types = false; - for (i, multi_type) in inner_multi_types.iter_mut().enumerate() { + for (i, multi_type) in inner_multi_types.iter().enumerate() { let trimmed = multi_type.trim(); - handle_abi_type(type_string, trimmed.to_string()); + let mut inner_type_string = RustTypeString::default(); + + handle_abi_type(&mut inner_type_string, trimmed.to_string()); + + type_name_parts.push(inner_type_string.type_name.clone()); + + if inner_type_string.contains_custom_types { + contains_custom_types = true + } + default_value_expr_parts.push(inner_type_string.default_value_expr); if i < inner_multi_types_len - 1 { - type_string.type_name += ", "; - type_string.default_value_expr += ", "; + default_value_expr_parts.push(", ".to_string()); } } - type_string.type_name += ">"; - type_string.default_value_expr += "))"; + // construct the type name + let type_name = format!( + "MultiValue{}::<{}>", + inner_multi_types_len, + type_name_parts.join(", ") + ); + + // construct the default value expression + let default_value_expr = format!( + "{}::from(({}))", + type_name, + default_value_expr_parts.join("") + ); + + type_string.type_name = type_name; + type_string.default_value_expr = default_value_expr; + type_string.contains_custom_types |= contains_custom_types; } fn handle_list_type(type_string: &mut RustTypeString, inner_types: String) { type_string.type_name += "ManagedVec::new(), }; diff --git a/framework/meta-lib/src/contract/sc_config.rs b/framework/meta-lib/src/contract/sc_config.rs new file mode 100644 index 0000000000..ff41a7655d --- /dev/null +++ b/framework/meta-lib/src/contract/sc_config.rs @@ -0,0 +1,21 @@ +mod contract_variant; +mod contract_variant_builder; +mod contract_variant_settings; +mod contract_variant_validate; +pub mod proxy_config; +mod sc_config_model; +mod sc_config_proxy; +mod sc_config_serde; +mod wasm_build; +mod wasm_clean; +mod wasm_crate_gen; +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/oc_config.rs b/framework/meta-lib/src/contract/sc_config/contract_variant.rs similarity index 87% rename from framework/meta/src/cmd/contract/sc_config/oc_config.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/oc_config.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/oc_builder.rs b/framework/meta-lib/src/contract/sc_config/contract_variant_builder.rs similarity index 68% rename from framework/meta/src/cmd/contract/sc_config/oc_builder.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant_builder.rs index 882039f469..8bf9793f39 100644 --- a/framework/meta/src/cmd/contract/sc_config/oc_builder.rs +++ b/framework/meta-lib/src/contract/sc_config/contract_variant_builder.rs @@ -1,3 +1,4 @@ +use core::panic; use multiversx_sc::abi::{ContractAbi, EndpointAbi}; use std::{ collections::{BTreeSet, HashMap, HashSet}, @@ -5,11 +6,14 @@ use std::{ path::{Path, PathBuf}, }; +use crate::ei::parse_check_ei; + use super::{ - oc_global_config::SC_CONFIG_FILE_NAMES, - oc_settings::{parse_allocator, parse_check_ei, parse_stack_size}, - ContractVariant, ContractVariantSerde, ContractVariantSettings, MultiContractConfigSerde, - ScConfig, + contract_variant_settings::{parse_allocator, parse_stack_size}, + proxy_config::ProxyConfig, + sc_config_model::SC_CONFIG_FILE_NAMES, + ContractVariant, ContractVariantProfile, ContractVariantSerde, ContractVariantSettings, + ProxyConfigSerde, ScConfig, ScConfigSerde, }; /// Temporary structure, to help create instances of `ContractVariant`. Not publicly exposed. @@ -75,10 +79,7 @@ impl ContractVariantBuilder { stack_size: parse_stack_size(&cms.stack_size), features: cms.features.clone(), kill_legacy_callback: cms.kill_legacy_callback, - contract_variant_profile: cms - .contract_variant_profile - .clone() - .unwrap_or(default.settings.contract_variant_profile), + profile: ContractVariantProfile::from_serde(&cms.profile), }, ..default }, @@ -170,11 +171,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) @@ -189,6 +192,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(), @@ -198,7 +202,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") } @@ -234,7 +238,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; } @@ -251,32 +255,126 @@ fn validate_contract_variants(contracts: &[ContractVariant]) { } } +fn process_contracts(config: &ScConfigSerde, original_abi: &ContractAbi) -> Vec { + let mut contract_builders: HashMap = config + .contracts + .iter() + .map(ContractVariantBuilder::map_from_config) + .collect(); + + 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); + + contracts +} + +fn process_proxy_contracts(config: &ScConfigSerde, original_abi: &ContractAbi) -> Vec { + let mut proxy_contracts = Vec::new(); + + let main_contract = process_contracts(config, original_abi) + .into_iter() + .find(|contract| contract.main) + .unwrap(); + + proxy_contracts.push(ProxyConfig::new_with_default_path(main_contract.abi)); + + for proxy_config in &config.proxy { + let mut contract_builders = HashMap::new(); + + match &proxy_config.variant { + Some(variant) => { + let setting_contract = config + .contracts + .iter() + .find(|setting| setting.0.eq(variant)) + .unwrap_or_else(|| panic!("No contact with this name")); + let (contract_id, mut contract_builder) = + ContractVariantBuilder::map_from_config(setting_contract); + alter_builder_with_proxy_config(proxy_config, &mut contract_builder); + + contract_builders = HashMap::from([(contract_id, contract_builder)]); + }, + None => { + let mut contract_builder = ContractVariantBuilder::default(); + alter_builder_with_proxy_config(proxy_config, &mut contract_builder); + + contract_builders.insert(proxy_config.path.clone(), contract_builder); + }, + } + + collect_and_process_endpoints( + &mut contract_builders, + original_abi, + &config.labels_for_contracts, + ); + if let Some((_, builder)) = contract_builders.into_iter().next() { + let contract = build_contract(builder, original_abi); + + proxy_contracts.push(ProxyConfig::new( + proxy_config.path.to_owned(), + proxy_config.override_import.to_owned(), + proxy_config.path_rename.to_owned(), + contract.abi, + )); + } + } + + proxy_contracts +} + impl ScConfig { /// Assembles an `ContractVariantConfig` from a raw config object that was loaded via Serde. /// /// In most cases the config will be loaded from a .toml file, use `load_from_file` for that. - pub fn load_from_config(config: &MultiContractConfigSerde, original_abi: &ContractAbi) -> Self { - let mut contract_builders: HashMap = config - .contracts - .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); - let mut contracts: Vec = contract_builders - .into_values() - .map(|builder| build_contract(builder, original_abi)) - .collect(); - set_main_contract_flag(&mut contracts, &config.settings.main); - validate_contract_variants(&contracts); + pub fn load_from_config(config: &ScConfigSerde, original_abi: &ContractAbi) -> Self { + let default_contract_config_name = config.settings.main.clone().unwrap_or_default(); ScConfig { - default_contract_config_name: config.settings.main.clone().unwrap_or_default(), - contracts, + default_contract_config_name, + contracts: process_contracts(config, original_abi), + proxy_configs: process_proxy_contracts(config, original_abi), } } +} + +fn alter_builder_with_proxy_config( + proxy_config: &ProxyConfigSerde, + contract_builder: &mut ContractVariantBuilder, +) { + let default = ContractVariantBuilder::default(); + contract_builder.add_unlabelled = proxy_config + .add_unlabelled + .unwrap_or(default.add_unlabelled); + contract_builder.add_endpoints = proxy_config.add_endpoints.iter().cloned().collect(); + contract_builder.add_labels = proxy_config.add_labels.iter().cloned().collect(); +} + +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. @@ -293,6 +391,7 @@ impl ScConfig { wasm_crate_name, abi: original_abi.clone(), }], + proxy_configs: Vec::new(), } } @@ -300,7 +399,7 @@ impl ScConfig { pub fn load_from_file>(path: P, original_abi: &ContractAbi) -> Option { match fs::read_to_string(path.as_ref()) { Ok(s) => { - let config_serde: MultiContractConfigSerde = toml::from_str(s.as_str()) + let config_serde: ScConfigSerde = toml::from_str(s.as_str()) .unwrap_or_else(|error| panic!("error parsing multicontract.toml: {error}")); Some(Self::load_from_config(&config_serde, original_abi)) }, diff --git a/framework/meta-lib/src/contract/sc_config/contract_variant_settings.rs b/framework/meta-lib/src/contract/sc_config/contract_variant_settings.rs new file mode 100644 index 0000000000..b0af57deef --- /dev/null +++ b/framework/meta-lib/src/contract/sc_config/contract_variant_settings.rs @@ -0,0 +1,101 @@ +mod contract_allocator; +mod stack_size; + +pub use contract_allocator::{parse_allocator, ContractAllocator}; +pub use stack_size::*; + +use crate::ei::EIVersion; + +use super::ContractVariantProfileSerde; + +/// Collection of flags, specified in the multicontract config. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct ContractVariantSettings { + /// External view contracts are just readers of data from another contract. + pub external_view: bool, + + /// Panic messages add a lot of bloat to the final bytecode, + /// so they should only be used for debugging purposes. + pub panic_message: bool, + + /// Post-processing check of the VM hooks is based on this. + pub check_ei: Option, + + /// Allocator config, i.e which allocator to choose for the contract. + pub allocator: ContractAllocator, + + pub stack_size: usize, + + /// Features that are activated on the contract crate, from wasm. + pub features: Vec, + + /// Forcibly remove the original contrct legacy callback. + pub kill_legacy_callback: bool, + + pub profile: ContractVariantProfile, +} + +impl Default for ContractVariantSettings { + fn default() -> Self { + ContractVariantSettings { + external_view: Default::default(), + panic_message: Default::default(), + check_ei: Some(EIVersion::default()), + allocator: Default::default(), + stack_size: DEFAULT_STACK_SIZE, + features: Default::default(), + kill_legacy_callback: false, + profile: Default::default(), + } + } +} + +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct ContractVariantProfile { + pub codegen_units: u8, + pub opt_level: String, + pub lto: bool, + pub debug: bool, + pub panic: String, + pub overflow_checks: bool, +} + +impl Default for ContractVariantProfile { + fn default() -> ContractVariantProfile { + ContractVariantProfile { + codegen_units: 1u8, + opt_level: "z".to_owned(), + lto: true, + debug: false, + panic: "abort".to_owned(), + overflow_checks: false, + } + } +} + +impl ContractVariantProfile { + pub fn from_serde(opt_serde_profile: &Option) -> Self { + let mut result = Self::default(); + if let Some(serde_profile) = opt_serde_profile { + if let Some(codegen_units) = serde_profile.codegen_units { + result.codegen_units = codegen_units; + } + if let Some(opt_level) = &serde_profile.opt_level { + result.opt_level.clone_from(opt_level); + } + if let Some(lto) = serde_profile.lto { + result.lto = lto; + } + if let Some(debug) = serde_profile.debug { + result.debug = debug; + } + if let Some(panic) = &serde_profile.panic { + result.panic.clone_from(panic); + } + if let Some(overflow_checks) = serde_profile.overflow_checks { + result.overflow_checks = overflow_checks; + } + } + result + } +} diff --git a/framework/meta/src/cmd/contract/sc_config/oc_settings/oc_allocator.rs b/framework/meta-lib/src/contract/sc_config/contract_variant_settings/contract_allocator.rs similarity index 89% rename from framework/meta/src/cmd/contract/sc_config/oc_settings/oc_allocator.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant_settings/contract_allocator.rs index 14441dca02..6a5cc68c75 100644 --- a/framework/meta/src/cmd/contract/sc_config/oc_settings/oc_allocator.rs +++ b/framework/meta-lib/src/contract/sc_config/contract_variant_settings/contract_allocator.rs @@ -44,3 +44,10 @@ impl ContractAllocator { } } } + +pub fn parse_allocator(allocator: &Option) -> ContractAllocator { + allocator + .as_ref() + .map(|s| ContractAllocator::parse_or_panic(s)) + .unwrap_or_default() +} diff --git a/framework/meta/src/cmd/contract/sc_config/oc_settings/oc_parse_stack_size.rs b/framework/meta-lib/src/contract/sc_config/contract_variant_settings/stack_size.rs similarity index 91% rename from framework/meta/src/cmd/contract/sc_config/oc_settings/oc_parse_stack_size.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant_settings/stack_size.rs index 6e0ddb3fd7..0ad4eda7af 100644 --- a/framework/meta/src/cmd/contract/sc_config/oc_settings/oc_parse_stack_size.rs +++ b/framework/meta-lib/src/contract/sc_config/contract_variant_settings/stack_size.rs @@ -44,5 +44,8 @@ mod tests { assert_eq!(parse_stack_size_expr("1 pages"), 65536); assert_eq!(parse_stack_size_expr("2 pages"), 65536 * 2); assert_eq!(parse_stack_size_expr("10 pages"), 65536 * 10); + + assert_eq!(parse_stack_size_expr("128k"), DEFAULT_STACK_SIZE); + assert_eq!(parse_stack_size_expr("2 pages"), DEFAULT_STACK_SIZE); } } diff --git a/framework/meta/src/cmd/contract/sc_config/oc_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/oc_validate.rs rename to framework/meta-lib/src/contract/sc_config/contract_variant_validate.rs index 4b60fe14e4..7ea1572437 100644 --- a/framework/meta/src/cmd/contract/sc_config/oc_validate.rs +++ b/framework/meta-lib/src/contract/sc_config/contract_variant_validate.rs @@ -9,16 +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 => 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()), + } } /// 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)?; } @@ -57,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::*; @@ -66,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); @@ -91,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-lib/src/contract/sc_config/proxy_config.rs b/framework/meta-lib/src/contract/sc_config/proxy_config.rs new file mode 100644 index 0000000000..2097f50559 --- /dev/null +++ b/framework/meta-lib/src/contract/sc_config/proxy_config.rs @@ -0,0 +1,37 @@ +use multiversx_sc::abi::ContractAbi; + +use super::sc_config_proxy::PathRename; +const DEFAULT_PATH: &str = "/output/proxy.rs"; + +#[derive(Debug)] +pub struct ProxyConfig { + pub path: String, + pub override_import: String, + pub path_rename: Vec, + pub abi: ContractAbi, +} + +impl ProxyConfig { + pub fn new( + path: String, + override_imports: Option, + path_rename: Option>, + abi: ContractAbi, + ) -> Self { + ProxyConfig { + path, + override_import: override_imports.unwrap_or_default(), + path_rename: path_rename.unwrap_or_default(), + abi, + } + } + + pub fn new_with_default_path(abi: ContractAbi) -> Self { + ProxyConfig { + path: DEFAULT_PATH.to_string(), + override_import: String::new(), + path_rename: Vec::new(), + abi, + } + } +} diff --git a/framework/meta/src/cmd/contract/sc_config/oc_global_config.rs b/framework/meta-lib/src/contract/sc_config/sc_config_model.rs similarity index 94% rename from framework/meta/src/cmd/contract/sc_config/oc_global_config.rs rename to framework/meta-lib/src/contract/sc_config/sc_config_model.rs index 1bfb2ffa71..8286abd5b9 100644 --- a/framework/meta/src/cmd/contract/sc_config/oc_global_config.rs +++ b/framework/meta-lib/src/contract/sc_config/sc_config_model.rs @@ -1,4 +1,7 @@ -use super::{oc_validate::validate_contract_variant, ContractVariant}; +use super::{ + contract_variant_validate::validate_contract_variant, proxy_config::ProxyConfig, + 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..ada8b230cc --- /dev/null +++ b/framework/meta-lib/src/contract/sc_config/sc_config_proxy.rs @@ -0,0 +1,55 @@ +use serde::Deserialize; + +const DEFAULT_PATH: &str = "/output/proxy.rs"; + +#[derive(Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)] +#[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, + + #[serde(rename = "add-unlabelled")] + pub add_unlabelled: Option, + + #[serde(default)] + #[serde(rename = "add-labels")] + pub add_labels: Vec, + + #[serde(default)] + #[serde(rename = "add-endpoints")] + pub add_endpoints: Vec, +} + +impl ProxyConfigSerde { + pub fn new() -> Self { + Self { + path: DEFAULT_PATH.to_string(), + override_import: None, + path_rename: None, + variant: None, + add_unlabelled: None, + add_labels: Vec::new(), + add_endpoints: Vec::new(), + } + } +} + +#[derive(Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)] +pub struct PathRename { + #[serde(default)] + pub from: String, + + #[serde(default)] + pub to: String, +} diff --git a/framework/meta/src/cmd/contract/sc_config/multi_contract_serde.rs b/framework/meta-lib/src/contract/sc_config/sc_config_serde.rs similarity index 62% rename from framework/meta/src/cmd/contract/sc_config/multi_contract_serde.rs rename to framework/meta-lib/src/contract/sc_config/sc_config_serde.rs index e671fb485a..c3c6b94d30 100644 --- a/framework/meta/src/cmd/contract/sc_config/multi_contract_serde.rs +++ b/framework/meta-lib/src/contract/sc_config/sc_config_serde.rs @@ -1,18 +1,24 @@ use serde::Deserialize; use std::collections::HashMap; +use super::ProxyConfigSerde; + #[derive(Deserialize, Debug)] -pub struct MultiContractConfigSerde { +#[serde(deny_unknown_fields)] +pub struct ScConfigSerde { #[serde(default)] pub settings: MultiContractGeneralSettingsSerde, #[serde(default)] pub contracts: HashMap, #[serde(default)] + pub proxy: Vec, + #[serde(default)] #[serde(rename = "labels-for-contracts")] pub labels_for_contracts: HashMap>, } #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct ContractVariantSerde { pub name: Option, @@ -53,31 +59,36 @@ pub struct ContractVariantSerde { pub kill_legacy_callback: bool, #[serde(default)] - pub contract_variant_profile: Option, + pub profile: Option, } #[derive(Deserialize, Default, Debug)] +#[serde(deny_unknown_fields)] pub struct MultiContractGeneralSettingsSerde { pub main: Option, } -#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] -pub struct ContractVariantProfile { - pub codegen_units: u8, - pub opt_level: String, - pub lto: bool, - pub debug: bool, - pub panic: String, -} +#[derive(Deserialize, Default, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] +pub struct ContractVariantProfileSerde { + #[serde(default)] + #[serde(rename = "codegen-units")] + pub codegen_units: Option, -impl Default for ContractVariantProfile { - fn default() -> ContractVariantProfile { - ContractVariantProfile { - codegen_units: 1u8, - opt_level: "z".to_owned(), - lto: true, - debug: false, - panic: "abort".to_owned(), - } - } + #[serde(default)] + #[serde(rename = "opt-level")] + pub opt_level: Option, + + #[serde(default)] + pub lto: Option, + + #[serde(default)] + pub debug: Option, + + #[serde(default)] + pub panic: Option, + + #[serde(default)] + #[serde(rename = "overflow-checks")] + pub overflow_checks: Option, } 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 82% 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 879a726a09..5b318da9a0 100644 --- a/framework/meta/src/cmd/contract/sc_config/wasm_build.rs +++ b/framework/meta-lib/src/contract/sc_config/wasm_build.rs @@ -3,11 +3,13 @@ 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}, print_util::*, - tools, + report_info_json::ReportInfoJson, + tools::{self, WasmInfo}, }; impl ContractVariant { @@ -71,9 +73,9 @@ impl ContractVariant { self.copy_contracts_to_output(build_args, output_path); self.run_wasm_opt(build_args, output_path); self.run_wasm2wat(build_args, output_path); - self.extract_imports(build_args, output_path); + let wasm_info = self.extract_wasm_info(build_args, output_path); self.run_twiggy(build_args, output_path); - self.pack_mxsc_file(build_args, output_path); + self.pack_mxsc_file(build_args, output_path, wasm_info); } fn copy_contracts_to_output(&self, build_args: &BuildArgs, output_path: &str) { @@ -84,7 +86,7 @@ impl ContractVariant { .expect("failed to copy compiled contract to output directory"); } - fn pack_mxsc_file(&self, build_args: &BuildArgs, output_path: &str) { + fn pack_mxsc_file(&self, build_args: &BuildArgs, output_path: &str, wasm_info: WasmInfo) { let output_wasm_path = format!("{output_path}/{}", self.wasm_output_name(build_args)); let compiled_bytes = fs::read(output_wasm_path).expect("failed to open compiled contract"); let output_mxsc_path = format!("{output_path}/{}", self.mxsc_file_output_name(build_args)); @@ -92,11 +94,13 @@ impl ContractVariant { print_contract_size(compiled_bytes.len()); let mut abi = ContractAbiJson::from(&self.abi); let build_info = core::mem::take(&mut abi.build_info).unwrap(); + let ei_check_json = EiCheckJson::new(&self.settings.check_ei, wasm_info.ei_check); + let report = ReportInfoJson::new(&wasm_info, ei_check_json, compiled_bytes.len()); let mxsc_file_json = MxscFileJson { build_info, abi, - size: compiled_bytes.len(), code: hex::encode(compiled_bytes), + report, }; save_mxsc_file_json(&mxsc_file_json, output_mxsc_path); @@ -123,21 +127,36 @@ impl ContractVariant { tools::wasm_to_wat(output_wasm_path.as_str(), output_wat_path.as_str()); } - fn extract_imports(&self, build_args: &BuildArgs, output_path: &str) { + fn extract_wasm_info(&self, build_args: &BuildArgs, output_path: &str) -> WasmInfo { + let output_wasm_path = format!("{output_path}/{}", self.wasm_output_name(build_args)); + if !build_args.extract_imports { - return; + return WasmInfo::extract_wasm_info( + &output_wasm_path, + build_args.extract_imports, + &self.settings.check_ei, + ) + .expect("error occured while extracting imports from .wasm "); } - let output_wasm_path = format!("{output_path}/{}", self.wasm_output_name(build_args)); let output_imports_json_path = format!( "{}/{}", output_path, self.imports_json_output_name(build_args) ); print_extract_imports(&output_imports_json_path); - let import_names = tools::extract_wasm_imports(&output_wasm_path); - write_imports_output(output_imports_json_path.as_str(), import_names.as_slice()); - validate_ei(&import_names, &self.settings.check_ei); + + let wasm_data = + WasmInfo::extract_wasm_info(&output_wasm_path, true, &self.settings.check_ei) + .expect("error occured while extracting imports from .wasm "); + + write_imports_output( + output_imports_json_path.as_str(), + wasm_data.imports.as_slice(), + ); + print_ei_check(&wasm_data, &self.settings.check_ei); + + wasm_data } } @@ -146,18 +165,19 @@ fn write_imports_output(dest_path: &str, import_names: &[String]) { fs::write(dest_path, json).expect("failed to write imports json file"); } -fn validate_ei(import_names: &[String], check_ei: &Option) { +fn print_ei_check(wasm_data: &WasmInfo, check_ei: &Option) { if let Some(ei) = check_ei { print_check_ei(ei.name()); - let mut num_errors = 0; - for import_name in import_names { - if !ei.contains_vm_hook(import_name) { - print_invalid_vm_hook(import_name, ei.name()); - num_errors += 1; - } - } - if num_errors == 0 { + + if wasm_data.ei_check { print_check_ei_ok(); + return; + } + + for import_name in &wasm_data.imports { + if !ei.contains_vm_hook(import_name.as_str()) { + print_invalid_vm_hook(import_name.as_str(), ei.name()); + } } } else { print_ignore_ei_check(); 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 91% 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 141bc8a266..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 @@ -10,7 +10,7 @@ use std::{ use super::ContractVariant; const PREFIX_AUTO_GENERATED: &str = - "// Code generated by the multiversx-sc multi-contract system. DO NOT EDIT. + "// Code generated by the multiversx-sc build system. DO NOT EDIT. //////////////////////////////////////////////////// ////////////////// AUTO-GENERATED ////////////////// @@ -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 58% rename from framework/meta/src/ei.rs rename to framework/meta-lib/src/ei.rs index 8198d69c87..7f58c2ad1e 100644 --- a/framework/meta/src/ei.rs +++ b/framework/meta-lib/src/ei.rs @@ -2,10 +2,14 @@ mod ei_1_0; mod ei_1_1; mod ei_1_2; mod ei_1_3; +mod ei_1_4; +mod ei_1_5; mod ei_version; pub use ei_1_0::EI_1_0_NAMES; pub use ei_1_1::EI_1_1_NAMES; pub use ei_1_2::EI_1_2_NAMES; pub use ei_1_3::EI_1_3_NAMES; -pub use ei_version::EIVersion; +pub use ei_1_4::EI_1_4_NAMES; +pub use ei_1_5::EI_1_5_NAMES; +pub use ei_version::{parse_check_ei, EIVersion}; 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 98% rename from framework/meta/src/ei/ei_1_3.rs rename to framework/meta-lib/src/ei/ei_1_3.rs index ae360d5fce..210776f3c4 100644 --- a/framework/meta/src/ei/ei_1_3.rs +++ b/framework/meta-lib/src/ei/ei_1_3.rs @@ -4,7 +4,8 @@ // !!!!!!!!!!!!!!!!!!!!!! AUTO-GENERATED FILE !!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -/// VM Hooks version planned to be released with VM 1.5 in Q2 2023. +/// VM Hooks version released in January 2024: +/// https://multiversx.com/release/release-sirius-v1-6-7 /// /// It adds the new async call functionality (promises). /// diff --git a/framework/meta-lib/src/ei/ei_1_4.rs b/framework/meta-lib/src/ei/ei_1_4.rs new file mode 100644 index 0000000000..9c4df8fc07 --- /dev/null +++ b/framework/meta-lib/src/ei/ei_1_4.rs @@ -0,0 +1,270 @@ +// Code generated by vmhooks generator. DO NOT EDIT. + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!! AUTO-GENERATED FILE !!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +pub const EI_1_4_NAMES: &[&str] = &[ + "getGasLeft", + "getSCAddress", + "getOwnerAddress", + "getShardOfAddress", + "isSmartContract", + "signalError", + "getExternalBalance", + "getBlockHash", + "getESDTBalance", + "getESDTNFTNameLength", + "getESDTNFTAttributeLength", + "getESDTNFTURILength", + "getESDTTokenData", + "getESDTLocalRoles", + "validateTokenIdentifier", + "transferValue", + "transferValueExecute", + "transferESDTExecute", + "transferESDTNFTExecute", + "multiTransferESDTNFTExecute", + "createAsyncCall", + "setAsyncContextCallback", + "upgradeContract", + "upgradeFromSourceContract", + "deleteContract", + "asyncCall", + "getArgumentLength", + "getArgument", + "getFunction", + "getNumArguments", + "storageStore", + "storageLoadLength", + "storageLoadFromAddress", + "storageLoad", + "setStorageLock", + "getStorageLock", + "isStorageLocked", + "clearStorageLock", + "getCaller", + "checkNoPayment", + "getCallValue", + "getESDTValue", + "getESDTValueByIndex", + "getESDTTokenName", + "getESDTTokenNameByIndex", + "getESDTTokenNonce", + "getESDTTokenNonceByIndex", + "getCurrentESDTNFTNonce", + "getESDTTokenType", + "getESDTTokenTypeByIndex", + "getNumESDTTransfers", + "getCallValueTokenName", + "getCallValueTokenNameByIndex", + "isReservedFunctionName", + "writeLog", + "writeEventLog", + "getBlockTimestamp", + "getBlockNonce", + "getBlockRound", + "getBlockEpoch", + "getBlockRandomSeed", + "getStateRootHash", + "getPrevBlockTimestamp", + "getPrevBlockNonce", + "getPrevBlockRound", + "getPrevBlockEpoch", + "getPrevBlockRandomSeed", + "finish", + "executeOnSameContext", + "executeOnDestContext", + "executeReadOnly", + "createContract", + "deployFromSourceContract", + "getNumReturnData", + "getReturnDataSize", + "getReturnData", + "cleanReturnData", + "deleteFromReturnData", + "getOriginalTxHash", + "getCurrentTxHash", + "getPrevTxHash", + "managedSCAddress", + "managedOwnerAddress", + "managedCaller", + "managedGetOriginalCallerAddr", + "managedGetRelayerAddr", + "managedSignalError", + "managedWriteLog", + "managedGetOriginalTxHash", + "managedGetStateRootHash", + "managedGetBlockRandomSeed", + "managedGetPrevBlockRandomSeed", + "managedGetReturnData", + "managedGetMultiESDTCallValue", + "managedGetBackTransfers", + "managedGetESDTBalance", + "managedGetESDTTokenData", + "managedAsyncCall", + "managedCreateAsyncCall", + "managedGetCallbackClosure", + "managedUpgradeFromSourceContract", + "managedUpgradeContract", + "managedDeleteContract", + "managedDeployFromSourceContract", + "managedCreateContract", + "managedExecuteReadOnly", + "managedExecuteOnSameContext", + "managedExecuteOnDestContext", + "managedMultiTransferESDTNFTExecute", + "managedMultiTransferESDTNFTExecuteByUser", + "managedTransferValueExecute", + "managedIsESDTFrozen", + "managedIsESDTLimitedTransfer", + "managedIsESDTPaused", + "managedBufferToHex", + "managedGetCodeMetadata", + "managedIsBuiltinFunction", + "bigFloatNewFromParts", + "bigFloatNewFromFrac", + "bigFloatNewFromSci", + "bigFloatAdd", + "bigFloatSub", + "bigFloatMul", + "bigFloatDiv", + "bigFloatNeg", + "bigFloatClone", + "bigFloatCmp", + "bigFloatAbs", + "bigFloatSign", + "bigFloatSqrt", + "bigFloatPow", + "bigFloatFloor", + "bigFloatCeil", + "bigFloatTruncate", + "bigFloatSetInt64", + "bigFloatIsInt", + "bigFloatSetBigInt", + "bigFloatGetConstPi", + "bigFloatGetConstE", + "bigIntGetUnsignedArgument", + "bigIntGetSignedArgument", + "bigIntStorageStoreUnsigned", + "bigIntStorageLoadUnsigned", + "bigIntGetCallValue", + "bigIntGetESDTCallValue", + "bigIntGetESDTCallValueByIndex", + "bigIntGetExternalBalance", + "bigIntGetESDTExternalBalance", + "bigIntNew", + "bigIntUnsignedByteLength", + "bigIntSignedByteLength", + "bigIntGetUnsignedBytes", + "bigIntGetSignedBytes", + "bigIntSetUnsignedBytes", + "bigIntSetSignedBytes", + "bigIntIsInt64", + "bigIntGetInt64", + "bigIntSetInt64", + "bigIntAdd", + "bigIntSub", + "bigIntMul", + "bigIntTDiv", + "bigIntTMod", + "bigIntEDiv", + "bigIntEMod", + "bigIntSqrt", + "bigIntPow", + "bigIntLog2", + "bigIntAbs", + "bigIntNeg", + "bigIntSign", + "bigIntCmp", + "bigIntNot", + "bigIntAnd", + "bigIntOr", + "bigIntXor", + "bigIntShr", + "bigIntShl", + "bigIntFinishUnsigned", + "bigIntFinishSigned", + "bigIntToString", + "mBufferNew", + "mBufferNewFromBytes", + "mBufferGetLength", + "mBufferGetBytes", + "mBufferGetByteSlice", + "mBufferCopyByteSlice", + "mBufferEq", + "mBufferSetBytes", + "mBufferSetByteSlice", + "mBufferAppend", + "mBufferAppendBytes", + "mBufferToBigIntUnsigned", + "mBufferToBigIntSigned", + "mBufferFromBigIntUnsigned", + "mBufferFromBigIntSigned", + "mBufferToBigFloat", + "mBufferFromBigFloat", + "mBufferStorageStore", + "mBufferStorageLoad", + "mBufferStorageLoadFromAddress", + "mBufferGetArgument", + "mBufferFinish", + "mBufferSetRandom", + "managedMapNew", + "managedMapPut", + "managedMapGet", + "managedMapRemove", + "managedMapContains", + "smallIntGetUnsignedArgument", + "smallIntGetSignedArgument", + "smallIntFinishUnsigned", + "smallIntFinishSigned", + "smallIntStorageStoreUnsigned", + "smallIntStorageStoreSigned", + "smallIntStorageLoadUnsigned", + "smallIntStorageLoadSigned", + "int64getArgument", + "int64finish", + "int64storageStore", + "int64storageLoad", + "sha256", + "managedSha256", + "keccak256", + "managedKeccak256", + "ripemd160", + "managedRipemd160", + "verifyBLS", + "managedVerifyBLS", + "verifyEd25519", + "managedVerifyEd25519", + "verifyCustomSecp256k1", + "managedVerifyCustomSecp256k1", + "verifySecp256k1", + "managedVerifySecp256k1", + "encodeSecp256k1DerSignature", + "managedEncodeSecp256k1DerSignature", + "addEC", + "doubleEC", + "isOnCurveEC", + "scalarBaseMultEC", + "managedScalarBaseMultEC", + "scalarMultEC", + "managedScalarMultEC", + "marshalEC", + "managedMarshalEC", + "marshalCompressedEC", + "managedMarshalCompressedEC", + "unmarshalEC", + "managedUnmarshalEC", + "unmarshalCompressedEC", + "managedUnmarshalCompressedEC", + "generateKeyEC", + "managedGenerateKeyEC", + "createEC", + "managedCreateEC", + "getCurveLengthEC", + "getPrivKeyByteLengthEC", + "ellipticCurveGetValues", + "managedVerifySecp256r1", + "managedVerifyBLSSignatureShare", + "managedVerifyBLSAggregatedSignature", +]; diff --git a/framework/meta-lib/src/ei/ei_1_5.rs b/framework/meta-lib/src/ei/ei_1_5.rs new file mode 100644 index 0000000000..1ad9b654db --- /dev/null +++ b/framework/meta-lib/src/ei/ei_1_5.rs @@ -0,0 +1,278 @@ +// Code generated by vmhooks generator. DO NOT EDIT. + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!! AUTO-GENERATED FILE !!!!!!!!!!!!!!!!!!!!!! +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +pub const EI_1_5_NAMES: &[&str] = &[ + "getGasLeft", + "getSCAddress", + "getOwnerAddress", + "getShardOfAddress", + "isSmartContract", + "signalError", + "getExternalBalance", + "getBlockHash", + "getESDTBalance", + "getESDTNFTNameLength", + "getESDTNFTAttributeLength", + "getESDTNFTURILength", + "getESDTTokenData", + "getESDTLocalRoles", + "validateTokenIdentifier", + "transferValue", + "transferValueExecute", + "transferESDTExecute", + "transferESDTNFTExecute", + "multiTransferESDTNFTExecute", + "createAsyncCall", + "setAsyncContextCallback", + "upgradeContract", + "upgradeFromSourceContract", + "deleteContract", + "asyncCall", + "getArgumentLength", + "getArgument", + "getFunction", + "getNumArguments", + "storageStore", + "storageLoadLength", + "storageLoadFromAddress", + "storageLoad", + "setStorageLock", + "getStorageLock", + "isStorageLocked", + "clearStorageLock", + "getCaller", + "checkNoPayment", + "getCallValue", + "getESDTValue", + "getESDTValueByIndex", + "getESDTTokenName", + "getESDTTokenNameByIndex", + "getESDTTokenNonce", + "getESDTTokenNonceByIndex", + "getCurrentESDTNFTNonce", + "getESDTTokenType", + "getESDTTokenTypeByIndex", + "getNumESDTTransfers", + "getCallValueTokenName", + "getCallValueTokenNameByIndex", + "isReservedFunctionName", + "writeLog", + "writeEventLog", + "getBlockTimestamp", + "getBlockNonce", + "getBlockRound", + "getBlockEpoch", + "getBlockRandomSeed", + "getStateRootHash", + "getPrevBlockTimestamp", + "getPrevBlockNonce", + "getPrevBlockRound", + "getPrevBlockEpoch", + "getPrevBlockRandomSeed", + "getRoundTime", + "epochStartBlockTimeStamp", + "epochStartBlockNonce", + "epochStartBlockRound", + "finish", + "executeOnSameContext", + "executeOnDestContext", + "executeReadOnly", + "createContract", + "deployFromSourceContract", + "getNumReturnData", + "getReturnDataSize", + "getReturnData", + "cleanReturnData", + "deleteFromReturnData", + "getOriginalTxHash", + "getCurrentTxHash", + "getPrevTxHash", + "managedSCAddress", + "managedOwnerAddress", + "managedCaller", + "managedGetOriginalCallerAddr", + "managedGetRelayerAddr", + "managedSignalError", + "managedWriteLog", + "managedGetOriginalTxHash", + "managedGetStateRootHash", + "managedGetBlockRandomSeed", + "managedGetPrevBlockRandomSeed", + "managedGetReturnData", + "managedGetMultiESDTCallValue", + "managedGetBackTransfers", + "managedGetESDTBalance", + "managedGetESDTTokenData", + "managedAsyncCall", + "managedCreateAsyncCall", + "managedGetCallbackClosure", + "managedUpgradeFromSourceContract", + "managedUpgradeContract", + "managedDeleteContract", + "managedDeployFromSourceContract", + "managedCreateContract", + "managedExecuteReadOnly", + "managedExecuteOnSameContext", + "managedExecuteOnDestContext", + "managedMultiTransferESDTNFTExecute", + "managedMultiTransferESDTNFTExecuteByUser", + "managedTransferValueExecute", + "managedIsESDTFrozen", + "managedIsESDTLimitedTransfer", + "managedIsESDTPaused", + "managedBufferToHex", + "managedGetCodeMetadata", + "managedIsBuiltinFunction", + "bigFloatNewFromParts", + "bigFloatNewFromFrac", + "bigFloatNewFromSci", + "bigFloatAdd", + "bigFloatSub", + "bigFloatMul", + "bigFloatDiv", + "bigFloatNeg", + "bigFloatClone", + "bigFloatCmp", + "bigFloatAbs", + "bigFloatSign", + "bigFloatSqrt", + "bigFloatPow", + "bigFloatFloor", + "bigFloatCeil", + "bigFloatTruncate", + "bigFloatSetInt64", + "bigFloatIsInt", + "bigFloatSetBigInt", + "bigFloatGetConstPi", + "bigFloatGetConstE", + "bigIntGetUnsignedArgument", + "bigIntGetSignedArgument", + "bigIntStorageStoreUnsigned", + "bigIntStorageLoadUnsigned", + "bigIntGetCallValue", + "bigIntGetESDTCallValue", + "bigIntGetESDTCallValueByIndex", + "bigIntGetExternalBalance", + "bigIntGetESDTExternalBalance", + "bigIntNew", + "bigIntUnsignedByteLength", + "bigIntSignedByteLength", + "bigIntGetUnsignedBytes", + "bigIntGetSignedBytes", + "bigIntSetUnsignedBytes", + "bigIntSetSignedBytes", + "bigIntIsInt64", + "bigIntGetInt64", + "bigIntSetInt64", + "bigIntAdd", + "bigIntSub", + "bigIntMul", + "bigIntTDiv", + "bigIntTMod", + "bigIntEDiv", + "bigIntEMod", + "bigIntSqrt", + "bigIntPow", + "bigIntLog2", + "bigIntAbs", + "bigIntNeg", + "bigIntSign", + "bigIntCmp", + "bigIntNot", + "bigIntAnd", + "bigIntOr", + "bigIntXor", + "bigIntShr", + "bigIntShl", + "bigIntFinishUnsigned", + "bigIntFinishSigned", + "bigIntToString", + "mBufferNew", + "mBufferNewFromBytes", + "mBufferGetLength", + "mBufferGetBytes", + "mBufferGetByteSlice", + "mBufferCopyByteSlice", + "mBufferEq", + "mBufferSetBytes", + "mBufferSetByteSlice", + "mBufferAppend", + "mBufferAppendBytes", + "mBufferToBigIntUnsigned", + "mBufferToBigIntSigned", + "mBufferFromBigIntUnsigned", + "mBufferFromBigIntSigned", + "mBufferToSmallIntUnsigned", + "mBufferToSmallIntSigned", + "mBufferFromSmallIntUnsigned", + "mBufferFromSmallIntSigned", + "mBufferToBigFloat", + "mBufferFromBigFloat", + "mBufferStorageStore", + "mBufferStorageLoad", + "mBufferStorageLoadFromAddress", + "mBufferGetArgument", + "mBufferFinish", + "mBufferSetRandom", + "managedMapNew", + "managedMapPut", + "managedMapGet", + "managedMapRemove", + "managedMapContains", + "smallIntGetUnsignedArgument", + "smallIntGetSignedArgument", + "smallIntFinishUnsigned", + "smallIntFinishSigned", + "smallIntStorageStoreUnsigned", + "smallIntStorageStoreSigned", + "smallIntStorageLoadUnsigned", + "smallIntStorageLoadSigned", + "int64getArgument", + "int64finish", + "int64storageStore", + "int64storageLoad", + "sha256", + "managedSha256", + "keccak256", + "managedKeccak256", + "ripemd160", + "managedRipemd160", + "verifyBLS", + "managedVerifyBLS", + "verifyEd25519", + "managedVerifyEd25519", + "verifyCustomSecp256k1", + "managedVerifyCustomSecp256k1", + "verifySecp256k1", + "managedVerifySecp256k1", + "encodeSecp256k1DerSignature", + "managedEncodeSecp256k1DerSignature", + "addEC", + "doubleEC", + "isOnCurveEC", + "scalarBaseMultEC", + "managedScalarBaseMultEC", + "scalarMultEC", + "managedScalarMultEC", + "marshalEC", + "managedMarshalEC", + "marshalCompressedEC", + "managedMarshalCompressedEC", + "unmarshalEC", + "managedUnmarshalEC", + "unmarshalCompressedEC", + "managedUnmarshalCompressedEC", + "generateKeyEC", + "managedGenerateKeyEC", + "createEC", + "managedCreateEC", + "getCurveLengthEC", + "getPrivKeyByteLengthEC", + "ellipticCurveGetValues", + "managedVerifySecp256r1", + "managedVerifyBLSSignatureShare", + "managedVerifyBLSAggregatedSignature", +]; diff --git a/framework/meta/src/ei/ei_version.rs b/framework/meta-lib/src/ei/ei_version.rs similarity index 65% rename from framework/meta/src/ei/ei_version.rs rename to framework/meta-lib/src/ei/ei_version.rs index 513fb71a66..6ba2444a6e 100644 --- a/framework/meta/src/ei/ei_version.rs +++ b/framework/meta-lib/src/ei/ei_version.rs @@ -21,13 +21,19 @@ pub enum EIVersion { /// - more managed crypto hooks /// - big floats /// - some managed ESDT properties. - #[default] V1_2, - /// VM Hooks version planned to be released with VM 1.5 in Q2 2023. + /// Latest VM Hooks version, released with VM 1.5 in January 2024: https://multiversx.com/release/release-sirius-v1-6-7 /// /// It adds the new async call functionality (promises). + #[default] V1_3, + + /// Version to be released to mainnet in August 2024. + V1_4, + + /// Version planned for Q3 2024. + V1_5, } impl EIVersion { @@ -37,6 +43,8 @@ impl EIVersion { "1.1" => Some(EIVersion::V1_1), "1.2" => Some(EIVersion::V1_2), "1.3" => Some(EIVersion::V1_3), + "1.4" => Some(EIVersion::V1_4), + "1.5" => Some(EIVersion::V1_5), _ => None, } } @@ -47,6 +55,8 @@ impl EIVersion { EIVersion::V1_1 => "1.1", EIVersion::V1_2 => "1.2", EIVersion::V1_3 => "1.3", + EIVersion::V1_4 => "1.4", + EIVersion::V1_5 => "1.5", } } @@ -56,6 +66,8 @@ impl EIVersion { EIVersion::V1_1 => super::EI_1_1_NAMES, EIVersion::V1_2 => super::EI_1_2_NAMES, EIVersion::V1_3 => super::EI_1_3_NAMES, + EIVersion::V1_4 => super::EI_1_4_NAMES, + EIVersion::V1_5 => super::EI_1_5_NAMES, } } @@ -63,3 +75,18 @@ impl EIVersion { self.vm_hook_names().contains(&vm_hook_names) } } + +/// Parses an EIVersion, or returns None, if "ignore" was specifically stated. +pub fn parse_check_ei(ei: &Option) -> Option { + if let Some(ei_name) = ei { + if ei_name == "ignore" { + None + } else { + let ei_version = EIVersion::from_name(ei_name) + .unwrap_or_else(|| panic!("invalid EI version: {ei_name}")); + Some(ei_version) + } + } else { + Some(EIVersion::default()) + } +} diff --git a/framework/meta-lib/src/ei_check_json.rs b/framework/meta-lib/src/ei_check_json.rs new file mode 100644 index 0000000000..b655ab80c6 --- /dev/null +++ b/framework/meta-lib/src/ei_check_json.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; + +use crate::ei::EIVersion; + +#[derive(Serialize, Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub struct EiCheckJson { + #[serde(default)] + pub ei_version: String, + + #[serde(default)] + pub ok: bool, +} + +impl EiCheckJson { + pub fn new(check_ei: &Option, status: bool) -> Option { + if let Some(ei) = check_ei { + return Some(EiCheckJson { + ei_version: ei.name().to_string(), + ok: status, + }); + } + + None + } +} 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..61125711ca --- /dev/null +++ b/framework/meta-lib/src/lib.rs @@ -0,0 +1,19 @@ +pub mod abi_json; +pub mod cargo_toml_contents; +pub mod cli; +pub mod code_report_json; +pub mod contract; +pub mod ei; +pub mod ei_check_json; +pub mod esdt_attr_file_json; +pub mod mxsc_file_json; +pub mod print_util; +pub 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 87% rename from framework/meta/src/mxsc_file_json.rs rename to framework/meta-lib/src/mxsc_file_json.rs index b2181fa6e1..84a60d0afa 100644 --- a/framework/meta/src/mxsc_file_json.rs +++ b/framework/meta-lib/src/mxsc_file_json.rs @@ -1,15 +1,18 @@ use serde::{Deserialize, Serialize}; use std::{fs::File, io::Write, path::Path}; -use crate::abi_json::{BuildInfoAbiJson, ContractAbiJson}; +use crate::{ + abi_json::{BuildInfoAbiJson, ContractAbiJson}, + report_info_json::ReportInfoJson, +}; #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct MxscFileJson { pub build_info: BuildInfoAbiJson, pub abi: ContractAbiJson, - pub size: usize, pub code: String, + pub report: ReportInfoJson, } pub fn serialize_mxsc_file_json(mxsc_file_json: &MxscFileJson) -> String { diff --git a/framework/meta/src/print_util.rs b/framework/meta-lib/src/print_util.rs similarity index 75% rename from framework/meta/src/print_util.rs rename to framework/meta-lib/src/print_util.rs index 888951f829..e79df4f60b 100644 --- a/framework/meta/src/print_util.rs +++ b/framework/meta-lib/src/print_util.rs @@ -2,6 +2,13 @@ use std::process::Command; use colored::Colorize; +/// Just for convenience, since we seem to be printing many things in green. +/// +/// The argument is of type `String` because the argument is always a `format!` expression. +pub fn println_green(s: String) { + println!("{}", s.green()); +} + pub fn format_command(command: &Command) -> String { let mut result = String::new(); for (key, opt_value) in command.get_envs() { @@ -41,18 +48,15 @@ pub fn print_copy_contract(source_wasm_path: &str, output_wasm_path: &str) { } pub fn print_call_wasm_opt(wasm_path: &str) { - println!("{}", format!("Calling wasm-opt on {wasm_path} ...").green(),); + println_green(format!("Calling wasm-opt on {wasm_path} ...")); } pub fn print_call_wasm2wat(wasm_path: &str, wat_path: &str) { - println!( - "{}", - format!("Extracting wat from {wasm_path} to {wat_path} ...").green(), - ); + println_green(format!("Extracting wat from {wasm_path} to {wat_path} ...")); } pub fn print_pack_mxsc_file(output_mxsc_path: &str) { - println!("{}", format!("Packing {output_mxsc_path} ...").green(),); + println_green(format!("Packing {output_mxsc_path} ...")); } pub fn print_contract_size(size: usize) { @@ -60,10 +64,7 @@ pub fn print_contract_size(size: usize) { } pub fn print_extract_imports(imports_path: &str) { - println!( - "{}", - format!("Extracting imports to {imports_path} ...").green(), - ); + println_green(format!("Extracting imports to {imports_path} ...")); } pub fn print_check_ei(ei_version: &str) { @@ -89,3 +90,9 @@ pub fn print_check_ei_ok() { pub fn print_ignore_ei_check() { println!("{}", "EI version check explicitly ignored".yellow(),); } + +pub fn print_workspace_target_dir(target_path_str: &str) { + println_green(format!( + "Using workspace target directory: {target_path_str} ..." + )); +} diff --git a/framework/meta-lib/src/report_info_json.rs b/framework/meta-lib/src/report_info_json.rs new file mode 100644 index 0000000000..3ebbda0690 --- /dev/null +++ b/framework/meta-lib/src/report_info_json.rs @@ -0,0 +1,38 @@ +use serde::{Deserialize, Serialize}; + +use crate::{code_report_json::CodeReportJson, ei_check_json::EiCheckJson, tools::WasmInfo}; + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ReportInfoJson { + #[serde(default)] + #[serde(skip_serializing_if = "Vec::is_empty")] + pub imports: Vec, + + #[serde(default)] + pub is_mem_grow: bool, + + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + pub ei_check: Option, + + #[serde(default)] + pub code_report: CodeReportJson, +} + +impl ReportInfoJson { + pub fn new(wasm_info: &WasmInfo, ei_check_info: Option, size: usize) -> Self { + let ei_check = if wasm_info.imports.is_empty() { + None + } else { + ei_check_info + }; + + ReportInfoJson { + imports: wasm_info.imports.iter().map(|i| i.to_string()).collect(), + is_mem_grow: wasm_info.memory_grow_flag, + ei_check, + code_report: CodeReportJson::new(&wasm_info.report, size), + } + } +} diff --git a/framework/meta/src/tools.rs b/framework/meta-lib/src/tools.rs similarity index 78% rename from framework/meta/src/tools.rs rename to framework/meta-lib/src/tools.rs index c3bd3e6c84..e0a8962d9b 100644 --- a/framework/meta/src/tools.rs +++ b/framework/meta-lib/src/tools.rs @@ -1,15 +1,18 @@ +mod find_workspace; mod git_describe; +pub(crate) mod report_creator; pub mod twiggy; -mod wasm_imports; +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_imports::extract_wasm_imports; +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-lib/src/tools/find_workspace.rs b/framework/meta-lib/src/tools/find_workspace.rs new file mode 100644 index 0000000000..4a3b53c90f --- /dev/null +++ b/framework/meta-lib/src/tools/find_workspace.rs @@ -0,0 +1,27 @@ +use std::path::{Path, PathBuf}; + +/// Finds the workspace by searching for the workspace argument into the project's cargo. +/// Works in debug mode too. +/// +pub fn find_workspace(path: &Path) -> Option { + if let Ok(output) = std::process::Command::new(env!("CARGO")) + .current_dir(path) + .arg("locate-project") + .arg("--workspace") + .arg("--message-format=plain") + .output() + { + if let Ok(convert) = std::str::from_utf8(&output.stdout) { + let path = Path::new(convert.trim()); + if let Some(parent) = path.parent() { + return Some(parent.to_path_buf()); + } + } + } + + None +} + +pub fn find_current_workspace() -> Option { + find_workspace(&std::env::current_dir().unwrap()) +} 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-lib/src/tools/report_creator.rs b/framework/meta-lib/src/tools/report_creator.rs new file mode 100644 index 0000000000..37af10fa4e --- /dev/null +++ b/framework/meta-lib/src/tools/report_creator.rs @@ -0,0 +1,10 @@ +pub const WITH_MESSAGE: &str = "with message"; +pub const WITHOUT_MESSAGE: &str = "without message"; + +pub struct ReportCreator { + pub path: String, + pub has_allocator: bool, + pub has_panic: String, +} + +impl ReportCreator {} 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-lib/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs new file mode 100644 index 0000000000..50d5b78aff --- /dev/null +++ b/framework/meta-lib/src/tools/wasm_extractor.rs @@ -0,0 +1,183 @@ +use colored::Colorize; +use std::fs; +use wasmparser::{ + BinaryReaderError, DataSectionReader, FunctionBody, ImportSectionReader, Parser, Payload, +}; + +use crate::ei::EIVersion; + +use super::report_creator::{ReportCreator, WITHOUT_MESSAGE, WITH_MESSAGE}; + +const PANIC_WITH_MESSAGE: &[u8; 16] = b"panic occurred: "; +const PANIC_WITHOUT_MESSAGE: &[u8; 14] = b"panic occurred"; +const ERROR_FAIL_ALLOCATOR: &[u8; 27] = b"memory allocation forbidden"; +const MEMORY_GROW_OPCODE: u8 = 0x40; + +pub struct WasmInfo { + pub imports: Vec, + pub ei_check: bool, + pub memory_grow_flag: bool, + pub has_format: bool, + pub report: ReportCreator, +} + +impl WasmInfo { + pub fn extract_wasm_info( + output_wasm_path: &str, + extract_imports_enabled: bool, + check_ei: &Option, + ) -> Result { + let wasm_data = fs::read(output_wasm_path) + .expect("error occured while extracting information from .wasm: file not found"); + + populate_wasm_info( + output_wasm_path.to_string(), + wasm_data, + extract_imports_enabled, + check_ei, + ) + } +} + +fn populate_wasm_info( + path: String, + wasm_data: Vec, + extract_imports_enabled: bool, + check_ei: &Option, +) -> Result { + let mut imports = Vec::new(); + let mut allocator_trigger = false; + let mut ei_check = false; + let mut memory_grow_flag = false; + let mut has_panic = "none"; + + let parser = Parser::new(0); + for payload in parser.parse_all(&wasm_data) { + match payload? { + Payload::ImportSection(import_section) => { + imports = extract_imports(import_section, extract_imports_enabled); + ei_check = is_ei_valid(imports.clone(), check_ei); + }, + Payload::DataSection(data_section) => { + allocator_trigger = is_fail_allocator_triggered(data_section.clone()); + if is_panic_with_message_triggered(data_section.clone()) { + has_panic = WITH_MESSAGE; + } else if is_panic_without_message_triggered(data_section) { + has_panic = WITHOUT_MESSAGE; + } + }, + Payload::CodeSectionEntry(code_section) => { + memory_grow_flag = is_mem_grow(code_section); + }, + _ => (), + } + } + + let report = ReportCreator { + path, + has_allocator: allocator_trigger, + has_panic: has_panic.to_string(), + }; + + Ok(WasmInfo { + imports, + ei_check, + memory_grow_flag, + has_format: true, + report, + }) +} + +fn is_fail_allocator_triggered(data_section: DataSectionReader) -> bool { + for data_fragment in data_section.into_iter().flatten() { + if data_fragment + .data + .windows(ERROR_FAIL_ALLOCATOR.len()) + .any(|data| data == ERROR_FAIL_ALLOCATOR) + { + println!( + "{}", + "FailAllocator used while memory allocation is accessible in code. Contract may fail unexpectedly when memory allocation is attempted" + .to_string() + .red() + .bold() + ); + return true; + } + } + + false +} + +fn is_panic_with_message_triggered(data_section: DataSectionReader) -> bool { + for data_fragment in data_section.into_iter().flatten() { + if data_fragment + .data + .windows(PANIC_WITH_MESSAGE.len()) + .any(|data| data == PANIC_WITH_MESSAGE) + { + return true; + } + } + + false +} + +fn is_panic_without_message_triggered(data_section: DataSectionReader) -> bool { + for data_fragment in data_section.into_iter().flatten() { + if data_fragment + .data + .windows(PANIC_WITHOUT_MESSAGE.len()) + .any(|data| data == PANIC_WITHOUT_MESSAGE) + { + return true; + } + } + + false +} + +pub fn extract_imports( + import_section: ImportSectionReader, + import_extraction_enabled: bool, +) -> Vec { + if !import_extraction_enabled { + return Vec::new(); + } + + let mut import_names = Vec::new(); + for import in import_section.into_iter().flatten() { + import_names.push(import.name.to_string()); + } + + import_names.sort(); + + import_names +} + +fn is_ei_valid(imports: Vec, check_ei: &Option) -> bool { + if let Some(ei) = check_ei { + let mut num_errors = 0; + for import in imports { + if !ei.contains_vm_hook(import.as_str()) { + num_errors += 1; + } + } + + if num_errors == 0 { + return true; + } + } + + false +} + +fn is_mem_grow(code_section: FunctionBody) -> bool { + let mut code = code_section.get_binary_reader(); + while code.bytes_remaining() > 0 { + if code.read_u8().unwrap() == MEMORY_GROW_OPCODE { + return true; + } + } + false +} 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-lib/src/version.rs b/framework/meta-lib/src/version.rs new file mode 100644 index 0000000000..d4cf732e81 --- /dev/null +++ b/framework/meta-lib/src/version.rs @@ -0,0 +1,80 @@ +use core::fmt; +use std::cmp::Ordering; + +use semver::{BuildMetadata, Prerelease, Version}; + +#[derive(Debug, Clone, Eq)] +pub struct FrameworkVersion { + pub version: Version, +} + +impl FrameworkVersion { + pub const fn new(major: u64, minor: u64, patch: u64) -> Self { + let version = Version { + major, + minor, + patch, + pre: Prerelease::EMPTY, + build: BuildMetadata::EMPTY, + }; + + FrameworkVersion { version } + } + + pub const fn from_triple(triple: (u64, u64, u64)) -> Self { + let (major, minor, patch) = triple; + FrameworkVersion::new(major, minor, patch) + } + + pub fn from_string_template(version_str: &str) -> Self { + let version_arr: Vec<&str> = version_str.split('.').collect(); + + let major: u64 = version_arr[0].parse().unwrap(); + let minor: u64 = version_arr[1].parse().unwrap(); + let patch: u64 = version_arr[2].parse().unwrap(); + + FrameworkVersion::new(major, minor, patch) + } +} + +impl Ord for FrameworkVersion { + fn cmp(&self, other: &Self) -> Ordering { + self.version.cmp(&other.version) + } +} + +impl PartialOrd for FrameworkVersion { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialEq for FrameworkVersion { + fn eq(&self, other: &Self) -> bool { + self.version == other.version + } +} + +impl fmt::Display for FrameworkVersion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.version) + } +} + +pub fn is_sorted(versions: &[FrameworkVersion]) -> bool { + versions.windows(2).all(|window| (window[0] < window[1])) +} + +#[macro_export] +macro_rules! framework_version { + ($arg:expr) => { + FrameworkVersion::from_triple(multiversx_sc::derive::semver_tuple!($arg)) + }; +} + +#[macro_export] +macro_rules! framework_versions { + ($($arg:expr),+ $(,)?) => { + &[$(framework_version!($arg)),+] + }; +} diff --git a/framework/meta-lib/src/version_history.rs b/framework/meta-lib/src/version_history.rs new file mode 100644 index 0000000000..c7fab1162b --- /dev/null +++ b/framework/meta-lib/src/version_history.rs @@ -0,0 +1,245 @@ +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.53.0); + +/// Indicates where to stop with the upgrades. +pub const LAST_UPGRADE_VERSION: FrameworkVersion = LAST_VERSION; + +pub const LAST_TEMPLATE_VERSION: FrameworkVersion = LAST_VERSION; + +#[rustfmt::skip] +/// Known versions for the upgrader. +pub const VERSIONS: &[FrameworkVersion] = framework_versions![ + 0.28.0, + 0.29.0, + 0.29.2, + 0.29.3, + 0.30.0, + 0.31.0, + 0.31.1, + 0.32.0, + 0.33.0, + 0.33.1, + 0.34.0, + 0.34.1, + 0.35.0, + 0.36.0, + 0.36.1, + 0.37.0, + 0.38.0, + 0.39.0, + 0.39.1, + 0.39.2, + 0.39.3, + 0.39.4, + 0.39.5, + 0.39.6, + 0.39.7, + 0.39.8, + 0.40.0, + 0.40.1, + 0.41.0, + 0.41.1, + 0.41.2, + 0.41.3, + 0.42.0, + 0.43.0, + 0.43.1, + 0.43.2, + 0.43.3, + 0.43.4, + 0.43.5, + 0.44.0, + 0.45.0, + 0.45.2, + 0.46.0, + 0.46.1, + 0.47.0, + 0.47.1, + 0.47.2, + 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.50.4, + 0.50.5, + 0.50.6, + 0.51.0, + 0.51.1, + 0.52.0, + 0.52.1, + 0.52.2, + 0.52.3, + 0.53.0, +]; + +#[rustfmt::skip] +pub const CHECK_AFTER_UPGRADE_TO: &[FrameworkVersion] = framework_versions![ + 0.28.0, + 0.29.0, + 0.30.0, + 0.31.0, + 0.32.0, + 0.33.0, + 0.34.0, + 0.35.0, + 0.36.0, + 0.37.0, + 0.40.0, + 0.41.0, + 0.42.0, + 0.43.0, + 0.44.0, + 0.45.2, + 0.46.0, + 0.47.0, + 0.49.0, + 0.50.6, + 0.51.1, + 0.52.3, + 0.53.0, +]; + +pub const LOWER_VERSION_WITH_TEMPLATE_TAG: FrameworkVersion = framework_version!(0.43.0); +pub const LOWER_VERSION_WITH_AUTOGENERATED_JSON: FrameworkVersion = framework_version!(0.44.0); +pub const LOWER_VERSION_WITH_AUTOGENERATED_WASM: FrameworkVersion = framework_version!(0.45.0); + +pub fn parse_known_version(tag_str: &str) -> FrameworkVersion { + let tag: FrameworkVersion = FrameworkVersion::from_string_template(tag_str); + if VERSIONS.contains(&tag) { + tag + } else { + panic!("Version unknown") + } +} + +/// We started supporting contract templates with version 0.43.0. +pub fn validate_template_tag(tag_str: &str) -> bool { + let tag: FrameworkVersion = parse_known_version(tag_str); + + tag >= LOWER_VERSION_WITH_TEMPLATE_TAG +} + +pub fn is_template_with_autogenerated_wasm(tag: FrameworkVersion) -> bool { + tag >= LOWER_VERSION_WITH_AUTOGENERATED_WASM +} + +pub fn is_template_with_autogenerated_json(tag: FrameworkVersion) -> bool { + tag >= LOWER_VERSION_WITH_AUTOGENERATED_JSON +} + +pub fn find_version_by_str(tag: &str) -> Option<&FrameworkVersion> { + VERSIONS.iter().find(|&v| v.to_string() == tag) +} + +pub struct VersionIterator { + next_version: usize, + last_version: FrameworkVersion, +} + +impl VersionIterator { + fn is_last_version(&self, version: &FrameworkVersion) -> bool { + self.last_version == *version + } +} + +impl Iterator for VersionIterator { + type Item = (&'static FrameworkVersion, &'static FrameworkVersion); + + fn next(&mut self) -> Option { + if self.next_version > 0 && self.next_version < VERSIONS.len() { + let from_version = &VERSIONS[self.next_version - 1]; + + if self.is_last_version(from_version) { + None + } else { + let to_version = &VERSIONS[self.next_version]; + let result = (from_version, to_version); + self.next_version += 1; + Some(result) + } + } else { + None + } + } +} + +pub fn versions_iter(last_version: FrameworkVersion) -> VersionIterator { + VersionIterator { + next_version: 1, + last_version, + } +} + +#[cfg(test)] +pub mod tests { + + use crate::version::is_sorted; + + use super::*; + + #[test] + fn compare_versions_test() { + let f1: FrameworkVersion = framework_version!(0.44.0); + let f2: FrameworkVersion = framework_version!(0.41.2); + + assert!(f1 > f2); + } + + #[test] + fn framework_version_display_test() { + assert_eq!(format!("Framework: {}", VERSIONS[0]), "Framework: 0.28.0"); + } + + #[test] + fn template_versions_test() { + assert!(validate_template_tag("0.43.0")); + assert!(!validate_template_tag("0.42.0")); + } + + #[test] + fn template_versions_with_autogenerated_wasm_test() { + assert!(is_template_with_autogenerated_wasm(framework_version!( + 0.45.0 + ))); + assert!(!is_template_with_autogenerated_wasm(framework_version!( + 0.44.0 + ))); + } + + #[test] + fn template_versions_with_autogenerated_json_test() { + assert!(is_template_with_autogenerated_json(framework_version!( + 0.44.0 + ))); + assert!(!is_template_with_autogenerated_json(framework_version!( + 0.43.0 + ))); + } + + #[test] + fn find_version_by_str_test() { + let version = find_version_by_str("0.28.0"); + match version { + Some(v) => assert_eq!(VERSIONS[0], *v), + None => unreachable!(), + } + } + + #[test] + fn framework_version_test() { + assert!(is_sorted(VERSIONS)); + } +} diff --git a/framework/meta/tests/ei_test.rs b/framework/meta-lib/tests/ei_test.rs similarity index 76% rename from framework/meta/tests/ei_test.rs rename to framework/meta-lib/tests/ei_test.rs index 8ea4442b43..78df88fe3e 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; @@ -74,6 +74,27 @@ pub const EI_1_3_ADDED_NAMES: &[&str] = &[ "managedIsBuiltinFunction", ]; +pub const EI_1_4_ADDED_NAMES: &[&str] = &[ + "isReservedFunctionName", + "managedGetOriginalCallerAddr", + "managedGetRelayerAddr", + "managedMultiTransferESDTNFTExecuteByUser", + "managedVerifySecp256r1", + "managedVerifyBLSSignatureShare", + "managedVerifyBLSAggregatedSignature", +]; + +pub const EI_1_5_ADDED_NAMES: &[&str] = &[ + "getRoundTime", + "epochStartBlockTimeStamp", + "epochStartBlockNonce", + "epochStartBlockRound", + "mBufferToSmallIntUnsigned", + "mBufferToSmallIntSigned", + "mBufferFromSmallIntUnsigned", + "mBufferFromSmallIntSigned", +]; + fn list_to_set<'a>(list: &[&'a str]) -> HashSet<&'a str> { let mut set = HashSet::new(); for &item in list { @@ -109,3 +130,13 @@ fn test_added_names_ei_1_2() { fn test_added_names_ei_1_3() { test_added_names(ei::EI_1_2_NAMES, EI_1_3_ADDED_NAMES, ei::EI_1_3_NAMES); } + +#[test] +fn test_added_names_ei_1_4() { + test_added_names(ei::EI_1_3_NAMES, EI_1_4_ADDED_NAMES, ei::EI_1_4_NAMES); +} + +#[test] +fn test_added_names_ei_1_5() { + test_added_names(ei::EI_1_4_NAMES, EI_1_5_ADDED_NAMES, ei::EI_1_5_NAMES); +} diff --git a/framework/meta/tests/multi_contract_test.rs b/framework/meta-lib/tests/multi_contract_test.rs similarity index 96% rename from framework/meta/tests/multi_contract_test.rs rename to framework/meta-lib/tests/multi_contract_test.rs index 7a7959fd21..4f2f20bdee 100644 --- a/framework/meta/tests/multi_contract_test.rs +++ b/framework/meta-lib/tests/multi_contract_test.rs @@ -1,7 +1,7 @@ use multiversx_sc::abi::{ContractAbi, EndpointAbi}; -use multiversx_sc_meta::cmd::contract::sc_config::{MultiContractConfigSerde, ScConfig}; +use multiversx_sc_meta_lib::contract::sc_config::{ScConfig, ScConfigSerde}; -fn get_serialized_toml() -> MultiContractConfigSerde { +fn get_serialized_toml() -> ScConfigSerde { toml::from_str( r#" [settings] diff --git a/framework/meta/Cargo.toml b/framework/meta/Cargo.toml index 715d0d974f..0b7af9bb63 100644 --- a/framework/meta/Cargo.toml +++ b/framework/meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-meta" -version = "0.44.0" +version = "0.53.0" edition = "2021" authors = [ @@ -12,44 +12,44 @@ 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 = [] [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.116.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" +bip39 = "2.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.53.0" +path = "../meta-lib" [dependencies.multiversx-sc] -version = "=0.44.0" +version = "=0.53.0" path = "../base" -features = ["alloc", "num-bigint", "promises"] +features = ["alloc", "num-bigint"] -[dev-dependencies] -multiversx-sc-meta = { path = ".", features = ["standalone"] } +[dependencies.multiversx-sc-snippets] +version = "=0.53.0" +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 55% rename from framework/meta/src/cli_args/cli_args_standalone.rs rename to framework/meta/src/cli/cli_args_standalone.rs index dab29f2119..ce2c3b66a6 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,24 +47,43 @@ 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), #[command(name = "templates", about = "Lists all pre-existing templates")] TemplateList(TemplateListArgs), + #[command( name = "test-gen", about = "Generates Rust integration tests based on scenarios provided in the scenarios folder of each contract." )] TestGen(TestGenArgs), + #[command(name = "test", about = "Runs cargo test")] Test(TestArgs), + + #[command(name = "test-coverage", about = "Run test coverage and output report")] + TestCoverage(TestCoverageArgs), + + #[command(name = "report", about = "Generate code report")] + CodeReportGen(CodeReportArgs), + + #[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), + + #[command( + name = "wallet", + about = "Generates a new wallet or performs actions on an existing wallet." + )] + Wallet(WalletArgs), } #[derive(Default, Clone, PartialEq, Eq, Debug, Args)] @@ -95,6 +116,96 @@ pub struct TestArgs { /// If scen and go are both specified, scen overrides the go argument. #[arg(short, long, default_value = "false", verbatim_doc_comment)] pub scen: bool, + + /// This arg prints the entire output of the vm. + /// Default value will be "false" if not specified + #[arg(short, long, default_value = "false", verbatim_doc_comment)] + pub nocapture: bool, +} + +#[derive(Default, Clone, PartialEq, Eq, Debug, ValueEnum)] +pub enum OutputFormat { + /// 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(Clone, PartialEq, Eq, Debug, Args)] +pub struct CodeReportArgs { + #[command(subcommand)] + pub command: CodeReportAction, +} + +#[derive(Clone, PartialEq, Eq, Debug, Subcommand)] +pub enum CodeReportAction { + #[command(name = "compile", about = "Generates the contract report.")] + Compile(CompileArgs), + + #[command(name = "compare", about = "Compare two contract reports.")] + Compare(CompareArgs), + + #[command( + name = "convert", + about = "Converts a contract report to a Markdown file." + )] + Convert(ConvertArgs), +} + +#[derive(Clone, PartialEq, Eq, Debug, Args)] +pub struct CompileArgs { + /// Target directory where to generate code report. + #[arg(short, long, verbatim_doc_comment)] + pub path: PathBuf, + + /// Path to the Markdown or JSON file where the report results will be written. + #[arg(short, long, verbatim_doc_comment)] + pub output: PathBuf, +} + +#[derive(Clone, PartialEq, Eq, Debug, Args)] +pub struct CompareArgs { + /// Path to the previous version of code report JSON file + /// that will be used for comparison. + #[arg(short, long, verbatim_doc_comment)] + pub baseline: PathBuf, + + /// Path to the current version of the code report JSON file + /// that will be compared. + #[arg(short, long, verbatim_doc_comment)] + pub new: PathBuf, + + /// Path to the Markdown file where the comparison results will be written. + #[arg(short, long, verbatim_doc_comment)] + pub output: PathBuf, +} + +#[derive(Clone, PartialEq, Eq, Debug, Args)] +pub struct ConvertArgs { + /// Path to the JSON report file that needs to be converted to Markdown format. + #[arg(short, long, verbatim_doc_comment)] + pub input: PathBuf, + + /// Path to the Markdown file where the report results will be written. + #[arg(short, long, verbatim_doc_comment)] + pub output: PathBuf, } #[derive(Default, Clone, PartialEq, Eq, Debug, Args)] @@ -185,6 +296,10 @@ pub struct UpgradeArgs { /// By default it will be the last version out. #[arg(long = "to", verbatim_doc_comment)] pub override_target_version: Option, + + /// Skips 'cargo check' after upgrade + #[arg(short, long, default_value = "false", verbatim_doc_comment)] + pub no_check: bool, } #[derive(Default, Clone, PartialEq, Eq, Debug, Args)] @@ -219,6 +334,11 @@ pub struct TemplateArgs { /// Will be current directory if not specified. #[arg(long, verbatim_doc_comment)] pub path: Option, + + /// The author of the contract. + /// If missing, the default author will be considered. + #[arg(long, verbatim_doc_comment)] + pub author: Option, } impl CliArgsToRaw for TemplateArgs { @@ -250,3 +370,105 @@ pub struct TestGenArgs { #[arg(long, verbatim_doc_comment)] pub create: bool, } + +#[derive(Default, PartialEq, Eq, Debug, Clone, Parser)] +#[command(propagate_version = true)] +pub struct InstallArgs { + #[command(subcommand)] + pub command: Option, +} + +#[derive(Clone, PartialEq, Eq, Debug, Subcommand)] +pub enum InstallCommand { + #[command(about = "Installs all the known tools")] + All, + + #[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)] +pub struct InstallMxScenarioGoArgs { + /// The framework version on which the contracts should be created. + #[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, +} + +#[derive(Clone, PartialEq, Eq, Debug, Subcommand)] +pub enum WalletAction { + #[command(name = "new", about = "Creates a new wallet")] + New(WalletNewArgs), + + #[command( + name = "bech32", + about = "Encodes/decodes a bech32 address to/from hex" + )] + Bech32(WalletBech32Args), + #[command(name = "convert", about = "Converts a wallet")] + Convert(WalletConvertArgs), +} + +#[derive(Clone, PartialEq, Eq, Debug, Parser)] +#[command(propagate_version = true)] +pub struct WalletArgs { + #[command(subcommand)] + pub command: WalletAction, +} + +#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] +pub struct WalletNewArgs { + /// The type of wallet to create. + #[arg(long = "format", verbatim_doc_comment)] + pub wallet_format: Option, + + /// The name of the wallet to create. + #[arg(long = "outfile", verbatim_doc_comment)] + pub outfile: Option, +} + +#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] +pub struct WalletConvertArgs { + #[arg(long = "in-format", verbatim_doc_comment)] + pub from: String, + + #[arg(long = "out-format", verbatim_doc_comment)] + pub to: String, + + #[arg(long = "infile", verbatim_doc_comment)] + pub infile: Option, + + #[arg(long = "outfile", verbatim_doc_comment)] + pub outfile: Option, +} + +#[derive(Default, Clone, PartialEq, Eq, Debug, Args)] +pub struct WalletBech32Args { + #[arg(long = "encode", verbatim_doc_comment)] + pub hex_address: Option, + #[arg(long = "decode", verbatim_doc_comment)] + pub bech32_address: Option, +} diff --git a/framework/meta/src/cli/cli_standalone_main.rs b/framework/meta/src/cli/cli_standalone_main.rs new file mode 100644 index 0000000000..c749ff0056 --- /dev/null +++ b/framework/meta/src/cli/cli_standalone_main.rs @@ -0,0 +1,55 @@ +use crate::cli::{StandaloneCliAction, StandaloneCliArgs}; +use crate::cmd::retrieve_address::retrieve_address; +use crate::cmd::wallet::wallet; +use clap::Parser; + +use crate::cmd::all::call_all_meta; +use crate::cmd::code_report::report; +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 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::Template(args)) => { + create_contract(args); + }, + Some(StandaloneCliAction::TemplateList(args)) => { + print_template_names(args); + }, + Some(StandaloneCliAction::TestGen(args)) => { + test_gen_tool(args); + }, + Some(StandaloneCliAction::Test(args)) => test(args), + Some(StandaloneCliAction::TestCoverage(args)) => { + test_coverage(args); + }, + Some(StandaloneCliAction::CodeReportGen(args)) => { + report(args); + }, + Some(StandaloneCliAction::Account(args)) => { + retrieve_address(args).await; + }, + Some(StandaloneCliAction::LocalDeps(args)) => { + local_deps(args); + }, + Some(StandaloneCliAction::Wallet(args)) => { + wallet(args); + }, + None => {}, + } +} diff --git a/framework/meta/src/cmd.rs b/framework/meta/src/cmd.rs index 7ec72dd6f2..3263d36688 100644 --- a/framework/meta/src/cmd.rs +++ b/framework/meta/src/cmd.rs @@ -1,4 +1,13 @@ -pub mod contract; - -#[cfg(feature = "standalone")] -pub mod standalone; +pub mod all; +pub mod code_report; +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; +pub mod wallet; 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/code_report.rs b/framework/meta/src/cmd/code_report.rs new file mode 100644 index 0000000000..47e51948f0 --- /dev/null +++ b/framework/meta/src/cmd/code_report.rs @@ -0,0 +1,15 @@ +pub mod compare; +pub mod generate_report; +pub mod render_code_report; + +use generate_report::{compare_report, convert_report, create_report}; + +use crate::cli::{CodeReportAction, CodeReportArgs}; + +pub fn report(args: &CodeReportArgs) { + match &args.command { + CodeReportAction::Compile(compile_args) => create_report(compile_args), + CodeReportAction::Compare(compare_args) => compare_report(compare_args), + CodeReportAction::Convert(convert_args) => convert_report(convert_args), + } +} diff --git a/framework/meta/src/cmd/code_report/compare.rs b/framework/meta/src/cmd/code_report/compare.rs new file mode 100644 index 0000000000..28c604962d --- /dev/null +++ b/framework/meta/src/cmd/code_report/compare.rs @@ -0,0 +1,47 @@ +pub(crate) fn size_status_after_comparing(size: usize, compared_size: usize) -> String { + match size.cmp(&compared_size) { + std::cmp::Ordering::Greater => { + format!("{} :arrow_right: {} :red_circle:", compared_size, size) + }, + std::cmp::Ordering::Less => { + format!("{} :arrow_right: {} :green_circle:", compared_size, size) + }, + std::cmp::Ordering::Equal => { + format!("{}", size) + }, + } +} + +pub(crate) fn allocator_status_after_comparing( + has_allocator: bool, + compared_has_allocator: bool, +) -> String { + if compared_has_allocator == has_allocator { + return format!("{}", has_allocator); + } + + let allocator_status = format!("{} :arrow-right: {}", compared_has_allocator, has_allocator); + + if !has_allocator { + format!("{allocator_status} :green-circle:") + } else { + format!("{allocator_status} :red-circle:") + } +} + +pub(crate) fn panic_status_after_comparing( + has_panic: &String, + compared_has_panic: &String, +) -> String { + if has_panic == compared_has_panic { + return has_panic.to_string(); + } + + let panic_status = format!("{} :arrow-right: {}", compared_has_panic, has_panic); + + if has_panic == "none" { + return format!("{panic_status} :green-circle:"); + } + + panic_status +} diff --git a/framework/meta/src/cmd/code_report/generate_report.rs b/framework/meta/src/cmd/code_report/generate_report.rs new file mode 100644 index 0000000000..5c06b65295 --- /dev/null +++ b/framework/meta/src/cmd/code_report/generate_report.rs @@ -0,0 +1,159 @@ +use std::{ + fs::{read_dir, File}, + io::{BufReader, Write}, + path::{Path, PathBuf}, +}; + +use crate::{ + cli::{CompareArgs, CompileArgs, ConvertArgs}, + folder_structure::RelevantDirectories, +}; + +use multiversx_sc_meta_lib::{ + self, code_report_json::CodeReportJson, mxsc_file_json::MxscFileJson, +}; + +use super::render_code_report::CodeReportRender; + +const JSON: &str = ".json"; +const MD: &str = ".md"; + +pub fn compare_report(compare_args: &CompareArgs) { + if !is_path_ends_with(&compare_args.output, MD) { + panic!("Compare output is only available for Markdown file extension."); + } + + if !is_path_ends_with(&compare_args.baseline, JSON) + && !is_path_ends_with(&compare_args.new, JSON) + { + panic!("Compare baseline and new are only available for JSON file extension."); + } + + let mut output_file = create_file(&compare_args.output); + + let baseline_reports: Vec = match File::open(&compare_args.baseline) { + Ok(_) => extract_reports_from_json(&compare_args.baseline), + Err(_) => vec![], + }; + + let new_reports: Vec = extract_reports_from_json(&compare_args.new); + + let mut render_code_report = + CodeReportRender::new(&mut output_file, &baseline_reports, &new_reports); + render_code_report.compare_reports(); +} + +pub fn convert_report(convert_args: &ConvertArgs) { + if !is_path_ends_with(&convert_args.output, MD) { + panic!("Conversion output is only available for Markdown file extension"); + } + + if !is_path_ends_with(&convert_args.input, JSON) { + panic!("Conversion only available from JSON file extension"); + } + + let mut output_file = create_file(&convert_args.output); + + let reports: Vec = extract_reports_from_json(&convert_args.input); + + let mut convert_code_report = CodeReportRender::new_without_compare(&mut output_file, &reports); + + convert_code_report.render_report(); +} + +pub fn create_report(compile_args: &CompileArgs) { + if !is_path_ends_with(&compile_args.output, JSON) + && !is_path_ends_with(&compile_args.output, MD) + { + panic!("Create report is only available for Markdown or JSON output file.") + } + + let reports = generate_new_report(&compile_args.path); + + let mut file = create_file(&compile_args.output); + + if is_path_ends_with(&compile_args.output, MD) { + let mut render_code_report = CodeReportRender::new_without_compare(&mut file, &reports); + render_code_report.render_report(); + } else { + let json_output = serde_json::to_string(&reports).unwrap(); + file.write_all(json_output.as_bytes()).unwrap(); + } +} + +fn generate_new_report(path: &PathBuf) -> Vec { + let directors = RelevantDirectories::find_all(path, &["".to_owned()]); + + assemble_report_vec(directors) +} + +fn assemble_report_vec(directors: RelevantDirectories) -> Vec { + let mut reports: Vec = Vec::new(); + + for director in directors.iter() { + let output_path: PathBuf = director.path.join("output"); + + collect_reports(&output_path, &mut reports); + sanitize_output_path_from_report(&mut reports); + } + + reports +} + +fn find_mxsc_files(path: &PathBuf) -> Vec { + if !path.is_dir() { + return vec![]; + } + + let mut mxsc_files = Vec::new(); + for entry in read_dir(path).unwrap() { + let file_path = entry.unwrap().path(); + if file_path.to_str().unwrap().ends_with(".mxsc.json") { + mxsc_files.push(file_path); + } + } + + mxsc_files +} + +fn collect_reports(path: &PathBuf, reports: &mut Vec) { + for mxsc_path in find_mxsc_files(path) { + let mxsc_file = match File::open(mxsc_path) { + Ok(file) => file, + Err(_) => continue, + }; + let data: MxscFileJson = serde_json::from_reader(mxsc_file).unwrap(); + reports.push(data.report.code_report); + } +} + +fn create_file(file_path: &PathBuf) -> File { + File::create(file_path).expect("could not write report file") +} + +fn sanitize_output_path_from_report(reports: &mut [CodeReportJson]) { + reports.iter_mut().for_each(|report| { + report.path = report + .path + .split('/') + .last() + .unwrap_or(&report.path) + .to_string(); + }) +} + +fn is_path_ends_with(path: &Path, extension: &str) -> bool { + path.to_path_buf() + .into_os_string() + .into_string() + .unwrap() + .ends_with(extension) +} + +fn extract_reports_from_json(path: &PathBuf) -> Vec { + let file = + File::open(path).unwrap_or_else(|_| panic!("file with path {} not found", path.display())); + let reader = BufReader::new(file); + + serde_json::from_reader(reader).unwrap_or_else(|_| vec![]) +} diff --git a/framework/meta/src/cmd/code_report/render_code_report.rs b/framework/meta/src/cmd/code_report/render_code_report.rs new file mode 100644 index 0000000000..e6edcfae8e --- /dev/null +++ b/framework/meta/src/cmd/code_report/render_code_report.rs @@ -0,0 +1,122 @@ +use std::fmt::Display; + +pub struct CodeReportRender<'a> { + pub file: Option<&'a mut dyn std::io::Write>, + pub compared_reports: &'a [CodeReportJson], + pub reports: &'a [CodeReportJson], +} + +use multiversx_sc_meta_lib::code_report_json::CodeReportJson; + +use super::compare::{ + allocator_status_after_comparing, panic_status_after_comparing, size_status_after_comparing, +}; + +impl<'a> CodeReportRender<'a> { + pub fn new( + file: &'a mut dyn std::io::Write, + compared_reports: &'a [CodeReportJson], + reports: &'a [CodeReportJson], + ) -> Self { + Self { + file: Some(file), + compared_reports, + reports, + } + } + + pub fn new_without_compare( + file: &'a mut dyn std::io::Write, + reports: &'a [CodeReportJson], + ) -> Self { + Self { + file: Some(file), + compared_reports: &[], + reports, + } + } + + pub fn render_report(&mut self) { + self.render_header(); + + self.render_reports(); + } + + pub fn compare_reports(&mut self) { + self.render_header(); + + if self.compared_reports.is_empty() { + self.render_reports(); + self.writeln("\n:warning: Could not download the report for the base branch. Displaying only the report for the current branch. :warning:"); + } else { + self.render_report_and_compare(); + } + } + + fn writeln(&mut self, s: impl Display) { + let file = self.file.as_mut().unwrap(); + file.write_all(s.to_string().as_bytes()).unwrap(); + file.write_all(b"\n").unwrap(); + } + + fn write_report_for_contract( + &mut self, + path: &String, + size: &String, + has_allocator: &String, + has_panic: &String, + ) { + self.writeln(format!( + "| {} | {} | {} | {} |", + path.split('/').last().unwrap_or_else(|| path), + size, + has_allocator, + has_panic + )); + } + + fn render_header(&mut self) { + self.writeln("| Path                                                         |                                     size |                  has-allocator |                     has-format |"); + self.writeln("| :-- | --: | --: | --: |"); + } + + fn render_reports(&mut self) { + for report in self.reports { + self.write_report_for_contract( + &report.path, + &report.size.to_string(), + &report.has_allocator.to_string(), + &report.has_panic, + ); + } + } + + fn render_report_and_compare(&mut self) { + for report in self.reports.iter() { + if let Some(compared_report) = self + .compared_reports + .iter() + .find(|cr| cr.path == report.path) + { + self.print_compared_output(report, compared_report); + } + } + } + + fn print_compared_output(&mut self, report: &CodeReportJson, compared_report: &CodeReportJson) { + let size_report = size_status_after_comparing(report.size, compared_report.size); + + let has_allocator_report = + allocator_status_after_comparing(report.has_allocator, compared_report.has_allocator); + + let has_panic_report = + panic_status_after_comparing(&report.has_panic, &compared_report.has_panic); + + self.write_report_for_contract( + &report.path, + &size_report, + &has_allocator_report, + &has_panic_report, + ); + } +} 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/contract/sc_config.rs b/framework/meta/src/cmd/contract/sc_config.rs deleted file mode 100644 index e28adf5d01..0000000000 --- a/framework/meta/src/cmd/contract/sc_config.rs +++ /dev/null @@ -1,17 +0,0 @@ -mod multi_contract_serde; -mod oc_builder; -mod oc_config; -mod oc_global_config; -mod oc_settings; -mod oc_validate; -mod wasm_build; -mod wasm_clean; -mod wasm_crate_gen; -mod wasm_update; - -pub use multi_contract_serde::*; -pub use oc_builder::*; -pub use oc_config::ContractVariant; -pub use oc_global_config::ScConfig; -pub use oc_settings::ContractVariantSettings; -pub use wasm_build::*; diff --git a/framework/meta/src/cmd/contract/sc_config/oc_settings.rs b/framework/meta/src/cmd/contract/sc_config/oc_settings.rs deleted file mode 100644 index 91e8782154..0000000000 --- a/framework/meta/src/cmd/contract/sc_config/oc_settings.rs +++ /dev/null @@ -1,53 +0,0 @@ -mod oc_allocator; -mod oc_parse; -mod oc_parse_stack_size; - -pub use oc_allocator::ContractAllocator; -pub use oc_parse::*; -pub use oc_parse_stack_size::*; - -use crate::ei::EIVersion; - -use super::ContractVariantProfile; - -/// Collection of flags, specified in the multicontract config. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct ContractVariantSettings { - /// External view contracts are just readers of data from another contract. - pub external_view: bool, - - /// Panic messages add a lot of bloat to the final bytecode, - /// so they should only be used for debugging purposes. - pub panic_message: bool, - - /// Post-processing check of the VM hooks is based on this. - pub check_ei: Option, - - /// Allocator config, i.e which allocator to choose for the contract. - pub allocator: ContractAllocator, - - pub stack_size: usize, - - /// Features that are activated on the contract crate, from wasm. - pub features: Vec, - - /// Forcibly remove the original contrct legacy callback. - pub kill_legacy_callback: bool, - - pub contract_variant_profile: ContractVariantProfile, -} - -impl Default for ContractVariantSettings { - fn default() -> Self { - ContractVariantSettings { - external_view: Default::default(), - panic_message: Default::default(), - check_ei: Some(EIVersion::default()), - allocator: Default::default(), - stack_size: DEFAULT_STACK_SIZE, - features: Default::default(), - kill_legacy_callback: false, - contract_variant_profile: Default::default(), - } - } -} diff --git a/framework/meta/src/cmd/contract/sc_config/oc_settings/oc_parse.rs b/framework/meta/src/cmd/contract/sc_config/oc_settings/oc_parse.rs deleted file mode 100644 index b3fb5ef27d..0000000000 --- a/framework/meta/src/cmd/contract/sc_config/oc_settings/oc_parse.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::ei::EIVersion; - -use super::ContractAllocator; - -pub fn parse_check_ei(ei: &Option) -> Option { - if let Some(ei_name) = ei { - if ei_name == "ignore" { - None - } else { - let ei_version = EIVersion::from_name(ei_name) - .unwrap_or_else(|| panic!("invalid EI version: {ei_name}")); - Some(ei_version) - } - } else { - Some(EIVersion::default()) - } -} - -pub fn parse_allocator(allocator: &Option) -> ContractAllocator { - allocator - .as_ref() - .map(|s| ContractAllocator::parse_or_panic(s)) - .unwrap_or_default() -} diff --git a/framework/meta/src/cmd/standalone/info.rs b/framework/meta/src/cmd/info.rs similarity index 84% rename from framework/meta/src/cmd/standalone/info.rs rename to framework/meta/src/cmd/info.rs index c086a54de5..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, }; @@ -14,6 +14,6 @@ pub fn call_info(args: &InfoArgs) { let dirs = RelevantDirectories::find_all(path, args.ignore.as_slice()); dir_pretty_print(dirs.iter(), "", &|dir| { - print_tree_dir_metadata(dir, LAST_UPGRADE_VERSION) + print_tree_dir_metadata(dir, &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/install/install_scenario_go.rs b/framework/meta/src/cmd/install/install_scenario_go.rs new file mode 100644 index 0000000000..2351ab2621 --- /dev/null +++ b/framework/meta/src/cmd/install/install_scenario_go.rs @@ -0,0 +1,177 @@ +use serde_json::Value; +use std::{ + fs::File, + io::Write, + path::{Path, PathBuf}, +}; + +use multiversx_sc_meta_lib::print_util::println_green; + +use super::system_info::{get_system_info, SystemInfo}; + +const USER_AGENT: &str = "multiversx-sc-meta"; +const SCENARIO_CLI_RELEASES_BASE_URL: &str = + "https://api.github.com/repos/multiversx/mx-chain-scenario-cli-go/releases"; +const CARGO_HOME: &str = env!("CARGO_HOME"); + +#[derive(Clone, Debug)] +pub struct ScenarioGoRelease { + #[allow(dead_code)] + pub tag_name: String, + pub download_url: String, +} + +#[derive(Clone, Debug)] +pub struct ScenarioGoInstaller { + tag: Option, + zip_name: String, + user_agent: String, + temp_dir_path: PathBuf, + cargo_bin_folder: PathBuf, +} + +fn select_zip_name() -> String { + match get_system_info() { + SystemInfo::Linux => "mx_scenario_go_linux_amd64.zip".to_string(), + SystemInfo::MacOs => "mx_scenario_go_darwin_amd64.zip".to_string(), + } +} + +impl ScenarioGoInstaller { + pub fn new(tag: Option) -> Self { + let cargo_home = PathBuf::from(CARGO_HOME); + let cargo_bin_folder = cargo_home.join("bin"); + ScenarioGoInstaller { + tag, + zip_name: select_zip_name(), + user_agent: USER_AGENT.to_string(), + temp_dir_path: std::env::temp_dir(), + cargo_bin_folder, + } + } + + pub fn install(&self) { + let release_raw = self + .get_scenario_go_release_json() + .expect("couldn't retrieve mx-chain-scenario-cli-go release"); + + assert!( + !release_raw.contains("\"message\": \"Not Found\""), + "release not found: {release_raw}" + ); + + let release = self.parse_scenario_go_release(&release_raw); + self.download_zip(&release) + .expect("could not download artifact"); + + self.unzip_binaries(); + self.delete_temp_zip(); + } + + fn release_url(&self) -> String { + if let Some(tag) = &self.tag { + format!("{SCENARIO_CLI_RELEASES_BASE_URL}/tags/{tag}") + } else { + format!("{SCENARIO_CLI_RELEASES_BASE_URL}/latest") + } + } + + fn get_scenario_go_release_json(&self) -> Result { + let release_url = self.release_url(); + println_green(format!("Retrieving release info: {release_url}")); + + let response = reqwest::blocking::Client::builder() + .user_agent(&self.user_agent) + .build()? + .get(release_url) + .send()? + .text()?; + + Ok(response) + } + + fn parse_scenario_go_release(&self, raw_json: &str) -> ScenarioGoRelease { + let parsed: Value = serde_json::from_str(raw_json).unwrap(); + + let tag_name = parsed + .get("tag_name") + .expect("tag name not found") + .as_str() + .expect("malformed json"); + + let assets = parsed + .get("assets") + .expect("assets not found in release") + .as_array() + .expect("malformed json"); + + let zip_asset = assets + .iter() + .find(|asset| self.asset_is_zip(asset)) + .expect("executable zip asset not found in release"); + + let download_url = zip_asset + .get("browser_download_url") + .expect("asset download url not found") + .as_str() + .expect("asset download url not a string"); + + ScenarioGoRelease { + tag_name: tag_name.to_string(), + download_url: download_url.to_string(), + } + } + + fn asset_is_zip(&self, asset: &Value) -> bool { + let name = asset + .get("name") + .expect("asset name not found") + .as_str() + .expect("asset name not a string"); + name == self.zip_name + } + + fn zip_temp_path(&self) -> PathBuf { + self.temp_dir_path.join(&self.zip_name) + } + + fn download_zip(&self, release: &ScenarioGoRelease) -> Result<(), reqwest::Error> { + println_green(format!("Downloading binaries: {}", &release.download_url)); + let response = reqwest::blocking::Client::builder() + .user_agent(&self.user_agent) + .build()? + .get(&release.download_url) + .send()? + .bytes()?; + if response.len() < 10000 { + panic!( + "Could not download artifact: {}", + String::from_utf8_lossy(&response) + ); + } + + println_green(format!("Saving to: {}", self.zip_temp_path().display())); + let mut file = match File::create(self.zip_temp_path()) { + Err(why) => panic!("couldn't create {why}"), + Ok(file) => file, + }; + file.write_all(&response).unwrap(); + Ok(()) + } + + fn unzip_binaries(&self) { + println_green(format!("Unzipping to: {}", self.cargo_bin_folder.display())); + let file = File::open(self.zip_temp_path()).unwrap(); + let mut zip = zip::ZipArchive::new(file).unwrap(); + zip.extract(Path::new(&self.cargo_bin_folder)) + .expect("Could not unzip artifact"); + } + + fn delete_temp_zip(&self) { + println_green(format!( + "Deleting temporary download: {}", + self.zip_temp_path().display() + )); + std::fs::remove_file(self.zip_temp_path()).unwrap(); + } +} 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/install/system_info.rs b/framework/meta/src/cmd/install/system_info.rs new file mode 100644 index 0000000000..e789bcc021 --- /dev/null +++ b/framework/meta/src/cmd/install/system_info.rs @@ -0,0 +1,14 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum SystemInfo { + Linux, + MacOs, +} + +pub fn get_system_info() -> SystemInfo { + let os = std::env::consts::OS; + match os { + "linux" => SystemInfo::Linux, + "macos" => SystemInfo::MacOs, + _ => panic!("unknown configuration: {os}"), + } +} 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.rs b/framework/meta/src/cmd/standalone.rs deleted file mode 100644 index c675fb601e..0000000000 --- a/framework/meta/src/cmd/standalone.rs +++ /dev/null @@ -1,44 +0,0 @@ -mod all; -mod info; -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 clap::Parser; -use info::call_info; -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; - -/// Entry point in the program when calling it as a standalone tool. -pub fn cli_main_standalone() { - let cli_args = StandaloneCliArgs::parse(); - match &cli_args.command { - Some(StandaloneCliAction::Info(args)) => call_info(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); - }, - Some(StandaloneCliAction::TemplateList(args)) => { - print_template_names(args); - }, - Some(StandaloneCliAction::TestGen(args)) => { - test_gen_tool(args); - }, - Some(StandaloneCliAction::Test(args)) => test(args), - None => {}, - } -} diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_selector.rs b/framework/meta/src/cmd/standalone/upgrade/upgrade_selector.rs deleted file mode 100644 index 83c442d5ce..0000000000 --- a/framework/meta/src/cmd/standalone/upgrade/upgrade_selector.rs +++ /dev/null @@ -1,101 +0,0 @@ -use crate::{ - cli_args::UpgradeArgs, - folder_structure::{dir_pretty_print, RelevantDirectories, RelevantDirectory}, - version_history::{versions_iter, LAST_UPGRADE_VERSION, VERSIONS}, -}; - -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_common::{cargo_check, version_bump_in_cargo_toml}, - upgrade_print::*, -}; - -pub fn upgrade_sc(args: &UpgradeArgs) { - let path = if let Some(some_path) = &args.path { - some_path.as_str() - } else { - "./" - }; - - let last_version = args - .override_target_version - .clone() - .unwrap_or_else(|| LAST_UPGRADE_VERSION.to_string()); - - assert!( - VERSIONS.contains(&last_version.as_str()), - "Invalid requested version: {last_version}", - ); - - let mut dirs = RelevantDirectories::find_all(path, args.ignore.as_slice()); - println!( - "Found {} directories to upgrade, out of which {} are contract crates.\n", - dirs.len(), - dirs.iter_contract_crates().count(), - ); - dir_pretty_print(dirs.iter(), "", &|dir| { - print_tree_dir_metadata(dir, last_version.as_str()) - }); - - for (from_version, to_version) in versions_iter(last_version) { - if dirs.count_for_version(from_version) == 0 { - continue; - } - - print_upgrading_all(from_version, to_version); - dirs.start_upgrade(from_version, to_version); - for dir in dirs.iter_version(from_version) { - upgrade_function_selector(dir); - } - - for dir in dirs.iter_version(from_version) { - upgrade_post_processing(dir); - } - - // // change the version in memory for the next iteration (dirs is not reloaded from disk) - // dirs.update_versions_in_memory(from_version, to_version); - dirs.finish_upgrade(); - } -} - -fn upgrade_function_selector(dir: &RelevantDirectory) { - if dir.upgrade_in_progress.is_some() { - print_upgrading(dir); - } - - match dir.upgrade_in_progress { - Some((_, "0.31.0")) => { - upgrade_to_31_0(dir); - }, - Some((_, "0.32.0")) => { - upgrade_to_32_0(dir); - }, - Some((_, "0.39.0")) => { - upgrade_to_39_0(dir); - }, - Some((from_version, to_version)) => { - version_bump_in_cargo_toml(&dir.path, from_version, to_version); - }, - None => {}, - } -} - -fn upgrade_post_processing(dir: &RelevantDirectory) { - match dir.upgrade_in_progress { - Some((_, "0.28.0")) | Some((_, "0.29.0")) | Some((_, "0.30.0")) | Some((_, "0.31.0")) - | Some((_, "0.32.0")) | Some((_, "0.33.0")) | Some((_, "0.34.0")) | Some((_, "0.35.0")) - | Some((_, "0.36.0")) | Some((_, "0.37.0")) | Some((_, "0.40.0")) | Some((_, "0.44.0")) - | Some((_, "0.42.0")) | Some((_, "0.43.0")) => { - print_post_processing(dir); - cargo_check(dir); - }, - Some((_, "0.39.0")) => { - print_post_processing(dir); - postprocessing_after_39_0(dir); - cargo_check(dir); - }, - _ => {}, - } -} 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 70% rename from framework/meta/src/cmd/standalone/template/contract_creator.rs rename to framework/meta/src/cmd/template/contract_creator.rs index 5b7932492e..8483f3c8f8 100644 --- a/framework/meta/src/cmd/standalone/template/contract_creator.rs +++ b/framework/meta/src/cmd/template/contract_creator.rs @@ -1,5 +1,8 @@ +use convert_case::{Case, Casing}; + use crate::{ - cli_args::TemplateArgs, + cli::TemplateArgs, + version::FrameworkVersion, version_history::{validate_template_tag, LAST_TEMPLATE_VERSION}, }; @@ -11,16 +14,27 @@ use super::{ /// Creates a new contract on disk, from a template, given a name. pub fn create_contract(args: &TemplateArgs) { let version = get_repo_version(&args.tag); + let version_tag: FrameworkVersion = version.get_tag(); let repo_temp_download = RepoSource::download_from_github(version, std::env::temp_dir()); let target = target_from_args(args); - let creator = ContractCreator::new(&repo_temp_download, args.template.clone(), target, false); + let creator = ContractCreator::new( + &repo_temp_download, + args.template.clone(), + target, + false, + args.author.clone(), + ); - creator.create_contract(); + creator.create_contract(version_tag); } fn target_from_args(args: &TemplateArgs) -> ContractCreatorTarget { - let new_name = args.name.clone().unwrap_or_else(|| args.template.clone()); + let new_name = args + .name + .clone() + .unwrap_or_else(|| args.template.clone()) + .to_case(Case::Kebab); let target_path = args.path.clone().unwrap_or_default(); ContractCreatorTarget { target_path, @@ -51,6 +65,7 @@ impl<'a> ContractCreator<'a> { template_name: String, target: ContractCreatorTarget, keep_paths: bool, + new_author: Option, ) -> Self { let template_sources = template_sources(repo_source); let template_source = template_sources @@ -67,23 +82,24 @@ impl<'a> ContractCreator<'a> { metadata, target, keep_paths, + new_author, }, } } - pub fn create_contract(&self) { - self.copy_template(); - self.update_dependencies(); + pub fn create_contract(&self, args_tag: FrameworkVersion) { + self.copy_template(args_tag.clone()); + self.update_dependencies(args_tag); self.rename_template(); } - pub fn copy_template(&self) { + pub fn copy_template(&self, args_tag: FrameworkVersion) { self.template_source - .copy_template(self.target.contract_dir()); + .copy_template(self.target.contract_dir(), args_tag); } - pub fn update_dependencies(&self) { - self.adjuster.update_dependencies(); + pub fn update_dependencies(&self, args_tag: FrameworkVersion) { + self.adjuster.update_cargo_toml_files(args_tag); } pub fn rename_template(&self) { 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 82% rename from framework/meta/src/cmd/standalone/template/copy_util.rs rename to framework/meta/src/cmd/template/copy_util.rs index 2d324a5e56..6a7ecc7b23 100644 --- a/framework/meta/src/cmd/standalone/template/copy_util.rs +++ b/framework/meta/src/cmd/template/copy_util.rs @@ -3,6 +3,8 @@ use std::{ path::{Path, PathBuf}, }; +use crate::{version::FrameworkVersion, version_history::is_template_with_autogenerated_json}; + /// Will copy an entire folder according to a whitelist of allowed paths. /// /// The whitelist is expected to contain paths relative from the source path. @@ -10,8 +12,19 @@ use std::{ /// If a folder is whitelisted, then everything in the folder is considered whitelisted too. /// /// The function creates all necessary folder structure in the target, no additional preparation required. -pub fn whitelisted_deep_copy(source_root: &Path, target_root: &Path, whitelist: &[String]) { - perform_file_copy(source_root, &PathBuf::new(), target_root, whitelist); +pub fn whitelisted_deep_copy( + source_root: &Path, + target_root: &Path, + whitelist: &[String], + args_tag: FrameworkVersion, +) { + if is_template_with_autogenerated_json(args_tag) { + perform_file_copy(source_root, &PathBuf::new(), target_root, whitelist); + } else { + let mut tmp_whitelist = whitelist.to_vec(); + tmp_whitelist.push("multiversx.json".into()); + perform_file_copy(source_root, &PathBuf::new(), target_root, &tmp_whitelist); + } } fn is_whitelisted(path: &Path, whitelist: &[String]) -> bool { 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 69% rename from framework/meta/src/cmd/standalone/template/repo_version.rs rename to framework/meta/src/cmd/template/repo_version.rs index 3eb798a66f..874f1b3832 100644 --- a/framework/meta/src/cmd/standalone/template/repo_version.rs +++ b/framework/meta/src/cmd/template/repo_version.rs @@ -1,3 +1,5 @@ +use crate::{version::FrameworkVersion, version_history::LAST_TEMPLATE_VERSION}; + pub enum RepoVersion { Master, Tag(String), @@ -23,4 +25,11 @@ impl RepoVersion { }, } } + + pub fn get_tag(&self) -> FrameworkVersion { + match self { + RepoVersion::Master => LAST_TEMPLATE_VERSION, + RepoVersion::Tag(tag) => FrameworkVersion::from_string_template(tag), + } + } } diff --git a/framework/meta/src/cmd/standalone/template/template_adjuster.rs b/framework/meta/src/cmd/template/template_adjuster.rs similarity index 67% rename from framework/meta/src/cmd/standalone/template/template_adjuster.rs rename to framework/meta/src/cmd/template/template_adjuster.rs index 0cd3d97456..2e628a9266 100644 --- a/framework/meta/src/cmd/standalone/template/template_adjuster.rs +++ b/framework/meta/src/cmd/template/template_adjuster.rs @@ -1,30 +1,41 @@ use super::{template_metadata::TemplateMetadata, ContractCreatorTarget}; use crate::{ - cmd::standalone::upgrade::upgrade_common::{rename_files, replace_in_files}, - CargoTomlContents, + cmd::upgrade::upgrade_common::{rename_files, replace_in_files}, + version::FrameworkVersion, + version_history::is_template_with_autogenerated_wasm, }; 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"; +const DEFAULT_AUTHOR: &str = "you"; pub struct TemplateAdjuster { pub metadata: TemplateMetadata, pub target: ContractCreatorTarget, pub keep_paths: bool, + pub new_author: Option, } impl TemplateAdjuster { - pub fn update_dependencies(&self) { - self.update_dependencies_root(); - self.update_dependencies_wasm(); - self.update_dependencies_meta(); + pub fn update_cargo_toml_files(&self, args_tag: FrameworkVersion) { + let author_as_str = self + .new_author + .clone() + .unwrap_or_else(|| DEFAULT_AUTHOR.to_string()); + self.update_cargo_toml_root(author_as_str.clone()); + self.update_cargo_toml_meta(); + self.update_cargo_toml_wasm(args_tag); + self.update_cargo_toml_interact(author_as_str); } - fn update_dependencies_root(&self) { + fn update_cargo_toml_root(&self, author: String) { let cargo_toml_path = self.target.contract_dir().join(ROOT_CARGO_TOML); let mut toml = CargoTomlContents::load_from_file(&cargo_toml_path); @@ -32,12 +43,16 @@ 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.change_author(author); toml.save_to_file(&cargo_toml_path); } - fn update_dependencies_meta(&self) { + fn update_cargo_toml_meta(&self) { let cargo_toml_path = self.target.contract_dir().join(META_CARGO_TOML); let mut toml = CargoTomlContents::load_from_file(&cargo_toml_path); @@ -48,7 +63,11 @@ impl TemplateAdjuster { toml.save_to_file(&cargo_toml_path); } - fn update_dependencies_wasm(&self) { + fn update_cargo_toml_wasm(&self, args_tag: FrameworkVersion) { + if is_template_with_autogenerated_wasm(args_tag) { + return; + } + let cargo_toml_path = self.target.contract_dir().join(WASM_CARGO_TOML); let mut toml = CargoTomlContents::load_from_file(&cargo_toml_path); @@ -59,12 +78,29 @@ impl TemplateAdjuster { toml.save_to_file(&cargo_toml_path); } + fn update_cargo_toml_interact(&self, author: String) { + 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.change_author(author); + 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(); } @@ -75,6 +111,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(), @@ -82,8 +120,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) { @@ -157,16 +202,44 @@ impl TemplateAdjuster { let old_wasm = wasm_file_name(&self.metadata.name); let new_wasm = wasm_file_name(&self.target.new_name); + let old_mxsc = mxsc_file_name(&self.metadata.name); + let new_mxsc = mxsc_file_name(&self.target.new_name); + + self.rename_in_scenarios(&old_wasm, &new_wasm); + self.rename_in_scenarios(&old_mxsc, &new_mxsc); + + queries.push(Query::substring(&old_wasm, &new_wasm)); + queries.push(Query::substring(&old_mxsc, &new_mxsc)); + + replace_in_files( + &self.target.contract_dir().join(TEST_DIRECTORY), + "*.rs", + &queries, + ); + } + + fn rename_in_scenarios(&self, old: &str, new: &str) { replace_in_files( &self.target.contract_dir(), "*.scen.json", - &[Query::substring(&old_wasm, &new_wasm)][..], + &[Query::substring(old, new)][..], ); - queries.push(Query::substring(&old_wasm, &new_wasm)); + replace_in_files( + &self.target.contract_dir(), + "*.steps.json", + &[Query::substring(old, new)][..], + ); + } + + 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(TEST_DIRECTORY), + &self.target.contract_dir().join(INTERACT_DIRECTORY), "*.rs", &queries, ); @@ -188,6 +261,10 @@ fn wasm_file_name(name: &str) -> String { format!("{name}.wasm",) } +fn mxsc_file_name(name: &str) -> String { + format!("{name}.mxsc.json",) +} + fn rs_file_name(name: &str) -> String { format!("{name}.rs",) } 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 85% rename from framework/meta/src/cmd/standalone/template/template_source.rs rename to framework/meta/src/cmd/template/template_source.rs index 94032a9398..ea4140cd31 100644 --- a/framework/meta/src/cmd/standalone/template/template_source.rs +++ b/framework/meta/src/cmd/template/template_source.rs @@ -3,7 +3,7 @@ use std::{ path::{Path, PathBuf}, }; -use crate::folder_structure::RelevantDirectories; +use crate::{folder_structure::RelevantDirectories, version::FrameworkVersion}; use super::{copy_util::whitelisted_deep_copy, template_metadata::TemplateMetadata, RepoSource}; @@ -17,18 +17,19 @@ pub struct TemplateSource<'a> { } impl<'a> TemplateSource<'a> { - pub fn copy_template(&self, target_path: impl AsRef) { + pub fn copy_template(&self, target_path: impl AsRef, args_tag: FrameworkVersion) { whitelisted_deep_copy( &self.source_path, target_path.as_ref(), &self.metadata.files_include, + args_tag, ); } } pub fn template_sources(repo_temp_dir: &RepoSource) -> Vec> { let templates_path = repo_temp_dir.repo_path().join(TEMPLATES_PATH_IN_REPO); - let dirs = RelevantDirectories::find_all(&templates_path, &[]); + let dirs = RelevantDirectories::find_all(templates_path, &[]); let mut sources = Vec::new(); for dir in dirs.iter_contract_crates() { let template_metadata_path = dir.path.join(TEMPLATE_TOML_FILE_NAME); diff --git a/framework/meta/src/cmd/standalone/test.rs b/framework/meta/src/cmd/test.rs similarity index 74% rename from framework/meta/src/cmd/standalone/test.rs rename to framework/meta/src/cmd/test.rs index a66f46c391..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("./"); @@ -11,18 +11,25 @@ pub fn test(test_args: &TestArgs) { let go = test_args.go; let scen = test_args.scen; + let no_capture = test_args.nocapture; if scen { - program = "run-scenarios"; - args.extend(["./"]); + program = "mx-scenario-go"; + args.extend(["run", "./"]); if go { println!("{}", "If scen parameter is true, it will override the go parameter. Executing scenarios...".yellow()); } - } else if go { - args.extend(["test", "--features", "multiversx-sc-scenario/run-go-tests"]); } else { - args.extend(["test"]); + args.push("test"); + + if go { + args.extend(["--features", "multiversx-sc-scenario/run-go-tests"]); + } + + if no_capture { + args.extend(["--", "--nocapture"]); + } } let args_str = args.join(" "); diff --git a/framework/meta/src/cmd/test_coverage.rs b/framework/meta/src/cmd/test_coverage.rs new file mode 100644 index 0000000000..0ece2454fb --- /dev/null +++ b/framework/meta/src/cmd/test_coverage.rs @@ -0,0 +1,25 @@ +mod cargo; +mod error; +mod llvm_cov; +mod render; +mod run; +mod util; + +use crate::{ + cli::{OutputFormat, TestCoverageArgs}, + 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(&OutputFormat::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..687d404009 --- /dev/null +++ b/framework/meta/src/cmd/test_coverage/run.rs @@ -0,0 +1,61 @@ +use std::fs; + +use crate::{ + cli::OutputFormat, + 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: &OutputFormat, + 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 { + OutputFormat::Markdown => { + render_coverage(&mut output, &coverage, root_path); + }, + OutputFormat::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 78% rename from framework/meta/src/cmd/standalone/upgrade.rs rename to framework/meta/src/cmd/upgrade.rs index c54d8e85dc..ab14b75075 100644 --- a/framework/meta/src/cmd/standalone/upgrade.rs +++ b/framework/meta/src/cmd/upgrade.rs @@ -1,9 +1,12 @@ 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; +mod upgrade_settings; pub use upgrade_print::print_tree_dir_metadata; pub use upgrade_selector::upgrade_sc; 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 76% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_0_31.rs rename to framework/meta/src/cmd/upgrade/upgrade_0_31.rs index dcd2afde30..234c2b972b 100644 --- a/framework/meta/src/cmd/standalone/upgrade/upgrade_0_31.rs +++ b/framework/meta/src/cmd/upgrade/upgrade_0_31.rs @@ -7,8 +7,8 @@ use std::path::Path; pub fn upgrade_to_31_0(dir: &RelevantDirectory) { v_0_31_replace_in_files(dir.path.as_ref()); - let (from_version, to_version) = dir.upgrade_in_progress.unwrap(); - version_bump_in_cargo_toml(&dir.path, from_version, to_version); + 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_31_replace_in_files(sc_crate_path: &Path) { 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 79% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_0_32.rs rename to framework/meta/src/cmd/upgrade/upgrade_0_32.rs index 8f6c2978ad..fa234ef04c 100644 --- a/framework/meta/src/cmd/standalone/upgrade/upgrade_0_32.rs +++ b/framework/meta/src/cmd/upgrade/upgrade_0_32.rs @@ -7,8 +7,8 @@ use std::path::Path; pub fn upgrade_to_32_0(dir: &RelevantDirectory) { v_0_32_replace_in_files(dir.path.as_ref()); - let (from_version, to_version) = dir.upgrade_in_progress.unwrap(); - version_bump_in_cargo_toml(&dir.path, from_version, to_version); + 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_32_replace_in_files(sc_crate_path: &Path) { 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 93% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_0_39.rs rename to framework/meta/src/cmd/upgrade/upgrade_0_39.rs index 4635fcd8c3..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}; @@ -28,8 +26,8 @@ pub fn upgrade_to_39_0(dir: &RelevantDirectory) { v_0_39_replace_in_files(&dir.path); rename_files(dir.path.as_ref(), SCENARIO_FILE_PATTERNS); - let (from_version, to_version) = dir.upgrade_in_progress.unwrap(); - version_bump_in_cargo_toml(&dir.path, from_version, to_version); + let (from_version, to_version) = dir.upgrade_in_progress.clone().unwrap(); + version_bump_in_cargo_toml(&dir.path, &from_version, &to_version); } /// Post-processing: re-generate the wasm crates. diff --git a/framework/meta/src/cmd/upgrade/upgrade_0_45.rs b/framework/meta/src/cmd/upgrade/upgrade_0_45.rs new file mode 100644 index 0000000000..7082f92f97 --- /dev/null +++ b/framework/meta/src/cmd/upgrade/upgrade_0_45.rs @@ -0,0 +1,34 @@ +use std::path::Path; + +use super::upgrade_common::version_bump_in_cargo_toml; +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. +pub fn upgrade_to_45_0(dir: &RelevantDirectory) { + if dir.dir_type == DirectoryType::Contract { + v_0_45_prepare_meta(&dir.path); + } + 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_45_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(); + if let Some(meta_dep) = deps.get_mut("multiversx-sc-meta") { + let meta_dep_table = meta_dep + .as_table_mut() + .expect("multiversx-sc-meta dependency expected to be given as a table"); + meta_dep_table.remove("default-features"); + meta_dep_table.insert("default-features".to_string(), Value::Boolean(false)); + } + meta_cargo_toml.save_to_file(&cargo_toml_path); +} 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 87% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_common.rs rename to framework/meta/src/cmd/upgrade/upgrade_common.rs index 6015e08631..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,17 +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, - }, - CargoTomlContents, -}; - -use super::upgrade_print::*; - /// Uses ruplacer. pub(crate) fn replace_in_files(sc_crate_path: &Path, file_type: &str, queries: &[Query]) { if !sc_crate_path.exists() { @@ -75,7 +75,11 @@ fn try_replace_file_name(file_name_str: &str, patterns: &[(&str, &str)]) -> Opti } /// Uses `CargoTomlContents`. Will only replace versions of framework crates. -pub fn version_bump_in_cargo_toml(path: &Path, from_version: &str, to_version: &str) { +pub fn version_bump_in_cargo_toml( + path: &Path, + from_version: &FrameworkVersion, + to_version: &FrameworkVersion, +) { if is_cargo_toml_file(path) { let mut cargo_toml_contents = CargoTomlContents::load_from_file(path); upgrade_all_dependency_versions( @@ -114,8 +118,8 @@ fn is_cargo_toml_file(path: &Path) -> bool { fn upgrade_all_dependency_versions( cargo_toml_contents: &mut CargoTomlContents, deps_name: &str, - from_version: &str, - to_version: &str, + from_version: &FrameworkVersion, + to_version: &FrameworkVersion, ) { if let Some(dependencies) = cargo_toml_contents.toml_value.get_mut(deps_name) { for &framework_crate_name in FRAMEWORK_CRATE_NAMES { @@ -136,8 +140,8 @@ fn upgrade_dependency_version( deps_name: &str, dependencies: &mut Value, framework_crate_name: &str, - from_version: &str, - to_version: &str, + from_version: &FrameworkVersion, + to_version: &FrameworkVersion, ) { match dependencies.get_mut(framework_crate_name) { Some(Value::String(version_string)) => { @@ -168,16 +172,16 @@ fn upgrade_dependency_version( fn change_version_string( version_string: &mut String, - from_version: &str, - to_version: &str, + from_version: &FrameworkVersion, + to_version: &FrameworkVersion, path: &Path, deps_name: &str, framework_crate_name: &str, ) { let version_string_before = version_string.clone(); let mut version_spec = VersionReq::from_string(std::mem::take(version_string)); - if version_spec.semver == from_version { - version_spec.semver = to_version.to_string(); + if version_spec.semver == *from_version { + version_spec.semver = to_version.clone(); } *version_string = version_spec.into_string(); @@ -200,7 +204,11 @@ pub fn re_generate_wasm_crate(dir: &RelevantDirectory) { ); } -pub fn cargo_check(dir: &RelevantDirectory) { +pub fn cargo_check(dir: &RelevantDirectory, settings: &UpgradeSettings) { + if settings.no_check { + return; + } + print_cargo_check(dir); let result = Command::new("cargo") diff --git a/framework/meta/src/cmd/standalone/upgrade/upgrade_print.rs b/framework/meta/src/cmd/upgrade/upgrade_print.rs similarity index 73% rename from framework/meta/src/cmd/standalone/upgrade/upgrade_print.rs rename to framework/meta/src/cmd/upgrade/upgrade_print.rs index 6ef50b6dea..51d66f9333 100644 --- a/framework/meta/src/cmd/standalone/upgrade/upgrade_print.rs +++ b/framework/meta/src/cmd/upgrade/upgrade_print.rs @@ -1,16 +1,21 @@ -use crate::folder_structure::{ - DirectoryType::{Contract, Lib}, - RelevantDirectory, +use crate::{ + folder_structure::{ + DirectoryType::{Contract, Lib}, + RelevantDirectory, + }, + version::FrameworkVersion, }; use colored::Colorize; use std::path::Path; pub fn print_upgrading(dir: &RelevantDirectory) { - if let Some((from_version, to_version)) = dir.upgrade_in_progress { + if let Some((from_version, to_version)) = &dir.upgrade_in_progress { println!( "\n{}", format!( - "Upgrading from {from_version} to {to_version} in {}\n", + "Upgrading from {} to {} in {}\n", + from_version, + to_version, dir.path.display(), ) .purple() @@ -19,11 +24,13 @@ pub fn print_upgrading(dir: &RelevantDirectory) { } pub fn print_post_processing(dir: &RelevantDirectory) { - if let Some((from_version, to_version)) = dir.upgrade_in_progress { + if let Some((from_version, to_version)) = &dir.upgrade_in_progress { println!( "\n{}", format!( - "Post-processing after upgrade from {from_version} to {to_version} in {}\n", + "Post-processing after upgrade from {} to {} in {}\n", + from_version, + to_version, dir.path.display(), ) .purple() @@ -31,10 +38,14 @@ pub fn print_post_processing(dir: &RelevantDirectory) { } } -pub fn print_upgrading_all(from_version: &str, to_version: &str) { +pub fn print_upgrading_all(from_version: &FrameworkVersion, to_version: &FrameworkVersion) { println!( "\n{}", - format!("Upgrading from {from_version} to {to_version} across crates ...").purple() + format!( + "Upgrading from {} to {} across crates ...", + from_version, to_version + ) + .purple() ); } @@ -71,14 +82,14 @@ pub fn print_postprocessing_after_39_1(path: &Path) { ); } -pub fn print_tree_dir_metadata(dir: &RelevantDirectory, last_version: &str) { +pub fn print_tree_dir_metadata(dir: &RelevantDirectory, last_version: &FrameworkVersion) { match dir.dir_type { Contract => print!(" {}", "[contract]".blue()), Lib => print!(" {}", "[lib]".magenta()), } - let version_string = format!("[{}]", &dir.version.semver); - if dir.version.semver == last_version { + let version_string = format!("[{}]", dir.version.semver); + if dir.version.semver == *last_version { print!(" {}", version_string.green()); } else { print!(" {}", version_string.red()); diff --git a/framework/meta/src/cmd/upgrade/upgrade_selector.rs b/framework/meta/src/cmd/upgrade/upgrade_selector.rs new file mode 100644 index 0000000000..0f958b176e --- /dev/null +++ b/framework/meta/src/cmd/upgrade/upgrade_selector.rs @@ -0,0 +1,109 @@ +use crate::{ + cli::UpgradeArgs, + cmd::upgrade::upgrade_settings::UpgradeSettings, + folder_structure::{dir_pretty_print, RelevantDirectories, RelevantDirectory}, + 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::*, +}; + +pub fn upgrade_sc(args: &UpgradeArgs) { + let path = if let Some(some_path) = &args.path { + some_path.as_str() + } else { + "./" + }; + + let settings = UpgradeSettings::new(args.no_check); + + let last_version = args + .override_target_version + .clone() + .map(|override_target_v| { + VERSIONS + .iter() + .find(|v| v.to_string() == override_target_v) + .cloned() + .unwrap_or(LAST_UPGRADE_VERSION) + }) + .unwrap_or_else(|| LAST_UPGRADE_VERSION); + + assert!( + VERSIONS.contains(&last_version), + "Invalid requested version: {}", + last_version.version, + ); + + let mut dirs = RelevantDirectories::find_all(path, args.ignore.as_slice()); + println!( + "Found {} directories to upgrade, out of which {} are contract crates.\n", + dirs.len(), + dirs.iter_contract_crates().count(), + ); + dir_pretty_print(dirs.iter(), "", &|dir| { + print_tree_dir_metadata(dir, &last_version) + }); + + for (from_version, to_version) in versions_iter(last_version) { + if dirs.count_for_version(from_version) == 0 { + continue; + } + + print_upgrading_all(from_version, to_version); + dirs.start_upgrade(from_version.clone(), to_version.clone()); + for dir in dirs.iter_version(from_version) { + upgrade_function_selector(dir); + } + + for dir in dirs.iter_version(from_version) { + upgrade_post_processing(dir, &settings); + } + + dirs.finish_upgrade(); + } +} + +fn upgrade_function_selector(dir: &RelevantDirectory) { + if dir.upgrade_in_progress.is_some() { + print_upgrading(dir); + } + + if let Some((from_version, to_version)) = &dir.upgrade_in_progress { + if framework_version!(0.31.0) == *to_version { + upgrade_to_31_0(dir) + } else if framework_version!(0.32.0) == *to_version { + upgrade_to_32_0(dir) + } else if framework_version!(0.39.0) == *to_version { + 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) + } + } +} + +fn upgrade_post_processing(dir: &RelevantDirectory, settings: &UpgradeSettings) { + if let Some((_, to_version)) = &dir.upgrade_in_progress { + if CHECK_AFTER_UPGRADE_TO.contains(to_version) { + print_post_processing(dir); + cargo_check(dir, settings); + } else if framework_version!(0.39.0) == *to_version { + print_post_processing(dir); + postprocessing_after_39_0(dir); + cargo_check(dir, settings); + } + } +} diff --git a/framework/meta/src/cmd/upgrade/upgrade_settings.rs b/framework/meta/src/cmd/upgrade/upgrade_settings.rs new file mode 100644 index 0000000000..8706de4613 --- /dev/null +++ b/framework/meta/src/cmd/upgrade/upgrade_settings.rs @@ -0,0 +1,9 @@ +pub struct UpgradeSettings { + pub no_check: bool, +} + +impl UpgradeSettings { + pub fn new(no_check: bool) -> Self { + UpgradeSettings { no_check } + } +} diff --git a/framework/meta/src/cmd/wallet.rs b/framework/meta/src/cmd/wallet.rs new file mode 100644 index 0000000000..b3833da517 --- /dev/null +++ b/framework/meta/src/cmd/wallet.rs @@ -0,0 +1,176 @@ +use core::str; + +use crate::cli::{WalletAction, WalletArgs, WalletBech32Args, WalletConvertArgs, WalletNewArgs}; +use multiversx_sc::types::{self}; +use multiversx_sc_snippets::sdk::{ + crypto::public_key::PublicKey, data::address::Address, wallet::Wallet, +}; +use multiversx_sc_snippets::{hex, imports::Bech32Address}; +use std::{ + fs::{self, File}, + io::{self, Read, Write}, +}; + +pub fn wallet(args: &WalletArgs) { + let command = &args.command; + match command { + WalletAction::New(new_args) => new(new_args), + WalletAction::Bech32(bech32_args) => bech32_conversion(bech32_args), + WalletAction::Convert(convert_args) => convert(convert_args), + } +} + +fn convert(convert_args: &WalletConvertArgs) { + let infile = convert_args.infile.as_ref(); + let outfile = convert_args.outfile.as_ref(); + let in_format = &convert_args.from; + let out_format = &convert_args.to; + + let mut mnemonic_str = String::new(); + let private_key_str: String; + let public_key_str: String; + + match (in_format.as_str(), out_format.as_str()) { + ("mnemonic", "pem") => match infile { + Some(file) => { + mnemonic_str = fs::read_to_string(file).unwrap(); + (private_key_str, public_key_str) = Wallet::get_wallet_keys_mnemonic(mnemonic_str); + write_resulted_pem(&public_key_str, &private_key_str, outfile); + }, + None => { + println!("Insert text below. Press 'Ctrl-D' (Linux / MacOS) or 'Ctrl-Z' (Windows) when done."); + _ = io::stdin().read_to_string(&mut mnemonic_str).unwrap(); + (private_key_str, public_key_str) = Wallet::get_wallet_keys_mnemonic(mnemonic_str); + write_resulted_pem(&public_key_str, &private_key_str, outfile); + }, + }, + ("keystore-secret", "pem") => match infile { + Some(file) => { + let private_key = Wallet::get_private_key_from_keystore_secret( + file, + &Wallet::get_keystore_password(), + ) + .unwrap(); + private_key_str = private_key.to_string(); + let public_key = PublicKey::from(&private_key); + public_key_str = public_key.to_string(); + write_resulted_pem(&public_key_str, &private_key_str, outfile); + }, + None => { + panic!("Input file is required for keystore-secret format"); + }, + }, + ("pem", "keystore-secret") => match infile { + Some(file) => { + let pem_decoded_keys = Wallet::get_pem_decoded_content(file); + (private_key_str, public_key_str) = Wallet::get_wallet_keys_pem(file); + + let address = get_wallet_address(&private_key_str); + let hex_decoded_keys = hex::decode(pem_decoded_keys).unwrap(); + + let json_result = Wallet::encrypt_keystore( + hex_decoded_keys.as_slice(), + &address, + &public_key_str, + &Wallet::get_keystore_password(), + ); + write_resulted_keystore(json_result, outfile); + }, + None => { + panic!("Input file is required for pem format"); + }, + }, + _ => { + println!("Unsupported conversion"); + }, + } +} + +fn write_resulted_pem(public_key: &str, private_key: &str, outfile: Option<&String>) { + let address = get_wallet_address(private_key); + match outfile { + Some(outfile) => { + let pem_content = Wallet::generate_pem_content(&address, private_key, public_key); + let mut file = File::create(outfile).unwrap(); + file.write_all(pem_content.as_bytes()).unwrap(); + }, + None => { + let pem_content = Wallet::generate_pem_content(&address, private_key, public_key); + print!("{}", pem_content); + }, + } +} + +fn write_resulted_keystore(json_result: String, outfile: Option<&String>) { + match outfile { + Some(outfile) => { + let mut file = File::create(outfile).unwrap(); + file.write_all(json_result.as_bytes()).unwrap(); + }, + None => { + println!("{}", json_result); + }, + } +} + +fn bech32_conversion(bech32_args: &WalletBech32Args) { + let encode_address = bech32_args.hex_address.as_ref(); + let decode_address = bech32_args.bech32_address.as_ref(); + + match (encode_address, decode_address) { + (Some(hex), None) => { + let bytes_from_hex = hex::decode(hex).unwrap(); + let bytes_arr: [u8; 32] = bytes_from_hex.try_into().unwrap(); + + let addr = types::Address::from(&bytes_arr); + let bech32_addr = Bech32Address::from(addr).to_bech32_str().to_string(); + println!("{}", bech32_addr); + }, + (None, Some(bech32)) => { + let hex_addr = Bech32Address::from_bech32_string(bech32.to_string()).to_hex(); + println!("{}", hex_addr); + }, + (Some(_), Some(_)) => { + println!("error: only one of --encode or --decode can be used in the same command"); + }, + _ => {}, + } +} + +fn get_wallet_address(private_key: &str) -> Address { + let wallet = Wallet::from_private_key(private_key).unwrap(); + wallet.address() +} + +fn new(new_args: &WalletNewArgs) { + let format = new_args.wallet_format.as_deref(); + let outfile = new_args.outfile.as_ref(); // Handle outfile as Option<&str> if it's an Option + let mnemonic = Wallet::generate_mnemonic(); + println!("Mnemonic: {}", mnemonic); + + let (private_key_str, public_key_str) = Wallet::get_wallet_keys_mnemonic(mnemonic.to_string()); + let address = get_wallet_address(private_key_str.as_str()); + + println!("Wallet address: {}", address); + + match format { + Some("pem") => { + write_resulted_pem(public_key_str.as_str(), private_key_str.as_str(), outfile); + }, + Some("keystore-secret") => { + let concatenated_keys = format!("{}{}", private_key_str, public_key_str); + let hex_decoded_keys = hex::decode(concatenated_keys).unwrap(); + let json_result = Wallet::encrypt_keystore( + hex_decoded_keys.as_slice(), + &address, + &public_key_str, + &Wallet::get_keystore_password(), + ); + write_resulted_keystore(json_result, outfile); + }, + Some(_) => { + println!("Unsupported format"); + }, + None => {}, + } +} diff --git a/framework/meta/src/folder_structure/relevant_directory.rs b/framework/meta/src/folder_structure/relevant_directory.rs index fc380a0014..be0c4ce0ac 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::CargoTomlContents; +use crate::version::FrameworkVersion; +use multiversx_sc_meta_lib::cargo_toml_contents::CargoTomlContents; use std::{ fs::{self, DirEntry}, path::{Path, PathBuf}, @@ -11,7 +12,9 @@ use super::version_req::VersionReq; pub const FRAMEWORK_CRATE_NAMES: &[&str] = &[ "multiversx-sc", "multiversx-sc-meta", + "multiversx-sc-meta-lib", "multiversx-sc-scenario", + "multiversx-sc-snippets", "multiversx-sc-wasm-adapter", "multiversx-sc-modules", "elrond-wasm", @@ -33,7 +36,7 @@ pub enum DirectoryType { pub struct RelevantDirectory { pub path: PathBuf, pub version: VersionReq, - pub upgrade_in_progress: Option<(&'static str, &'static str)>, + pub upgrade_in_progress: Option<(FrameworkVersion, FrameworkVersion)>, pub dir_type: DirectoryType, } @@ -83,27 +86,27 @@ impl RelevantDirectories { .filter(|dir| dir.dir_type == DirectoryType::Contract) } - pub fn count_for_version(&self, version: &str) -> usize { + pub fn count_for_version(&self, version: &FrameworkVersion) -> usize { self.0 .iter() - .filter(|dir| dir.version.semver == version) + .filter(|dir| dir.version.semver == *version) .count() } pub fn iter_version( &mut self, - version: &'static str, + version: &'static FrameworkVersion, ) -> impl Iterator { self.0 .iter() - .filter(move |dir| dir.version.semver == version) + .filter(move |dir| dir.version.semver == *version) } /// Marks all appropriate directories as ready for upgrade. - pub fn start_upgrade(&mut self, from_version: &'static str, to_version: &'static str) { + pub fn start_upgrade(&mut self, from_version: FrameworkVersion, to_version: FrameworkVersion) { for dir in self.0.iter_mut() { if dir.version.semver == from_version { - dir.upgrade_in_progress = Some((from_version, to_version)); + dir.upgrade_in_progress = Some((from_version.clone(), to_version.clone())); } } } @@ -113,7 +116,7 @@ impl RelevantDirectories { pub fn finish_upgrade(&mut self) { for dir in self.0.iter_mut() { if let Some((_, to_version)) = &dir.upgrade_in_progress { - dir.version.semver = to_version.to_string(); + dir.version.semver = to_version.clone(); dir.upgrade_in_progress = None; } } diff --git a/framework/meta/src/folder_structure/version_req.rs b/framework/meta/src/folder_structure/version_req.rs index 8bc71ebd77..bbfa752a12 100644 --- a/framework/meta/src/folder_structure/version_req.rs +++ b/framework/meta/src/folder_structure/version_req.rs @@ -1,22 +1,28 @@ +use crate::{ + version::FrameworkVersion, + version_history::{find_version_by_str, LAST_VERSION}, +}; + /// Crate version requirements, as expressed in Cargo.toml. A very crude version. /// /// TODO: replace with semver::VersionReq at some point. #[derive(Debug, Clone)] pub struct VersionReq { - pub semver: String, + pub semver: FrameworkVersion, pub is_strict: bool, } - impl VersionReq { pub fn from_string(raw: String) -> Self { if let Some(stripped_version) = raw.strip_prefix('=') { VersionReq { - semver: stripped_version.to_string(), + semver: find_version_by_str(stripped_version) + .unwrap_or(&LAST_VERSION) + .clone(), is_strict: true, } } else { VersionReq { - semver: raw, + semver: find_version_by_str(&raw).unwrap_or(&LAST_VERSION).clone(), is_strict: false, } } @@ -26,7 +32,7 @@ impl VersionReq { if self.is_strict { format!("={}", self.semver) } else { - self.semver + self.semver.to_string() } } } diff --git a/framework/meta/src/lib.rs b/framework/meta/src/lib.rs index e6dd8e9298..b74df97748 100644 --- a/framework/meta/src/lib.rs +++ b/framework/meta/src/lib.rs @@ -1,17 +1,31 @@ -pub mod abi_json; -mod cargo_toml_contents; -pub mod cli_args; +pub mod cli; pub mod cmd; -pub mod ei; -pub mod esdt_attr_file_json; pub mod folder_structure; -mod mxsc_file_json; -mod print_util; -mod tools; -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/src/tools/wasm_imports.rs b/framework/meta/src/tools/wasm_imports.rs deleted file mode 100644 index 64d8d68b8f..0000000000 --- a/framework/meta/src/tools/wasm_imports.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::fs; -use wasmparser::{BinaryReaderError, Parser, Payload}; - -/// Parses the WebAssembly code and extracts all the import names. -pub fn extract_wasm_imports(output_wasm_path: &str) -> Vec { - let wasm_data = fs::read(output_wasm_path) - .expect("error occured while extracting imports from .wasm: file not found"); - - parse_wasm_imports(wasm_data).expect("error occured while extracting imports from .wasm ") -} - -fn parse_wasm_imports(wasm_data: Vec) -> Result, BinaryReaderError> { - let mut import_names = Vec::new(); - - let parser = Parser::new(0); - for payload in parser.parse_all(&wasm_data) { - if let Payload::ImportSection(import_section) = payload? { - for import in import_section { - import_names.push(import?.name.to_string()); - } - } - } - - Ok(import_names) -} diff --git a/framework/meta/src/version_history.rs b/framework/meta/src/version_history.rs deleted file mode 100644 index 037ad02f98..0000000000 --- a/framework/meta/src/version_history.rs +++ /dev/null @@ -1,116 +0,0 @@ -/// 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: &str = "0.44.0"; - -/// Indicates where to stop with the upgrades. -pub const LAST_UPGRADE_VERSION: &str = LAST_VERSION; - -pub const LAST_TEMPLATE_VERSION: &str = LAST_VERSION; - -/// Known versions for the upgrader. -#[rustfmt::skip] -pub const VERSIONS: &[&str] = &[ - "0.28.0", - "0.29.0", - "0.29.2", - "0.29.3", - "0.30.0", - "0.31.0", - "0.31.1", - "0.32.0", - "0.33.0", - "0.33.1", - "0.34.0", - "0.34.1", - "0.35.0", - "0.36.0", - "0.36.1", - "0.37.0", - "0.38.0", - "0.39.0", - "0.39.1", - "0.39.2", - "0.39.3", - "0.39.4", - "0.39.5", - "0.39.6", - "0.39.7", - "0.39.8", - "0.40.0", - "0.40.1", - "0.44.0", - "0.41.1", - "0.41.2", - "0.41.3", - "0.42.0", - "0.43.0", - "0.43.1", - "0.43.2", - "0.43.3", - "0.43.4", - "0.43.5", - "0.44.0", -]; - -/// We started supporting contract templates with version 0.43.0. -pub fn template_versions() -> &'static [&'static str] { - &VERSIONS[33..] -} - -pub fn validate_template_tag(tag: &str) -> bool { - let versions = template_versions(); - versions.iter().any(|&tt| tt == tag) -} - -pub struct VersionIterator { - next_version: usize, - last_version: String, -} - -impl VersionIterator { - fn is_last_version(&self, version: &str) -> bool { - self.last_version == version - } -} - -impl Iterator for VersionIterator { - type Item = (&'static str, &'static str); - - fn next(&mut self) -> Option { - if self.next_version > 0 && self.next_version < VERSIONS.len() { - let from_version = VERSIONS[self.next_version - 1]; - - if self.is_last_version(from_version) { - None - } else { - let to_version = VERSIONS[self.next_version]; - let result = (from_version, to_version); - self.next_version += 1; - Some(result) - } - } else { - None - } - } -} - -pub fn versions_iter(last_version: String) -> VersionIterator { - VersionIterator { - next_version: 1, - last_version, - } -} - -#[cfg(test)] -pub mod tests { - use super::*; - - #[test] - fn template_versions_test() { - assert_eq!(template_versions()[0], "0.43.0"); - - assert!(validate_template_tag("0.43.0")); - assert!(!validate_template_tag("0.42.0")); - } -} 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 9ef068ee42..764aae6f87 100644 --- a/framework/meta/tests/template_test.rs +++ b/framework/meta/tests/template_test.rs @@ -1,21 +1,20 @@ +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, }, - version_history, -}; -use std::{ - fs, - path::{Path, PathBuf}, - process::Command, + 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; #[test] fn test_template_list() { - let workspace_path = find_workspace(); + let workspace_path = find_current_workspace().unwrap(); let repo_source = RepoSource::from_local_path(workspace_path); let mut template_names = template_names_from_repo(&repo_source); template_names.sort(); @@ -24,7 +23,8 @@ fn test_template_list() { [ "adder".to_string(), "crypto-zombies".to_string(), - "empty".to_string() + "empty".to_string(), + "ping-pong-egld".to_string(), ] ); } @@ -32,42 +32,73 @@ fn test_template_list() { #[test] #[cfg_attr(not(feature = "template-test-current"), ignore)] fn template_current_adder() { - template_test_current("adder", "examples", "new-adder"); + template_test_current( + "adder", + "examples", + "new-adder", + "Alin Cruceat ", + ); + + cargo_check_interactor("examples", "new-adder"); } #[test] #[cfg_attr(not(feature = "template-test-current"), ignore)] fn template_current_crypto_zombies() { - template_test_current("crypto-zombies", "examples", "new-crypto-zombies"); + template_test_current("crypto-zombies", "examples", "new-crypto-zombies", ""); } #[test] #[cfg_attr(not(feature = "template-test-current"), ignore)] fn template_current_empty() { - template_test_current("empty", "examples", "new-empty"); + template_test_current("empty", "examples", "new-empty", ""); +} + +#[test] +#[cfg_attr(not(feature = "template-test-current"), ignore)] +fn template_current_ping_pong_egld() { + template_test_current("ping-pong-egld", "examples", "new-ping-pong-egld", ""); +} + +#[test] +#[cfg_attr(not(feature = "template-test-current"), ignore)] +fn test_correct_naming() { + assert_eq!( + "myNew42-correct_Empty".to_string().to_case(Case::Kebab), + "my-new-42-correct-empty" + ); + + template_test_current("empty", "examples", "my1New2_3-correct_Empty", ""); } /// Recreates the folder structure in `contracts`, on the same level. /// This way, the relative paths are still valid in this case, /// and we can test the templates with the framework version of the current branch. -fn template_test_current(template_name: &str, sub_path: &str, new_name: &str) { - let workspace_path = find_workspace(); +fn template_test_current(template_name: &str, sub_path: &str, new_name: &str, new_author: &str) { + let workspace_path = find_current_workspace().unwrap(); let target = ContractCreatorTarget { target_path: workspace_path.join(TEMPLATE_TEMP_DIR_NAME).join(sub_path), - new_name: new_name.to_string(), + new_name: new_name.to_string().to_case(Case::Kebab), }; let repo_source = RepoSource::from_local_path(workspace_path); prepare_target_dir(&target); + let author = if new_author.is_empty() { + None + } else { + Some(new_author.to_string()) + }; + ContractCreator::new( &repo_source, template_name.to_string(), target.clone(), true, + author, ) - .create_contract(); + .create_contract(LAST_TEMPLATE_VERSION); if BUILD_CONTRACTS { build_contract(&target); @@ -78,19 +109,25 @@ fn template_test_current(template_name: &str, sub_path: &str, new_name: &str) { #[test] #[cfg_attr(not(feature = "template-test-released"), ignore)] fn template_released_adder() { - template_test_released("adder", "released-adder"); + template_test_released( + "adder", + "released-adder", + "Alin Cruceat ", + ); + + cargo_check_interactor("", "released-adder"); } #[test] #[cfg_attr(not(feature = "template-test-released"), ignore)] fn template_released_crypto_zombies() { - template_test_released("crypto-zombies", "released-crypto-zombies"); + template_test_released("crypto-zombies", "released-crypto-zombies", ""); } #[test] #[cfg_attr(not(feature = "template-test-released"), ignore)] fn template_released_empty() { - template_test_released("empty", "released-empty"); + template_test_released("empty", "released-empty", ""); } /// These tests fully replicate the templating process. They @@ -98,8 +135,8 @@ fn template_released_empty() { /// - create proper contracts, /// - build the newly created contracts (to wasm) /// - run all tests (including Go scenarios) on them. -fn template_test_released(template_name: &str, new_name: &str) { - let workspace_path = find_workspace(); +fn template_test_released(template_name: &str, new_name: &str, new_author: &str) { + let workspace_path = find_current_workspace().unwrap(); let target = ContractCreatorTarget { target_path: workspace_path.join(TEMPLATE_TEMP_DIR_NAME), new_name: new_name.to_string(), @@ -116,13 +153,20 @@ fn template_test_released(template_name: &str, new_name: &str) { prepare_target_dir(&target); + let author = if new_author.is_empty() { + None + } else { + Some(new_author.to_string()) + }; + ContractCreator::new( &repo_source, template_name.to_string(), target.clone(), false, + author, ) - .create_contract(); + .create_contract(LAST_TEMPLATE_VERSION); if BUILD_CONTRACTS { build_contract(&target); @@ -140,7 +184,7 @@ fn prepare_target_dir(target: &ContractCreatorTarget) { } pub fn cargo_test(target: &ContractCreatorTarget) { - let workspace_target_dir = find_workspace().join("target"); + let workspace_target_dir = find_current_workspace().unwrap().join("target"); let mut args = vec![ "test", @@ -164,7 +208,7 @@ pub fn cargo_test(target: &ContractCreatorTarget) { } pub fn build_contract(target: &ContractCreatorTarget) { - let workspace_target_dir = find_workspace().join("target"); + let workspace_target_dir = find_current_workspace().unwrap().join("target"); let exit_status = Command::new("cargo") .args([ @@ -182,20 +226,21 @@ pub fn build_contract(target: &ContractCreatorTarget) { assert!(exit_status.success(), "contract build process failed"); } -/// Finds the workspace by taking the `current_exe` and working its way up. -/// Works in debug mode too. -/// -/// TODO: duplicated code from scenario_world. De-duplicate after dependencies are reorganized. -pub fn find_workspace() -> PathBuf { - let current_exe = std::env::current_exe().unwrap(); - let mut path = current_exe.as_path(); - while !is_target(path) { - path = path.parent().unwrap(); - } +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"); - path.parent().unwrap().into() -} + 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"); -fn is_target(path_buf: &Path) -> bool { - path_buf.file_name().unwrap() == "target" + assert!(exit_status.success(), "contract test process failed"); } diff --git a/framework/scenario/Cargo.toml b/framework/scenario/Cargo.toml index 99705270d2..24eb8b918b 100644 --- a/framework/scenario/Cargo.toml +++ b/framework/scenario/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-scenario" -version = "0.44.0" +version = "0.53.0" edition = "2021" authors = [ @@ -17,48 +17,41 @@ keywords = ["multiversx", "blockchain", "contract", "debug"] categories = ["cryptography::cryptocurrencies", "development-tools::debugging"] [dependencies] -base64 = "0.13.0" +base64 = "0.22" num-bigint = "0.4" num-traits = "0.2" hex = "0.4" -bech32 = "0.9" +bech32 = "0.11" log = "0.4.17" sha2 = "0.10.6" serde = "1.0" serde_json = "1.0" pathdiff = "0.2.1" -itertools = "0.11" +itertools = "0.13.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] +default = ["wasm-incompatible"] +wasm-incompatible = ["multiversx-chain-vm/wasm-incompatible"] run-go-tests = [] [dependencies.multiversx-sc] -version = "=0.44.0" +version = "=0.53.0" features = ["alloc", "num-bigint"] path = "../base" -[dependencies.multiversx-sc-meta] -version = "=0.44.0" -path = "../meta" +[dependencies.multiversx-sc-meta-lib] +version = "=0.53.0" +path = "../meta-lib" [dependencies.multiversx-chain-scenario-format] -version = "0.20.0" +version = "0.23.0" path = "../../sdk/scenario-format" [dependencies.multiversx-chain-vm-executor] version = "0.2.0" [dependencies.multiversx-chain-vm] -version = "=0.6.0" +version = "=0.10.0" path = "../../vm" - -[dependencies.multiversx-sdk] -version = "=0.2.0" -path = "../../sdk/core" diff --git a/framework/scenario/src/api/core_api_vh/blockchain_api_vh.rs b/framework/scenario/src/api/core_api_vh/blockchain_api_vh.rs index fa723dd273..825a38ca9b 100644 --- a/framework/scenario/src/api/core_api_vh/blockchain_api_vh.rs +++ b/framework/scenario/src/api/core_api_vh/blockchain_api_vh.rs @@ -264,6 +264,26 @@ impl BlockchainApiImpl for VMHooksApi { let result = self.with_vm_hooks(|vh| { vh.get_esdt_local_roles(token_id_handle.get_raw_handle_unchecked()) }); - unsafe { EsdtLocalRoleFlags::from_bits_unchecked(result as u64) } + + multiversx_sc::types::EsdtLocalRoleFlags::from_bits_retain(result as u64) + } + + fn managed_is_builtin_function(&self, function_name_handle: Self::ManagedBufferHandle) -> bool { + i32_to_bool(self.with_vm_hooks(|vh| { + vh.managed_is_builtin_function(function_name_handle.get_raw_handle_unchecked()) + })) + } + + fn managed_get_code_metadata( + &self, + address_handle: Self::ManagedBufferHandle, + response_handle: Self::ManagedBufferHandle, + ) { + self.with_vm_hooks(|vh| { + vh.managed_get_code_metadata( + address_handle.get_raw_handle_unchecked(), + response_handle.get_raw_handle_unchecked(), + ) + }); } } diff --git a/framework/scenario/src/api/core_api_vh/crypto_api_vh.rs b/framework/scenario/src/api/core_api_vh/crypto_api_vh.rs index f3789181e7..305b3d6be9 100644 --- a/framework/scenario/src/api/core_api_vh/crypto_api_vh.rs +++ b/framework/scenario/src/api/core_api_vh/crypto_api_vh.rs @@ -53,7 +53,7 @@ impl CryptoApiImpl for VMHooksApi { _key: Self::ManagedBufferHandle, _message: Self::ManagedBufferHandle, _signature: Self::ManagedBufferHandle, - ) -> bool { + ) { panic!("verify_bls not implemented yet!") } @@ -99,4 +99,31 @@ impl CryptoApiImpl for VMHooksApi { ) { panic!("encode_secp256k1_signature not implemented yet!") } + + fn verify_secp256r1_managed( + &self, + _key: Self::ManagedBufferHandle, + _message: Self::ManagedBufferHandle, + _signature: Self::ManagedBufferHandle, + ) { + panic!("verify_secp256r1 not implemented yet!") + } + + fn verify_bls_signature_share_managed( + &self, + _key: Self::ManagedBufferHandle, + _message: Self::ManagedBufferHandle, + _signature: Self::ManagedBufferHandle, + ) { + panic!("verify_bls_signature_share not implemented yet!") + } + + fn verify_bls_aggregated_signature_managed( + &self, + _key: Self::ManagedBufferHandle, + _message: Self::ManagedBufferHandle, + _signature: Self::ManagedBufferHandle, + ) { + panic!("verify_bls_aggregated_signature not implemented yet!") + } } 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/local_api_vh/static_var_api_vh.rs b/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs index c736ea9c01..e72ae45f74 100644 --- a/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs +++ b/framework/scenario/src/api/local_api_vh/static_var_api_vh.rs @@ -80,4 +80,14 @@ impl StaticVarApiImpl for VMHooksApi { use_raw_handle(data.static_vars_cell.borrow().call_value_multi_esdt_handle) }) } + + fn is_scaling_factor_cached(&self, decimals: usize) -> bool { + self.with_static_data(|data| data.static_vars_cell.borrow().scaling_factor_init[decimals]) + } + + fn set_scaling_factor_cached(&self, decimals: usize) { + self.with_static_data(|data| { + data.static_vars_cell.borrow_mut().scaling_factor_init[decimals] = true + }) + } } diff --git a/framework/scenario/src/api/managed_type_api_vh/big_int_api_vh.rs b/framework/scenario/src/api/managed_type_api_vh/big_int_api_vh.rs index ebe9ca6e71..621115dc62 100644 --- a/framework/scenario/src/api/managed_type_api_vh/big_int_api_vh.rs +++ b/framework/scenario/src/api/managed_type_api_vh/big_int_api_vh.rs @@ -88,8 +88,8 @@ impl BigIntApiImpl for VMHooksApi { unary_op_method! {bi_sqrt, big_int_sqrt} binary_op_method! {bi_pow, big_int_pow} - fn bi_log2(&self, x: Self::BigIntHandle) -> u32 { - self.with_vm_hooks_ctx_1(&x, |vh| vh.big_int_log2(x.get_raw_handle_unchecked())) as u32 + fn bi_log2(&self, x: Self::BigIntHandle) -> i32 { + self.with_vm_hooks_ctx_1(&x, |vh| vh.big_int_log2(x.get_raw_handle_unchecked())) } binary_op_method! {bi_and, big_int_and} 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..ef934cf225 100644 --- a/framework/scenario/src/bech32.rs +++ b/framework/scenario/src/bech32.rs @@ -1,9 +1,9 @@ -use bech32::{FromBase32, ToBase32, Variant}; +use bech32::{Bech32, Hrp}; 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 = Vec::::from_base32(&dest_address_bytes_u5).unwrap(); + let (_hrp, dest_address_bytes) = bech32::decode(bech32_address) + .unwrap_or_else(|err| panic!("bech32 decode error for {bech32_address}: {err}")); if dest_address_bytes.len() != 32 { panic!("Invalid address length after decoding") } @@ -12,6 +12,6 @@ pub fn decode(bech32_address: &str) -> Address { } pub fn encode(address: &Address) -> String { - bech32::encode("erd", address.as_bytes().to_base32(), Variant::Bech32) - .expect("bech32 encode error") + let hrp = Hrp::parse("erd").expect("invalid hrp"); + bech32::encode::(hrp, address.as_bytes()).expect("bech32 encode error") } diff --git a/framework/scenario/src/debug_executor/tx_static_vars.rs b/framework/scenario/src/debug_executor/tx_static_vars.rs index 4ca23f33cb..88277694c4 100644 --- a/framework/scenario/src/debug_executor/tx_static_vars.rs +++ b/framework/scenario/src/debug_executor/tx_static_vars.rs @@ -7,6 +7,8 @@ pub struct TxStaticVars { pub num_arguments: i32, pub call_value_egld_handle: RawHandle, pub call_value_multi_esdt_handle: RawHandle, + //vec of true/false, true if bit from handle = scaling_start + index is not empty + pub scaling_factor_init: [bool; const_handles::SCALING_FACTOR_LENGTH], } impl Default for TxStaticVars { @@ -17,6 +19,7 @@ impl Default for TxStaticVars { num_arguments: -1, call_value_egld_handle: const_handles::UNINITIALIZED_HANDLE, call_value_multi_esdt_handle: const_handles::UNINITIALIZED_HANDLE, + scaling_factor_init: [false; const_handles::SCALING_FACTOR_LENGTH], } } } 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..33b5b1a495 --- /dev/null +++ b/framework/scenario/src/facade/result_handlers.rs @@ -0,0 +1,21 @@ +mod expect_error; +mod expect_message; +mod expect_status; +mod expect_value; +mod returns_logs; +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_logs::ReturnsLogs; +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_logs.rs b/framework/scenario/src/facade/result_handlers/returns_logs.rs new file mode 100644 index 0000000000..7aa4292fa2 --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/returns_logs.rs @@ -0,0 +1,24 @@ +use multiversx_sc::types::RHListItemExec; + +use crate::{ + multiversx_sc::types::{RHListItem, TxEnv}, + scenario_model::{Log, TxResponse}, +}; + +pub struct ReturnsLogs; + +impl RHListItem for ReturnsLogs +where + Env: TxEnv, +{ + type Returns = Vec; +} + +impl RHListItemExec for ReturnsLogs +where + Env: TxEnv, +{ + fn item_process_result(self, raw_result: &TxResponse) -> Self::Returns { + raw_result.logs.clone() + } +} 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 2ed948e2db..056cbbe7f7 100644 --- a/framework/scenario/src/facade/scenario_world.rs +++ b/framework/scenario/src/facade/scenario_world.rs @@ -1,18 +1,10 @@ -use multiversx_chain_scenario_format::interpret_trait::InterpretableFrom; use multiversx_chain_vm::world_mock::BlockchainState; 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_vm_go_tool, + vm_go_tool::run_mx_scenario_go, }; +use multiversx_sc_meta_lib::tools::find_current_workspace; use std::path::{Path, PathBuf}; use super::debugger_backend::DebuggerBackend; @@ -73,7 +65,7 @@ impl ScenarioWorld { debugger.run_scenario_file(&absolute_path); }, Backend::VmGoBackend => { - run_vm_go_tool(&absolute_path); + run_mx_scenario_go(&absolute_path); }, } } @@ -111,10 +103,13 @@ 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_workspace(); + let mut path = find_current_workspace().unwrap(); path.push(relative_path); self.current_dir = path; self @@ -124,86 +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 sub_contract = multi_contract_config.find_contract(sub_contract_name); - let contract_obj = if sub_contract.settings.external_view { - contract_builder.new_contract_obj::>() - } else { - contract_builder.new_contract_obj::() - }; - - self.register_contract_container( - expression, - ContractContainer::new( - contract_obj, - Some(sub_contract.all_exported_function_names()), - sub_contract.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 { @@ -221,19 +136,3 @@ impl ScenarioWorld { self.write_scenario_trace(file_path); } } - -/// Finds the workspace by taking the `current_exe` and working its way up. -/// Works in debug mode too. -pub fn find_workspace() -> PathBuf { - let current_exe = std::env::current_exe().unwrap(); - let mut path = current_exe.as_path(); - while !is_target(path) { - path = path.parent().unwrap(); - } - - path.parent().unwrap().into() -} - -fn is_target(path_buf: &Path) -> bool { - path_buf.file_name().unwrap() == "target" -} 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/scenario_world_whitebox.rs b/framework/scenario/src/facade/scenario_world_whitebox.rs index 32a148ad0a..542e0fe0b2 100644 --- a/framework/scenario/src/facade/scenario_world_whitebox.rs +++ b/framework/scenario/src/facade/scenario_world_whitebox.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + use multiversx_chain_vm::tx_mock::{TxFunctionName, TxResult}; use multiversx_sc::contract_base::{CallableContract, ContractBase}; @@ -10,6 +12,10 @@ use crate::{ use super::whitebox_contract::WhiteboxContract; impl ScenarioWorld { + #[deprecated( + since = "0.53.0", + note = "Please use method `whitebox`, as part of the unified transaction syntax." + )] pub fn whitebox_query( &mut self, whitebox_contract: &WhiteboxContract, @@ -24,6 +30,10 @@ impl ScenarioWorld { }) } + #[deprecated( + since = "0.53.0", + note = "Please use method `whitebox`, as part of the unified transaction syntax." + )] pub fn whitebox_query_check( &mut self, whitebox_contract: &WhiteboxContract, @@ -50,6 +60,10 @@ impl ScenarioWorld { self } + #[deprecated( + since = "0.53.0", + note = "Please use method `whitebox`, as part of the unified transaction syntax." + )] pub fn whitebox_call( &mut self, whitebox_contract: &WhiteboxContract, @@ -65,6 +79,10 @@ impl ScenarioWorld { }) } + #[deprecated( + since = "0.53.0", + note = "Please use method `whitebox`, as part of the unified transaction syntax." + )] pub fn whitebox_call_check( &mut self, whitebox_contract: &WhiteboxContract, @@ -99,6 +117,10 @@ impl ScenarioWorld { self } + #[deprecated( + since = "0.53.0", + note = "Please use method `whitebox`, as part of the unified transaction syntax." + )] pub fn whitebox_deploy( &mut self, whitebox_contract: &WhiteboxContract, @@ -114,6 +136,10 @@ impl ScenarioWorld { }) } + #[deprecated( + since = "0.53.0", + note = "Please use method `whitebox`, as part of the unified transaction syntax." + )] pub fn whitebox_deploy_check( &mut self, whitebox_contract: &WhiteboxContract, diff --git a/framework/scenario/src/facade/world_tx.rs b/framework/scenario/src/facade/world_tx.rs new file mode 100644 index 0000000000..d052614297 --- /dev/null +++ b/framework/scenario/src/facade/world_tx.rs @@ -0,0 +1,13 @@ +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; +mod scenario_tx_whitebox; + +pub use scenario_exec_call::ScenarioEnvExec; +pub use scenario_query_call::ScenarioEnvQuery; +pub use scenario_tx_env::{ScenarioTxEnv, ScenarioTxEnvData, ScenarioTxRun}; +pub use scenario_tx_whitebox::ScenarioTxWhitebox; 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..339ed9b38b --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_tx_env.rs @@ -0,0 +1,64 @@ +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 interpreter_context: InterpreterContext, + 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 { + self.interpreter_context.clone() + } +} + +impl ScenarioTxEnv for ScenarioTxEnvData { + fn env_data(&self) -> &ScenarioTxEnvData { + self + } +} + +impl ScenarioWorld { + pub(crate) fn new_env_data(&self) -> ScenarioTxEnvData { + ScenarioTxEnvData { + interpreter_context: InterpreterContext::new() + .with_dir(self.current_dir.clone()) + .with_allowed_missing_files(), + 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/facade/world_tx/scenario_tx_whitebox.rs b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs new file mode 100644 index 0000000000..62842a6e25 --- /dev/null +++ b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs @@ -0,0 +1,217 @@ +use crate::debug_executor::contract_instance_wrapped_execution; +use crate::scenario::tx_to_step::TxToQueryStep; +use crate::{ + imports::StaticApi, scenario::tx_to_step::TxToStep, scenario_model::TxResponse, ScenarioEnvExec, +}; +use crate::{DebugApi, ScenarioEnvQuery}; +use multiversx_chain_vm::tx_mock::TxFunctionName; +use multiversx_sc::contract_base::ContractBase; +use multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{ + Code, DeployCall, FunctionCall, RHListExec, Tx, TxCodeValue, TxFromSpecified, TxNoPayment, + TxPayment, TxToSpecified, + }, +}; + +pub trait ScenarioTxWhitebox { + type Returns; + + /// Runs a lambda function in the name of a smart contract, with the configured transaction context. + fn whitebox(self, contract_obj: fn() -> ContractObj, f: F) -> Self::Returns + where + ContractObj: ContractBase + 'static, + F: FnOnce(ContractObj); +} + +impl<'w, From, Payment, CodeValue, RH> ScenarioTxWhitebox + for Tx< + ScenarioEnvExec<'w>, + From, + (), + Payment, + (), + DeployCall, Code>, + RH, + > +where + From: TxFromSpecified>, + Payment: TxNoPayment>, + CodeValue: TxCodeValue>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + fn whitebox( + self, + contract_obj_builder: fn() -> ContractObj, + f: F, + ) -> Self::Returns + where + ContractObj: ContractBase + 'static, + F: FnOnce(ContractObj), + { + let contract_obj = contract_obj_builder(); + + let mut step_wrapper = self.tx_to_step(); + let (new_address, tx_result) = step_wrapper + .env + .world + .get_mut_debugger_backend() + .vm_runner + .perform_sc_deploy_lambda(&step_wrapper.step, || { + contract_instance_wrapped_execution(true, || { + f(contract_obj); + Ok(()) + }); + }); + + let mut response = TxResponse::from_tx_result(tx_result); + response.new_deployed_address = Some(new_address); + step_wrapper.step.save_response(response); + step_wrapper.process_result() + } +} + +impl<'w, From, To, Payment, RH> ScenarioTxWhitebox + for Tx, From, To, Payment, (), (), RH> +where + From: TxFromSpecified>, + To: TxToSpecified>, + Payment: TxPayment>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + fn whitebox( + self, + contract_obj_builder: fn() -> ContractObj, + f: F, + ) -> Self::Returns + where + ContractObj: ContractBase + 'static, + F: FnOnce(ContractObj), + { + self.raw_call(TxFunctionName::WHITEBOX_CALL.as_str()) + .whitebox(contract_obj_builder, f) + } +} + +impl<'w, From, To, Payment, RH> ScenarioTxWhitebox + for Tx, From, To, Payment, (), FunctionCall, RH> +where + From: TxFromSpecified>, + To: TxToSpecified>, + Payment: TxPayment>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + fn whitebox( + self, + contract_obj_builder: fn() -> ContractObj, + f: F, + ) -> Self::Returns + where + ContractObj: ContractBase + 'static, + F: FnOnce(ContractObj), + { + let contract_obj = contract_obj_builder(); + + let mut step_wrapper = self.tx_to_step(); + + // no endpoint is called per se, but if it is empty, the VM thinks it is a simple transfer of value + if step_wrapper.step.tx.function.is_empty() { + step_wrapper.step.tx.function = TxFunctionName::WHITEBOX_CALL.to_string(); + } + + let tx_result = step_wrapper + .env + .world + .get_mut_debugger_backend() + .vm_runner + .perform_sc_call_lambda(&step_wrapper.step, || { + contract_instance_wrapped_execution(true, || { + f(contract_obj); + Ok(()) + }); + }); + + let response = TxResponse::from_tx_result(tx_result); + step_wrapper.step.save_response(response); + step_wrapper.process_result() + } +} + +impl<'w, To, Payment, RH> ScenarioTxWhitebox + for Tx, (), To, Payment, (), (), RH> +where + To: TxToSpecified>, + Payment: TxNoPayment>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + fn whitebox( + self, + contract_obj_builder: fn() -> ContractObj, + f: F, + ) -> Self::Returns + where + ContractObj: ContractBase + 'static, + F: FnOnce(ContractObj), + { + self.raw_call(TxFunctionName::WHITEBOX_CALL.as_str()) + .whitebox(contract_obj_builder, f) + } +} + +impl<'w, To, Payment, RH> ScenarioTxWhitebox + for Tx, (), To, Payment, (), FunctionCall, RH> +where + To: TxToSpecified>, + Payment: TxNoPayment>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + type Returns = ::Unpacked; + + fn whitebox( + self, + contract_obj_builder: fn() -> ContractObj, + f: F, + ) -> Self::Returns + where + ContractObj: ContractBase + 'static, + F: FnOnce(ContractObj), + { + let contract_obj = contract_obj_builder(); + + let mut step_wrapper = self.tx_to_query_step(); + + // no endpoint is called per se, but if it is empty, the VM thinks it is a simple transfer of value + if step_wrapper.step.tx.function.is_empty() { + step_wrapper.step.tx.function = TxFunctionName::WHITEBOX_CALL.to_string(); + } + + let tx_result = step_wrapper + .env + .world + .get_mut_debugger_backend() + .vm_runner + .perform_sc_query_lambda(&step_wrapper.step, || { + contract_instance_wrapped_execution(true, || { + f(contract_obj); + Ok(()) + }); + }); + + let response = TxResponse::from_tx_result(tx_result); + step_wrapper.step.save_response(response); + step_wrapper.process_result() + } +} diff --git a/framework/scenario/src/imports.rs b/framework/scenario/src/imports.rs new file mode 100644 index 0000000000..171862dc9a --- /dev/null +++ b/framework/scenario/src/imports.rs @@ -0,0 +1,26 @@ +pub use crate::multiversx_sc::imports::*; + +pub use crate::multiversx_sc::codec::test_util::*; + +pub use crate::{ + api::{DebugApi, DebugHandle, 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::BigInt as RustBigInt, + 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 d46d27fc68..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,6 +24,8 @@ pub use num_bigint; pub use multiversx_sc; +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. pub use crate::scenario::model as scenario_model; @@ -42,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 912d8d94f5..9748fdf7dc 100644 --- a/framework/scenario/src/scenario/model/account_data/account.rs +++ b/framework/scenario/src/scenario/model/account_data/account.rs @@ -19,6 +19,7 @@ pub struct Account { pub username: Option, pub storage: BTreeMap, pub code: Option, + pub code_metadata: Option, pub owner: Option, pub developer_rewards: Option, } @@ -85,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 @@ -101,6 +102,7 @@ impl Account { U64Value: From, BigUintValue: From, BytesValue: From, + AddressValue: From, { let token_id = BytesKey::from(token_id_expr); @@ -210,6 +212,9 @@ impl InterpretableFrom for Account { }) .collect(), code: from.code.map(|c| BytesValue::interpret_from(c, context)), + code_metadata: from + .code_metadata + .map(|c| BytesValue::interpret_from(c, context)), owner: from.owner.map(|v| AddressValue::interpret_from(v, context)), developer_rewards: from .developer_rewards @@ -236,6 +241,7 @@ impl IntoRaw for Account { .map(|(key, value)| (key.original, value.original)) .collect(), code: self.code.map(|n| n.original), + code_metadata: self.code_metadata.map(|n| n.original), owner: self.owner.map(|n| n.original), developer_rewards: self.developer_rewards.map(|n| n.original), } diff --git a/framework/scenario/src/scenario/model/account_data/account_check.rs b/framework/scenario/src/scenario/model/account_data/account_check.rs index 2366941c02..c7c244d20f 100644 --- a/framework/scenario/src/scenario/model/account_data/account_check.rs +++ b/framework/scenario/src/scenario/model/account_data/account_check.rs @@ -22,6 +22,7 @@ pub struct CheckAccount { pub username: CheckValue, pub storage: CheckStorage, pub code: CheckValue, + pub code_metadata: CheckValue, pub owner: CheckValue, // WARNING! Not currently checked. TODO: implement check pub developer_rewards: CheckValue, pub async_call_data: CheckValue, @@ -65,6 +66,17 @@ impl CheckAccount { self } + pub fn code_metadata(mut self, code_metadata_expr: V) -> Self + where + BytesValue: InterpretableFrom, + { + self.code_metadata = CheckValue::Equal(BytesValue::interpret_from( + code_metadata_expr, + &InterpreterContext::default(), + )); + self + } + pub fn esdt_balance(mut self, token_id_expr: K, balance_expr: V) -> Self where BytesKey: From, @@ -175,6 +187,7 @@ impl InterpretableFrom> for CheckAccount { username: CheckValue::::interpret_from(from.username, context), storage: CheckStorage::interpret_from(from.storage, context), code: CheckValue::::interpret_from(from.code, context), + code_metadata: CheckValue::::interpret_from(from.code_metadata, context), owner: CheckValue::::interpret_from(from.owner, context), developer_rewards: CheckValue::::interpret_from( from.developer_rewards, @@ -198,6 +211,7 @@ impl IntoRaw for CheckAccount { username: self.username.into_raw(), storage: self.storage.into_raw(), code: self.code.into_raw_explicit(), // TODO: convert back to into_raw after VM CI upgrade + code_metadata: self.code_metadata.into_raw(), owner: self.owner.into_raw_explicit(), // TODO: convert back to into_raw after VM CI upgrade developer_rewards: self.developer_rewards.into_raw(), async_call_data: self.async_call_data.into_raw(), 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/log.rs b/framework/scenario/src/scenario/model/transaction/log.rs index 27ebccfd08..803c521bbf 100644 --- a/framework/scenario/src/scenario/model/transaction/log.rs +++ b/framework/scenario/src/scenario/model/transaction/log.rs @@ -1,9 +1,9 @@ -use crate::scenario_model::BytesValue; +use multiversx_sc::types::Address; #[derive(Debug, Clone)] pub struct Log { - pub address: BytesValue, - pub endpoint: BytesValue, - pub topics: Vec, - pub data: BytesValue, + pub address: Address, + pub endpoint: String, + pub topics: Vec>, + pub data: Vec>, } diff --git a/framework/scenario/src/scenario/model/transaction/log_check.rs b/framework/scenario/src/scenario/model/transaction/log_check.rs index f77d302a70..6145a9e161 100644 --- a/framework/scenario/src/scenario/model/transaction/log_check.rs +++ b/framework/scenario/src/scenario/model/transaction/log_check.rs @@ -11,7 +11,7 @@ pub struct CheckLog { pub address: CheckValue, pub endpoint: CheckValue, pub topics: CheckValueList, - pub data: CheckValue, + pub data: CheckValueList, } impl InterpretableFrom for CheckLog { @@ -20,7 +20,7 @@ impl InterpretableFrom for CheckLog { address: CheckValue::::interpret_from(from.address, context), endpoint: CheckValue::::interpret_from(from.endpoint, context), topics: CheckValueList::interpret_from(from.topics, context), - data: CheckValue::::interpret_from(from.data, context), + data: CheckValueList::interpret_from(from.data, context), } } } diff --git a/framework/scenario/src/scenario/model/transaction/tx_call.rs b/framework/scenario/src/scenario/model/transaction/tx_call.rs index 1e14638169..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}, @@ -57,7 +57,7 @@ impl InterpretableFrom for TxCall { .map(|t| BytesValue::interpret_from(t, context)) .collect(), gas_limit: U64Value::interpret_from(from.gas_limit, context), - gas_price: U64Value::interpret_from(from.gas_price, context), + gas_price: U64Value::interpret_from(from.gas_price.unwrap_or_default(), context), } } } @@ -81,14 +81,19 @@ impl IntoRaw for TxCall { .map(|arg| arg.into_raw()) .collect(), gas_limit: self.gas_limit.into_raw(), - gas_price: self.gas_price.into_raw(), + gas_price: self.gas_price.into_raw_opt(), } } } 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_deploy.rs b/framework/scenario/src/scenario/model/transaction/tx_deploy.rs index 02396e99d1..ba6f0c44ca 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_deploy.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_deploy.rs @@ -13,8 +13,8 @@ use super::{tx_interpret_util::interpret_egld_value, DEFAULT_GAS_EXPR}; pub struct TxDeploy { pub from: AddressValue, pub egld_value: BigUintValue, - pub code_metadata: CodeMetadata, pub contract_code: BytesValue, + pub code_metadata: CodeMetadata, pub arguments: Vec, pub gas_limit: U64Value, pub gas_price: U64Value, @@ -47,7 +47,7 @@ impl InterpretableFrom for TxDeploy { .map(|t| BytesValue::interpret_from(t, context)) .collect(), gas_limit: U64Value::interpret_from(from.gas_limit, context), - gas_price: U64Value::interpret_from(from.gas_price, context), + gas_price: U64Value::interpret_from(from.gas_price.unwrap_or_default(), context), } } } @@ -65,7 +65,7 @@ impl IntoRaw for TxDeploy { .map(|arg| arg.into_raw()) .collect(), gas_limit: self.gas_limit.into_raw(), - gas_price: self.gas_price.into_raw(), + gas_price: self.gas_price.into_raw_opt(), } } } 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 68167affdb..8a7a5c4bf9 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_response.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_response.rs @@ -1,17 +1,7 @@ -use crate::multiversx_sc::types::Address; use multiversx_chain_vm::tx_mock::TxResult; -use multiversx_sdk::data::transaction::{ - ApiLogs, ApiSmartContractResult, Events, TransactionOnNetwork, -}; +use multiversx_sc::types::Address; -use super::{ - decode_scr_data_or_panic, is_out_scr, process_topics_error, Log, TxExpect, TxResponseStatus, -}; - -const LOG_IDENTIFIER_SC_DEPLOY: &str = "SCDeploy"; -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. @@ -30,10 +20,6 @@ pub struct TxResponse { pub gas: u64, /// The refund of the transaction. pub refund: u64, - /// The smart contract results of the transaction. - pub api_scrs: Vec, - /// The api logs of the transaction. - pub api_logs: Option, } impl TxResponse { @@ -45,26 +31,20 @@ impl TxResponse { status: tx_result.result_status, message: tx_result.result_message, }, + logs: tx_result + .result_logs + .iter() + .map(|tx_log| Log { + address: Address::from_slice(tx_log.address.as_bytes()), + endpoint: tx_log.endpoint.to_string(), + topics: tx_log.topics.clone(), + data: tx_log.data.clone(), + }) + .collect(), ..Default::default() } } - /// 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() - } - /// Creates a [`TxResponse`] from raw results. pub fn from_raw_results(raw_results: Vec>) -> Self { TxResponse { @@ -100,934 +80,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()).unwrap(); - let error = String::from_utf8(error_raw).unwrap(); - return TxResponseStatus::signal_error(&error); - } - - TxResponseStatus::default() - } - - fn process(self) -> Self { - self.process_out() - .process_new_deployed_address() - .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()).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) -> Self { - if let Some(event) = self.find_log(LOG_IDENTIFIER_SC_DEPLOY).cloned() { - let topics = event.topics.as_ref(); - if process_topics_error(topics).is_some() { - return self; - } - - let address_raw = base64::decode(topics.unwrap().get(0).unwrap()).unwrap(); - let address: Address = Address::from_slice(address_raw.as_slice()); - self.new_deployed_address = Some(address); - } - - self - } - - fn process_new_issued_token_identifier(mut self) -> Self { - let token_identifier_issue_scr: Option<&ApiSmartContractResult> = self - .api_scrs - .iter() - .find(|scr| scr.sender.to_string() == SYSTEM_SC_BECH32 && scr.data.starts_with("@00@")); - - if token_identifier_issue_scr.is_none() { - return self; - } - - let token_identifier_issue_scr = token_identifier_issue_scr.unwrap(); - let encoded_tid = token_identifier_issue_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()); - - 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_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 = 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) - } } 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/check_state.rs b/framework/scenario/src/scenario/run_vm/check_state.rs index dfcceb5c73..abed0212cc 100644 --- a/framework/scenario/src/scenario/run_vm/check_state.rs +++ b/framework/scenario/src/scenario/run_vm/check_state.rs @@ -51,10 +51,20 @@ fn execute(state: &BlockchainState, accounts: &CheckAccounts) { let actual_code = account.contract_path.as_ref().unwrap_or(default_value); assert!( expected_account.code.check(actual_code), - "bad account code. Address: {}. Want: {}. Have: {}", + "bad account code. Address: {}. Want: {}. Have: {} ({} bytes)", expected_address, expected_account.code, - std::str::from_utf8(actual_code.as_slice()).unwrap() + hex::encode(actual_code), + actual_code.len(), + ); + + let actual_code_metadata = account.code_metadata.to_vec(); + assert!( + expected_account.code_metadata.check(&actual_code_metadata), + "bad account code metadata. Address: {}. Want: {}. Have: {}", + expected_address, + expected_account.code_metadata, + hex::encode(actual_code_metadata), ); assert!( 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/sc_deploy.rs b/framework/scenario/src/scenario/run_vm/sc_deploy.rs index 67540877c6..11bb387a6b 100644 --- a/framework/scenario/src/scenario/run_vm/sc_deploy.rs +++ b/framework/scenario/src/scenario/run_vm/sc_deploy.rs @@ -5,6 +5,7 @@ use crate::{ use multiversx_chain_vm::{ tx_execution::execute_current_tx_context_input, tx_mock::{TxFunctionName, TxInput, TxResult}, + types::VMCodeMetadata, }; use super::{check_tx_output, tx_input_util::generate_tx_hash, ScenarioVMRunner}; @@ -34,6 +35,7 @@ impl ScenarioVMRunner { let (new_address, tx_result) = self.blockchain_mock.vm.sc_create( tx_input, contract_code, + VMCodeMetadata::from(sc_deploy_step.tx.code_metadata.bits()), &mut self.blockchain_mock.state, f, ); diff --git a/framework/scenario/src/scenario/run_vm/set_state.rs b/framework/scenario/src/scenario/run_vm/set_state.rs index c09804ae1b..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, + types::VMCodeMetadata, world_mock::{ AccountData, AccountEsdt, BlockInfo as CrateBlockInfo, BlockchainState, EsdtData, EsdtInstance, EsdtInstanceMetadata, EsdtInstances, EsdtRoles, @@ -10,6 +10,9 @@ use multiversx_chain_vm::{ use super::ScenarioVMRunner; +/// Refers to the default of the "setState" scenario step. +pub const DEFAULT_CODE_METADATA: VMCodeMetadata = VMCodeMetadata::all(); + impl ScenarioVMRunner { pub fn perform_set_state(&mut self, set_state_step: &SetStateStep) { execute(&mut self.blockchain_mock.state, set_state_step); @@ -54,6 +57,11 @@ fn execute(state: &mut BlockchainState, set_state_step: &SetStateStep) { .code .as_ref() .map(|bytes_value| bytes_value.value.clone()), + code_metadata: account + .code_metadata + .as_ref() + .map(|bytes_value| VMCodeMetadata::from(&bytes_value.value)) + .unwrap_or(DEFAULT_CODE_METADATA), contract_owner: account .owner .as_ref() @@ -147,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/run_vm/tx_output_check.rs b/framework/scenario/src/scenario/run_vm/tx_output_check.rs index cfe220b968..eeec7a1c4e 100644 --- a/framework/scenario/src/scenario/run_vm/tx_output_check.rs +++ b/framework/scenario/src/scenario/run_vm/tx_output_check.rs @@ -1,7 +1,7 @@ use crate::scenario::model::{CheckLogs, Checkable, TxExpect}; use multiversx_chain_vm::{ - display_util::{address_hex, verbose_hex, verbose_hex_list}, + display_util::{address_hex, verbose_hex_list}, tx_mock::{TxLog, TxResult}, }; @@ -46,20 +46,9 @@ pub fn check_tx_output(tx_id: &str, tx_expect: &TxExpect, tx_result: &TxResult) for (i, actual_log) in tx_result.result_logs.iter().enumerate() { if i < expected_logs.list.len() { let expected_log = &expected_logs.list[i]; - assert!( - scenario_check(actual_log, expected_log), - "Logs do not match. Tx id: '{}'. Index: {}.\nWant: Address: {}, Endpoint: {}, Topics: {:?}, Data: {}\nHave: Address: {}, Endpoint: {}, Topics: {:?}, Data: {}", - tx_id, - i, - &expected_log.address, - &expected_log.endpoint, - &expected_log.topics.pretty_str(), - &expected_log.data, - address_hex(&actual_log.address), - &actual_log.endpoint, - verbose_hex_list(actual_log.topics.as_slice()), - verbose_hex(&actual_log.data), - ); + if let Err(main_message) = scenario_check(actual_log, expected_log) { + panic_log(main_message, tx_id, i, actual_log, expected_log); + } } else if !expected_logs.more_allowed_at_end { panic!( "Unexpected log. Tx id: '{}'. Index: {}.\nAddress: {}, Endpoint: {}, Topics: {:?}, Data: {}", @@ -68,7 +57,7 @@ pub fn check_tx_output(tx_id: &str, tx_expect: &TxExpect, tx_result: &TxResult) address_hex(&actual_log.address), &actual_log.endpoint, verbose_hex_list(actual_log.topics.as_slice()), - verbose_hex(&actual_log.data), + verbose_hex_list(&actual_log.data), ) } } @@ -76,9 +65,47 @@ pub fn check_tx_output(tx_id: &str, tx_expect: &TxExpect, tx_result: &TxResult) } } -fn scenario_check(tx_log: &TxLog, check_log: &crate::scenario::model::CheckLog) -> bool { - check_log.address.check(tx_log.address.as_bytes()) - && check_log.endpoint.check(&tx_log.endpoint) - && check_log.topics.check(tx_log.topics.as_slice()) - && check_log.data.check(tx_log.data.as_slice()) +fn scenario_check( + actual_log: &TxLog, + expected_log: &crate::scenario::model::CheckLog, +) -> Result<(), &'static str> { + if !expected_log.address.check(actual_log.address.as_bytes()) { + return Err("Log address does not match"); + } + if !expected_log.endpoint.check(&actual_log.endpoint) { + return Err("Log endpoint does not match"); + } + + if !expected_log.topics.check(actual_log.topics.as_slice()) { + return Err("Log topics do not match"); + } + + if !expected_log.data.check(actual_log.data.as_slice()) { + return Err("Log data does not match"); + } + + Ok(()) +} + +fn panic_log( + main_message: &str, + tx_id: &str, + log_index: usize, + actual_log: &TxLog, + expected_log: &crate::scenario::model::CheckLog, +) -> ! { + panic!( + "{}. Tx id: '{}'. Index: {}.\nWant: Address: {}, Endpoint: {}, Topics: {:?}, Data: {:?}\nHave: Address: {}, Endpoint: {}, Topics: {:?}, Data: {}", + main_message, + tx_id, + log_index, + &expected_log.address, + &expected_log.endpoint, + &expected_log.topics.pretty_str(), + &expected_log.data.pretty_str(), + address_hex(&actual_log.address), + &actual_log.endpoint, + verbose_hex_list(actual_log.topics.as_slice()), + verbose_hex_list(&actual_log.data), + ); } 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..d2baa6bc6c --- /dev/null +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_transfer.rs @@ -0,0 +1,60 @@ +use multiversx_sc::types::{Tx, TxEnv, TxFromSpecified, TxGas, TxPayment, TxToSpecified}; + +use crate::{imports::TxESDT, 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(); + } else { + step.tx.esdt_value = full_payment_data + .multi_esdt + .iter() + .map(TxESDT::from) + .collect(); + } + + step +} diff --git a/framework/scenario/src/standalone/account_tool.rs b/framework/scenario/src/standalone/account_tool.rs deleted file mode 100644 index 877e75fc18..0000000000 --- a/framework/scenario/src/standalone/account_tool.rs +++ /dev/null @@ -1,141 +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), - 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/vm_go_tool.rs b/framework/scenario/src/vm_go_tool.rs index 54dc00e965..72fbb963f8 100644 --- a/framework/scenario/src/vm_go_tool.rs +++ b/framework/scenario/src/vm_go_tool.rs @@ -1,20 +1,28 @@ use colored::Colorize; -use std::{io::ErrorKind, path::Path, process::Command}; +use std::{ + io::{Error, ErrorKind}, + path::Path, + process::{Command, Output}, +}; -const RUNNER_TOOL_NAME: &str = "run-scenarios"; -const RUNNER_TOOL_NAME_LEGACY: &str = "mandos-test"; +const RUNNER_TOOL_NAME: &str = "mx-scenario-go"; +const RUNNER_TOOL_NAME_LEGACY: &str = "run-scenarios"; /// Just marks that the tool was not found. struct ToolNotFound; /// Runs the VM executable, /// which reads parses and executes one or more mandos tests. -pub fn run_vm_go_tool(absolute_path: &Path) { +pub fn run_mx_scenario_go(absolute_path: &Path) { if cfg!(not(feature = "run-go-tests")) { return; } - if run_scenario_tool(RUNNER_TOOL_NAME, absolute_path).is_ok() { + let output = Command::new(RUNNER_TOOL_NAME) + .arg("run") + .arg(absolute_path) + .output(); + if run_scenario_tool(RUNNER_TOOL_NAME, output).is_ok() { return; } @@ -23,23 +31,24 @@ pub fn run_vm_go_tool(absolute_path: &Path) { "{}", format!("Warning: `{RUNNER_TOOL_NAME}` not found. Using `{RUNNER_TOOL_NAME_LEGACY}` as fallback.").yellow(), ); - if run_scenario_tool(RUNNER_TOOL_NAME_LEGACY, absolute_path).is_ok() { + let output = Command::new(RUNNER_TOOL_NAME_LEGACY) + .arg(absolute_path) + .output(); + if run_scenario_tool(RUNNER_TOOL_NAME_LEGACY, output).is_ok() { return; } panic!("Could not find `{RUNNER_TOOL_NAME_LEGACY}`, aborting."); } -fn run_scenario_tool(tool_name: &str, path: &Path) -> Result<(), ToolNotFound> { - let result = Command::new(tool_name).arg(path).output(); - - if let Err(error) = &result { +fn run_scenario_tool(tool_name: &str, output: Result) -> Result<(), ToolNotFound> { + if let Err(error) = &output { if error.kind() == ErrorKind::NotFound { return Err(ToolNotFound); } } - let output = result.expect("failed to execute process"); + let output = output.expect("failed to execute process"); if output.status.success() { println!("{}", String::from_utf8_lossy(output.stdout.as_slice())); 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 e4e91c7a52..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) { @@ -686,7 +616,7 @@ impl BlockchainStateWrapper { .to(sc_wrapper.address_ref()) .function(TxFunctionName::WHITEBOX_CALL.as_str()) .egld_value(egld_payment) - .gas_limit(u64::MAX) + .gas_limit("100,000,000") .no_expect(); sc_call_step.explicit_tx_hash = Some(H256::zero()); @@ -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/raw_converter.rs b/framework/scenario/src/whitebox_legacy/raw_converter.rs index c9a33b154b..2b390e98ba 100644 --- a/framework/scenario/src/whitebox_legacy/raw_converter.rs +++ b/framework/scenario/src/whitebox_legacy/raw_converter.rs @@ -9,6 +9,7 @@ use crate::{ EsdtFullRaw, EsdtInstanceRaw, EsdtRaw, TxCallRaw, TxESDTRaw, TxExpectRaw, TxQueryRaw, ValueSubTree, }, + scenario_model::U64Value, }; use multiversx_chain_vm::{ types::VMAddress, @@ -46,10 +47,11 @@ pub(crate) fn account_as_raw(acc: &AccountData) -> AccountRaw { AccountRaw { balance: balance_raw, - code: code_raw, comment: None, esdt: all_esdt_raw, nonce: Some(u64_as_raw(acc.nonce)), + code: code_raw, + code_metadata: Some(bytes_as_raw(acc.code_metadata.to_vec())), owner: acc.contract_owner.as_ref().map(vm_address_as_raw), storage: storage_raw, username: None, // TODO: Add if needed @@ -76,10 +78,10 @@ pub(crate) fn esdt_data_as_raw(esdt: &EsdtData) -> EsdtRaw { attributes: Some(bytes_as_raw(&inst.metadata.attributes)), balance: Some(rust_biguint_as_raw(&inst.balance)), creator: inst.metadata.creator.as_ref().map(vm_address_as_raw), - hash: inst.metadata.hash.as_ref().map(|h| bytes_as_raw(h)), + hash: inst.metadata.hash.as_ref().map(bytes_as_raw), nonce: Some(u64_as_raw(inst.nonce)), royalties: Some(u64_as_raw(inst.metadata.royalties)), - uri: inst.metadata.uri.iter().map(|u| bytes_as_raw(u)).collect(), + uri: inst.metadata.uri.iter().map(bytes_as_raw).collect(), }; instances_raw.push(inst_raw); @@ -123,7 +125,7 @@ pub(crate) fn tx_call_as_raw(tx_call: &ScCallMandos) -> TxCallRaw { function: tx_call.function.clone(), arguments: arguments_raw, gas_limit: u64_as_raw(tx_call.gas_limit), - gas_price: u64_as_raw(tx_call.gas_price), + gas_price: u64_as_raw_opt(tx_call.gas_price), } } @@ -243,6 +245,7 @@ pub(crate) fn account_as_check_state_raw(acc: &AccountData) -> CheckAccountsRaw developer_rewards: CheckBytesValueRaw::Equal(rust_biguint_as_raw(&acc.developer_rewards)), storage: CheckStorageRaw::Equal(check_storage_raw), code: CheckBytesValueRaw::Star, + code_metadata: CheckBytesValueRaw::Star, async_call_data: CheckBytesValueRaw::Unspecified, comment: None, username: CheckBytesValueRaw::Unspecified, @@ -299,10 +302,20 @@ pub(crate) fn u64_as_raw(value: u64) -> ValueSubTree { ValueSubTree::Str(value.to_string()) } -pub(crate) fn bytes_as_raw(bytes: &[u8]) -> ValueSubTree { +pub(crate) fn u64_as_raw_opt(value: u64) -> Option { + U64Value::from(value).into_raw_opt() +} + +pub(crate) fn bytes_as_raw(bytes: B) -> ValueSubTree +where + B: AsRef<[u8]>, +{ ValueSubTree::Str(bytes_to_hex(bytes)) } -pub(crate) fn bytes_to_hex(bytes: &[u8]) -> String { +pub(crate) fn bytes_to_hex(bytes: B) -> String +where + B: AsRef<[u8]>, +{ format!("0x{}", hex::encode(bytes)) } 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/address_eq_test.rs b/framework/scenario/tests/address_eq_test.rs new file mode 100644 index 0000000000..af78e6778b --- /dev/null +++ b/framework/scenario/tests/address_eq_test.rs @@ -0,0 +1,39 @@ +use multiversx_sc::types::TestAddress; +use multiversx_sc_scenario::api::StaticApi; + +const ALICE: TestAddress = TestAddress::new("alice"); +const SC_ADDR: TestAddress = TestAddress::new("sc"); + +#[test] +fn test_address_eq() { + let alice2 = TestAddress::new("alice"); + + assert_eq!(ALICE, alice2); + assert_eq!(ALICE, alice2.to_address()); + assert_eq!(ALICE.to_address(), alice2); + assert_eq!(ALICE.to_address(), alice2.to_address()); + + assert_eq!(ALICE, alice2.to_managed_address::()); + assert_eq!(ALICE.to_managed_address::(), alice2); + assert_eq!( + ALICE.to_managed_address::(), + alice2.to_managed_address::() + ); +} + +#[test] +fn test_sc_address_eq() { + let sc2 = TestAddress::new("sc"); + + assert_eq!(SC_ADDR, sc2); + assert_eq!(SC_ADDR, sc2.to_address()); + assert_eq!(SC_ADDR.to_address(), sc2); + assert_eq!(SC_ADDR.to_address(), sc2.to_address()); + + assert_eq!(SC_ADDR, sc2.to_managed_address::()); + assert_eq!(SC_ADDR.to_managed_address::(), sc2); + assert_eq!( + SC_ADDR.to_managed_address::(), + sc2.to_managed_address::() + ); +} diff --git a/framework/scenario/tests/big_float_test.rs b/framework/scenario/tests/big_float_test.rs new file mode 100644 index 0000000000..d103f45208 --- /dev/null +++ b/framework/scenario/tests/big_float_test.rs @@ -0,0 +1,115 @@ +use multiversx_sc::types::{BigFloat, BigInt, BigUint}; +use multiversx_sc_scenario::api::StaticApi; + +#[test] +fn big_float_overflow_test_rs() { + let exp = 1_080i32; + + let first = BigFloat::::from_sci(1_005, -3) + .pow(exp) + .to_fixed_point(&(100_000_000_000_000_000i64.into())) + .into_big_uint(); + + let second = BigFloat::::from_sci(1_005, -3) + .pow(exp) + .to_fixed_point(&(10_000_000_000_000_000i64.into())) + .into_big_uint(); + + let third_float = BigFloat::::from_sci(1_005, -3) + .pow(exp) + .to_managed_decimal_signed(17usize); + let third = third_float.into_raw_units(); + + let forth_float = BigFloat::::from_sci(1_005, -3) + .pow(exp) + .to_managed_decimal_signed(16usize); + let forth = forth_float.into_raw_units(); + + assert_eq!( + first.unwrap_or_sc_panic("unwrap failed"), + /* overflow */ + BigUint::from(9223372036854775807u64) + ); + + assert_eq!( + second.unwrap_or_sc_panic("unwrap failed"), + BigUint::from(2184473079534488064u64) + ); + + assert_eq!( + third, + /* overflow */ + &BigInt::from(9223372036854775807i64) + ); + + assert_eq!(forth, &BigInt::from(2184473079534488064i64)); +} + +#[test] +fn big_float_ln_test_rs() { + let x = BigFloat::::from(23i64); + let ln_x = x.ln().unwrap(); + assert_eq!( + ln_x.to_managed_decimal_signed(9usize).to_string(), + "3.135514648" + ); + assert!(ln_x.is_close( + &BigFloat::from_frac(3135514648, 1_000_000_000), // 3.135514648 + &BigFloat::from_frac(1, 1_000_000_000) + )); + + let big = BigFloat::::from(382747812i64); + let ln_big = big.ln().unwrap(); + assert_eq!( + ln_big.to_managed_decimal_signed(9usize).to_string(), + "19.762913880" + ); + assert!(ln_big.is_close( + &BigFloat::from_frac(19762913880, 1_000_000_000), // 19.762913880 + &BigFloat::from_frac(1, 1_000_000_000) + )); + + let biggest = BigFloat::::from(999999999i64); + let ln_biggest = biggest.ln().unwrap(); + assert_eq!( + ln_biggest.to_managed_decimal_signed(9usize).to_string(), + "20.723319778" + ); + assert!(ln_biggest.is_close( + &BigFloat::from_frac(20723319778, 1_000_000_000), // 20.723319778 + &BigFloat::from_frac(1, 1_000_000_000) + )); + + let small = BigFloat::::from_frac(3i64, 2i64); + let ln_small = small.ln().unwrap(); + assert_eq!( + ln_small.to_managed_decimal_signed(9usize).to_string(), + "0.405448248" + ); + assert!(ln_small.is_close( + &BigFloat::from_frac(405448248, 1_000_000_000), // 0.405448248 + &BigFloat::from_frac(1, 1_000_000_000) + )); + + let smallest = BigFloat::::from(1i64); + let ln_smallest = smallest.ln().unwrap(); + assert_eq!( + ln_smallest.to_managed_decimal_signed(9usize).to_string(), + "0.000000000" + ); + assert!(ln_smallest.is_close( + &BigFloat::from(0i64), // 0.0 + &BigFloat::from_frac(1, 100_000_000) + )); + + let y = BigFloat::::from_frac(11i64, 10i64); + let ln_y = y.ln().unwrap(); + assert_eq!( + ln_y.to_managed_decimal_signed(9usize).to_string(), + "0.095251830" + ); + assert!(ln_y.is_close( + &BigFloat::from_frac(95251830, 1_000_000_000), // 0.095310179 + &BigFloat::from_frac(1, 1_000_000_000) + )); +} diff --git a/framework/scenario/tests/big_uint_test.rs b/framework/scenario/tests/big_uint_test.rs new file mode 100644 index 0000000000..60ad0ab78f --- /dev/null +++ b/framework/scenario/tests/big_uint_test.rs @@ -0,0 +1,22 @@ +use multiversx_sc::types::BigUint; +use multiversx_sc_scenario::api::StaticApi; + +fn assert_big_uint_ln(x: u32, ln_str: &str) { + let x = BigUint::::from(x); + let ln_x = x.ln(); + assert_eq!(ln_x.unwrap().to_string(), ln_str); +} + +#[test] +fn test_big_uint_ln() { + assert_big_uint_ln(23, "3.135514649"); // vs. 3.1354942159291497 first 6 decimals are ok + + assert_big_uint_ln(1, "0.000060599"); + assert_big_uint_ln(2, "0.693207779"); // vs. 0.6931471805599453 + assert_big_uint_ln(3, "1.098595430"); // vs. 1.0986122886681096 + assert_big_uint_ln(4, "1.386354959"); // vs. 1.3862943611198906 + assert_big_uint_ln(5, "1.609481340"); // vs. 1.6094379124341003 + assert_big_uint_ln(6, "1.791742610"); // vs. 1.791759469228055 + + assert_big_uint_ln(1000, "6.907784913"); // vs. 6.907755278982137 +} 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 039b606a83..a08f1a4bbd 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,22 +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) -> SCResult<()> { - let mut sum = self.get_sum(); - sum.add_assign(value); - self.set_sum(&sum); - Ok(()) + #[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) -> SCResult<()> { - 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>; } ///////////////////////////////////////////////////////////////////////////////////////////////// @@ -149,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___) } } @@ -172,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] @@ -185,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) { @@ -195,39 +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", ())); - let result = self.add(value); - multiversx_sc::io::finish_multi::(&result); + 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 @@ -235,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 __wasm__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) } } @@ -289,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 { @@ -309,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, { @@ -336,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, @@ -372,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 @@ -415,35 +782,32 @@ fn contract_without_macros_basic() { let adder = sample_adder::contract_obj::(); - adder.init(&BigInt::from(5)); - assert_eq!(BigInt::from(5), adder.get_sum()); - - let _ = 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()); - let _ = 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()); - let _ = 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 { let mut blockchain = multiversx_sc_scenario::ScenarioWorld::new(); blockchain.register_contract( - "file:../../contracts/examples/adder/output/adder.wasm", + "mxsc:../../contracts/examples/adder/output/adder.mxsc.json", sample_adder::ContractBuilder, ); blockchain 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_buffer_read_to_end_test.rs b/framework/scenario/tests/managed_buffer_read_to_end_test.rs new file mode 100644 index 0000000000..fca0451d7c --- /dev/null +++ b/framework/scenario/tests/managed_buffer_read_to_end_test.rs @@ -0,0 +1,52 @@ +use multiversx_sc::{ + api::ManagedTypeApi, + codec::{ + self, + derive::{TopDecode, TopEncode}, + }, + contract_base::ManagedSerializer, + derive::type_abi, + types::{ManagedBuffer, ManagedBufferReadToEnd}, +}; +use multiversx_sc_scenario::api::StaticApi; + +#[type_abi] +#[derive(TopDecode, TopEncode, Clone, PartialEq, Debug)] +pub struct CallData { + pub endpoint: ManagedBuffer, + pub gas_limit: u64, + pub data: ManagedBufferReadToEnd, +} + +#[test] +fn read_to_end_codec_test() { + let cd: CallData<_> = CallData:: { + endpoint: ManagedBuffer::from("abc"), + gas_limit: 0x100_0000, + data: ManagedBuffer::from("ddd").into(), + }; + + #[rustfmt::skip] + let expected = &[ + /* endpoint length */ 0, 0, 0, 3, + /* endpoint contents */ b'a', b'b', b'c', + /* gas limit */ 0, 0, 0, 0, 1, 0, 0, 0, + /* data */ b'd', b'd', b'd', + ]; + + let encoded = ManagedSerializer::::new().top_encode_to_managed_buffer(&cd); + assert_eq!(encoded.to_boxed_bytes().as_slice(), expected.as_slice()); + + let decoded: CallData = + ManagedSerializer::::new().top_decode_from_managed_buffer(&encoded); + assert_eq!(decoded, cd); + + assert_eq!( + decoded.data.as_managed_buffer(), + &ManagedBuffer::from("ddd") + ); + assert_eq!( + decoded.data.into_managed_buffer(), + ManagedBuffer::from("ddd") + ); +} diff --git a/framework/scenario/tests/managed_decimal_test.rs b/framework/scenario/tests/managed_decimal_test.rs new file mode 100644 index 0000000000..96cfcbf182 --- /dev/null +++ b/framework/scenario/tests/managed_decimal_test.rs @@ -0,0 +1,456 @@ +use multiversx_sc::{ + codec::test_util::{check_dep_encode_decode, check_top_encode_decode}, + derive::{debug_const_managed_decimal, debug_managed_decimal}, + types::{ + BigFloat, BigInt, BigUint, ConstDecimals, ManagedDecimal, ManagedDecimalSigned, NumDecimals, + }, +}; +use multiversx_sc_scenario::api::StaticApi; + +#[test] +pub fn test_managed_decimal() { + let fixed = ManagedDecimal::>::from(BigUint::from(1u64)); + let fixed_2 = ManagedDecimal::>::from(BigUint::from(5u64)); + let fixed_3 = ManagedDecimal::>::from(BigUint::from(8u64)); + + let addition = fixed.clone() + fixed_2.clone(); + assert_eq!( + addition, + ManagedDecimal::>::from(BigUint::from(6u64)) + ); + assert_eq!(addition.into_raw_units(), &BigUint::from(600u64)); + assert_eq!(addition.trunc(), BigUint::from(6u64)); + + let subtraction = addition - fixed; + assert_eq!( + subtraction, + ManagedDecimal::>::from(BigUint::from(5u64)) + ); + + let multiplication = fixed_3.clone() * fixed_2; + assert_eq!( + multiplication, + ManagedDecimal::>::from(BigUint::from(40u64)) + ); + + let division = multiplication / fixed_3; + assert_eq!( + division, + ManagedDecimal::>::from(BigUint::from(5u64)) + ); + + let fixed_4: ManagedDecimal = + ManagedDecimal::from_raw_units(BigUint::from(100u64), 2usize); + let fixed_5 = fixed_4.rescale(2usize); + assert_eq!( + fixed_5, + ManagedDecimal::from_raw_units(BigUint::from(100000000u64), 8usize) + ); + + let fixed_6: ManagedDecimal> = + ManagedDecimal::from(BigUint::from(1500u64)); + let fixed_7 = fixed_6.rescale(ConstDecimals::<8>); + assert_eq!( + fixed_7, + ManagedDecimal::>::from(BigUint::from(1500u64)) + ); + + let fixed_8: ManagedDecimal = + ManagedDecimal::from_raw_units(BigUint::from(5u64), 5usize); + let fixed_9 = fixed_8.rescale(ConstDecimals::<3>); + assert_eq!( + fixed_9, + ManagedDecimal::>::const_decimals_from_raw(BigUint::from( + 500u64 + )) + ); + + let float_1 = BigFloat::::from_frac(3i64, 2i64); + let fixed_float_1 = ManagedDecimalSigned::>::from_big_float( + &float_1, + ConstDecimals::<1>, + ); + let fixed_float_2 = + ManagedDecimalSigned::::from_big_float(&float_1, 1usize); + + assert_eq!( + fixed_float_1, + ManagedDecimalSigned::>::const_decimals_from_raw(BigInt::from( + 15 + )) + ); + assert_eq!( + fixed_float_2, + ManagedDecimalSigned::::from_raw_units(BigInt::from(15), 1usize) + ); +} + +#[test] +fn test_managed_decimal_macros() { + let small = debug_managed_decimal!("3.1"); + assert_eq!(small.scale(), 1usize); + assert_eq!(small.into_raw_units(), &BigUint::from(31u64)); + assert_eq!(&small.trunc(), &BigUint::from(3u64)); + + let three = debug_const_managed_decimal!("1.654"); + assert_eq!(three.scale(), 3usize); + + let four = debug_managed_decimal!("89632.2223"); + assert_eq!(four.scale(), 4usize); + + let huge = debug_const_managed_decimal!("8723.283764652365232"); + assert_eq!(huge.scale(), 15usize); + assert_eq!( + huge.into_raw_units(), + &BigUint::from(8723283764652365232u64) + ); + assert_eq!(&huge.trunc(), &BigUint::from(8723u64)); +} + +#[test] +fn test_managed_decimal_conversion() { + let fixed: ManagedDecimalSigned = + ManagedDecimalSigned::from_raw_units(BigInt::from(123456789123456789i64), 15usize); + //123,45.... + let float_coresp = fixed.to_big_float(); + + // hook not available yet, uncomment when available + // assert_eq!( + // float_coresp.to_buffer(), + // ManagedBuffer::from("123.456789123456789") + // ); + + assert_eq!( + float_coresp, + BigFloat::from_frac(123456789123456789i64, 1_000_000_000_000_000i64), + ); +} + +#[test] +pub fn test_addition_managed_decimal_signed() { + let fixed_1 = ManagedDecimalSigned::>::from(BigInt::from(1i64)); + let fixed_2 = ManagedDecimalSigned::>::from(BigInt::from(3i64)); + let fixed_3 = ManagedDecimalSigned::>::from(BigInt::from(-5i64)); + let fixed_4 = ManagedDecimalSigned::>::from(BigInt::from(-2i64)); + + let addition_1 = fixed_1.clone() + fixed_2.clone(); + assert_eq!( + addition_1, + ManagedDecimalSigned::>::from(BigInt::from(4i64)) + ); + assert_eq!(addition_1.into_raw_units(), &BigInt::from(400i64)); + assert_eq!(addition_1.trunc(), BigInt::from(4i64)); + + let addition_2 = fixed_1.clone() + fixed_3.clone(); + assert_eq!( + addition_2, + ManagedDecimalSigned::>::from(BigInt::from(-4i64)) + ); + assert_eq!(addition_2.into_raw_units(), &BigInt::from(-400i64)); + assert_eq!(addition_2.trunc(), BigInt::from(-4i64)); + + let addition_3 = fixed_3.clone() + fixed_4.clone(); + assert_eq!( + addition_3, + ManagedDecimalSigned::>::from(BigInt::from(-7i64)) + ); + assert_eq!(addition_3.into_raw_units(), &BigInt::from(-700i64)); + assert_eq!(addition_3.trunc(), BigInt::from(-7i64)); + + let addition_4 = fixed_4.clone() + fixed_2.clone(); + assert_eq!( + addition_4, + ManagedDecimalSigned::>::from(BigInt::from(1i64)) + ); + assert_eq!(addition_4.into_raw_units(), &BigInt::from(100i64)); + assert_eq!(addition_4.trunc(), BigInt::from(1i64)); +} + +#[test] +pub fn test_substraction_managed_decimal_signed() { + let fixed_1 = ManagedDecimalSigned::>::from(BigInt::from(1i64)); + let fixed_2 = ManagedDecimalSigned::>::from(BigInt::from(3i64)); + let fixed_3 = ManagedDecimalSigned::>::from(BigInt::from(-5i64)); + let fixed_4 = ManagedDecimalSigned::>::from(BigInt::from(-2i64)); + + let substraction_1 = fixed_2.clone() - fixed_1.clone(); + assert_eq!( + substraction_1, + ManagedDecimalSigned::>::from(BigInt::from(2i64)) + ); + assert_eq!(substraction_1.into_raw_units(), &BigInt::from(200i64)); + assert_eq!(substraction_1.trunc(), BigInt::from(2i64)); + + let substraction_2 = fixed_1.clone() - fixed_2.clone(); + assert_eq!( + substraction_2, + ManagedDecimalSigned::>::from(BigInt::from(-2i64)) + ); + assert_eq!(substraction_2.into_raw_units(), &BigInt::from(-200i64)); + assert_eq!(substraction_2.trunc(), BigInt::from(-2i64)); + + let substraction_3 = substraction_2 - fixed_3.clone(); + assert_eq!( + substraction_3, + ManagedDecimalSigned::>::from(BigInt::from(3i64)) + ); + assert_eq!(substraction_3.into_raw_units(), &BigInt::from(300i64)); + assert_eq!(substraction_3.trunc(), BigInt::from(3i64)); + + let substraction_4 = fixed_3.clone() - fixed_4.clone(); + assert_eq!( + substraction_4, + ManagedDecimalSigned::>::from(BigInt::from(-3i64)) + ); + assert_eq!(substraction_4.into_raw_units(), &BigInt::from(-300i64)); + assert_eq!(substraction_4.trunc(), BigInt::from(-3i64)); +} + +#[test] +pub fn test_multiplication_managed_decimal_signed() { + let fixed_1 = ManagedDecimalSigned::>::from(BigInt::from(1i64)); + let fixed_2 = ManagedDecimalSigned::>::from(BigInt::from(3i64)); + let fixed_3 = ManagedDecimalSigned::>::from(BigInt::from(-5i64)); + let fixed_4 = ManagedDecimalSigned::>::from(BigInt::from(-2i64)); + + let multiplication_1 = fixed_1.clone() * fixed_2.clone(); + assert_eq!( + multiplication_1, + ManagedDecimalSigned::>::from(BigInt::from(3i64)) + ); + + let multiplication_2 = fixed_3.clone() * fixed_2.clone(); + assert_eq!( + multiplication_2, + ManagedDecimalSigned::>::from(BigInt::from(-15i64)) + ); + + let multiplication_2 = fixed_3.clone() * fixed_4.clone(); + assert_eq!( + multiplication_2, + ManagedDecimalSigned::>::from(BigInt::from(10i64)) + ); +} + +#[test] +pub fn test_devision_managed_decimal_signed() { + let fixed_1 = ManagedDecimalSigned::>::from(BigInt::from(6i64)); + let fixed_2 = ManagedDecimalSigned::>::from(BigInt::from(2i64)); + let fixed_3 = ManagedDecimalSigned::>::from(BigInt::from(-8i64)); + let fixed_4 = ManagedDecimalSigned::>::from(BigInt::from(-2i64)); + + let division_1 = fixed_1.clone() / fixed_2; + assert_eq!( + division_1, + ManagedDecimalSigned::>::from(BigInt::from(3i64)) + ); + + let division_2 = fixed_1 / fixed_4.clone(); + assert_eq!( + division_2, + ManagedDecimalSigned::>::from(BigInt::from(-3i64)) + ); + + let division_3 = fixed_3 / fixed_4; + assert_eq!( + division_3, + ManagedDecimalSigned::>::from(BigInt::from(4i64)) + ); +} + +#[test] +pub fn test_rescale_managed_decimal_signed() { + let fixed_1: ManagedDecimalSigned = + ManagedDecimalSigned::from_raw_units(BigInt::from(-10000i64), 2usize); + + let fixed_2 = fixed_1.rescale(3usize); + assert_eq!( + fixed_2, + ManagedDecimalSigned::from_raw_units(BigInt::from(-100000000i64), 6usize) + ); + + let fixed_3: ManagedDecimalSigned> = + ManagedDecimalSigned::from(BigInt::from(-1500i64)); + let fixed_4 = fixed_3.rescale(ConstDecimals::<8>); + assert_eq!(fixed_4.into_raw_units(), &BigInt::from(-150000000000i64)); + + let fixed_5: ManagedDecimalSigned = + ManagedDecimalSigned::from_raw_units(BigInt::from(-5i64), 5usize); + let fixed_6 = fixed_5.rescale(ConstDecimals::<3>); + assert_eq!( + fixed_6, + ManagedDecimalSigned::>::const_decimals_from_raw(BigInt::from( + -500i64 + )) + ); + + let float_1 = BigFloat::::from_frac(-3i64, 2i64); + let fixed_float_1 = ManagedDecimalSigned::>::from_big_float( + &float_1, + ConstDecimals::<1>, + ); + let fixed_float_2 = + ManagedDecimalSigned::::from_big_float(&float_1, 1usize); + + assert_eq!( + fixed_float_1, + ManagedDecimalSigned::>::const_decimals_from_raw(BigInt::from( + -15 + )) + ); + assert_eq!( + fixed_float_2, + ManagedDecimalSigned::::from_raw_units(BigInt::from(-15), 1usize) + ); +} + +#[test] +fn test_encode_decode() { + let fixed_struct: ManagedDecimal = + ManagedDecimal::from_raw_units(BigUint::from(1u64), 1usize); + + #[rustfmt::skip] + let nested_bytes = &[ + /* BigUint */ 0, 0, 0, 0x01, 0x01, + /* usize */ 0, 0, 0, 0x01, + ]; + + check_dep_encode_decode(fixed_struct.clone(), nested_bytes); + check_top_encode_decode(fixed_struct, nested_bytes); + + let fixed_const: ManagedDecimal> = + ManagedDecimal::const_decimals_from_raw(BigUint::from(1u64)); + + #[rustfmt::skip] + let bytes = &[ + /* BigUint */ 0x01, + ]; + + check_top_encode_decode(fixed_const, bytes); +} + +#[test] +fn test_managed_decimal_ln() { + let fixed = + ManagedDecimal::::from_raw_units(BigUint::from(23u64), 0usize); + let ln_fixed = fixed.ln().unwrap(); // precision of 9 decimal points + + assert_eq!(ln_fixed.to_string(), "3.135514649"); + + let const_dec = ManagedDecimal::>::const_decimals_from_raw( + BigUint::from(29299837u64), + ); + let ln_const = const_dec.ln().unwrap(); + + assert_eq!(ln_const.to_string(), "17.193072541"); + + let small = + ManagedDecimal::>::const_decimals_from_raw(BigUint::from(1u64)); // 0.1 + let ln_small = small.ln().unwrap(); + + assert_eq!(ln_small.to_string(), "-2.302524494"); + + let v_small = + ManagedDecimal::>::const_decimals_from_raw(BigUint::from(1u64)); + // 0.01 + let ln_v_small = v_small.ln().unwrap(); + + assert_eq!(ln_v_small.to_string(), "-4.605109587"); + + let smallest = + ManagedDecimal::>::const_decimals_from_raw(BigUint::from(1u64)); + // 0.000001 + let ln_smallest = smallest.ln().unwrap(); + + assert_eq!(ln_smallest.to_string(), "-13.815449959"); + + let frac = ManagedDecimal::>::const_decimals_from_raw( + BigUint::from(322u64), + ); + // 3.22 + let ln_frac = frac.ln().unwrap(); + + assert_eq!(ln_frac.to_string(), "1.169428520"); + + let frac = + ManagedDecimal::::from_raw_units(BigUint::from(288221u64), 3usize); + // 288.221 + let ln_frac = frac.ln().unwrap(); + + assert_eq!(ln_frac.to_string(), "5.663669039"); + + let frac = ManagedDecimal::::from_raw_units( + BigUint::from(288211000000u64), + 9usize, + ); + // 288.211000000 + let ln_frac = frac.ln().unwrap(); + + assert_eq!(ln_frac.to_string(), "5.663649649"); +} + +#[test] +fn test_managed_decimal_log2() { + let fixed = + ManagedDecimal::::from_raw_units(BigUint::from(5u64), 0usize); + let log2_fixed = fixed.log2().unwrap(); + + assert_eq!(log2_fixed.to_string(), "2.321990749"); + + let const_dec = ManagedDecimal::>::const_decimals_from_raw( + BigUint::from(29299837u64), + ); + let log2_const = const_dec.log2().unwrap(); + + assert_eq!(log2_const.to_string(), "24.804360510"); + + let small = + ManagedDecimal::>::const_decimals_from_raw(BigUint::from(1u64)); // 0.1 + let log2_small = small.log2().unwrap(); + + assert_eq!(log2_small.to_string(), "-3.321840669"); + + let v_small = + ManagedDecimal::>::const_decimals_from_raw(BigUint::from(1u64)); + // 0.01 + let log2_v_small = v_small.log2().unwrap(); + + assert_eq!(log2_v_small.to_string(), "-6.643768764"); + + let smallest = + ManagedDecimal::>::const_decimals_from_raw(BigUint::from(1u64)); + // 0.000001 + let log2_smallest = smallest.log2().unwrap(); + + assert_eq!(log2_smallest.to_string(), "-19.931481144"); + + let frac = + ManagedDecimal::::from_raw_units(BigUint::from(1872u64), 2usize); //18.72 + let log2_frac = frac.log2().unwrap(); + + assert_eq!(log2_frac.to_string(), "4.226560385"); + + let b_frac = ManagedDecimal::::from_raw_units( + BigUint::from(39874291763u64), + 7usize, + ); //3987.4291763 + let log2_b_frac = b_frac.log2().unwrap(); + + assert_eq!(log2_b_frac.to_string(), "11.961212882"); + + let normal_prec_frac = + ManagedDecimal::::from_raw_units(BigUint::from(453211u64), 3usize); + // 453.211 + let log2_np_frac = normal_prec_frac.log2().unwrap(); + + assert_eq!(log2_np_frac.to_string(), "8.823994915"); + + let high_prec_frac = ManagedDecimal::::from_raw_units( + BigUint::from(453211000000u64), + 9usize, + ); + // 453.211000000 + let log2_hp_frac = high_prec_frac.log2().unwrap(); + + assert_eq!(log2_hp_frac.to_string(), "8.823953218"); +} diff --git a/framework/scenario/tests/managed_type_debug_test.rs b/framework/scenario/tests/managed_type_debug_test.rs index fbe031ab7e..1342395377 100644 --- a/framework/scenario/tests/managed_type_debug_test.rs +++ b/framework/scenario/tests/managed_type_debug_test.rs @@ -10,26 +10,26 @@ use multiversx_sc_scenario::api::StaticApi; #[test] fn test_big_uint_format() { let s = format!("{:?}", BigUint::::from(0x1234u32)); - assert_eq!("BigUint { handle: -100, hex-value-be: \"1234\" }", s); + assert_eq!("BigUint { handle: -200, hex-value-be: \"1234\" }", s); } #[test] fn test_big_int_format_1() { let s = format!("{:?}", BigInt::::from(0x1234)); - assert_eq!("BigInt { handle: -100, hex-value-be: \"1234\" }", s); + assert_eq!("BigInt { handle: -200, hex-value-be: \"1234\" }", s); } #[test] fn test_big_int_format_2() { let s = format!("{:?}", BigInt::::from(-0x1234)); - assert_eq!("BigInt { handle: -100, hex-value-be: \"edcc\" }", s); + assert_eq!("BigInt { handle: -200, hex-value-be: \"edcc\" }", s); } #[test] fn test_managed_buffer() { let _ = multiversx_sc::hex_literal::hex!("abcd"); let s = format!("{:?}", ManagedBuffer::::from(&[0x12, 0x34])); - assert_eq!("ManagedBuffer { handle: -100, hex-value: \"1234\" }", s); + assert_eq!("ManagedBuffer { handle: -200, hex-value: \"1234\" }", s); } #[test] @@ -37,7 +37,7 @@ fn test_managed_byte_array() { let addr = hex!("01020304050607"); let s = format!("{:?}", ManagedByteArray::::from(&addr)); assert_eq!( - "ManagedByteArray { handle: -100, size: 7, hex-value: \"01020304050607\" }", + "ManagedByteArray { handle: -200, size: 7, hex-value: \"01020304050607\" }", s ); } @@ -46,7 +46,7 @@ fn test_managed_byte_array() { fn test_managed_address() { let addr = hex!("000000000000000000010000000000000000000000000000000000000002ffff"); let s = format!("{:?}", ManagedAddress::::from(&addr)); - assert_eq!("ManagedAddress { handle: -100, hex-value: \"000000000000000000010000000000000000000000000000000000000002ffff\" }", s); + assert_eq!("ManagedAddress { handle: -200, hex-value: \"000000000000000000010000000000000000000000000000000000000002ffff\" }", s); } #[test] @@ -55,7 +55,7 @@ fn test_managed_address_pretty() { let s = format!("{:#?}", ManagedAddress::::from(&addr)); assert_eq!( "ManagedAddress { - handle: -100, + handle: -200, hex-value: \"000000000000000000010000000000000000000000000000000000000002ffff\", }", s @@ -68,7 +68,7 @@ fn test_managed_vec_format_biguint() { mv.push(BigUint::from(1u32)); mv.push(BigUint::from(2u32)); let s = format!("{:?}", &mv); - assert_eq!("[BigUint { handle: -101, hex-value-be: \"01\" }, BigUint { handle: -102, hex-value-be: \"02\" }]", s); + assert_eq!("[BigUint { handle: -201, hex-value-be: \"01\" }, BigUint { handle: -202, hex-value-be: \"02\" }]", s); } #[test] diff --git a/framework/scenario/tests/managed_vec_test.rs b/framework/scenario/tests/managed_vec_test.rs index 5ca2b8ef1b..c24802e599 100644 --- a/framework/scenario/tests/managed_vec_test.rs +++ b/framework/scenario/tests/managed_vec_test.rs @@ -97,6 +97,53 @@ fn test_into_vec() { assert_eq!(vec, managed_vec.into_vec()); } +#[test] +fn test_to_array_of_refs() { + let mut vec = ManagedVec::::new(); + for i in 0..10 { + vec.push(i); + } + + let refs: Option<[i32; 20]> = vec.to_array_of_refs(); + assert!(refs.is_none()); + + let refs: Option<[i32; 10]> = vec.to_array_of_refs(); + assert!(refs.is_some()); + + let refs = refs.unwrap(); + for (i, &item) in refs.iter().enumerate() { + assert_eq!(item, i as i32); + } +} + +#[test] +fn test_take_u64() { + let mut vec = Vec::::new(); + let mut managed_vec = ManagedVec::::new(); + for i in 20u64..=30u64 { + managed_vec.push(i); + vec.push(i); + } + + assert_eq!(managed_vec.len(), 11); + assert_eq!(managed_vec.take(4), 24u64); + assert_eq!(managed_vec.len(), 10); +} + +#[test] +fn test_take_biguint() { + let mut vec = Vec::>::new(); + let mut managed_vec = ManagedVec::>::new(); + for i in 20u64..=30u64 { + let biguint = BigUint::::from(i); + managed_vec.push(biguint.clone()); + vec.push(biguint); + } + assert_eq!(managed_vec.len(), 11); + assert_eq!(managed_vec.take(4), BigUint::::from(24u64)); + assert_eq!(managed_vec.len(), 10); +} + #[test] fn test_sort_u64() { let mut vec = Vec::::new(); @@ -107,8 +154,6 @@ fn test_sort_u64() { } assert!(!managed_vec.is_sorted()); - assert!(managed_vec.is_sorted_by(|a, b| Some(a.cmp(&(b * 10u64))))); - assert!(managed_vec.is_sorted_by_key(|d| d / 10u64 > 1u64)); managed_vec.sort(); vec.sort(); @@ -150,13 +195,11 @@ fn test_sort_by_u64() { assert!(!managed_vec.is_sorted()); - assert!(!managed_vec.is_sorted_by(|a, b| Some(flip(a).cmp(&flip(b))))); managed_vec.sort_by(|a, b| flip(a).cmp(&flip(b))); vec.sort_by_key(flip); assert!(!managed_vec.is_sorted()); - assert!(managed_vec.is_sorted_by(|a, b| Some(flip(a).cmp(&flip(b))))); assert_eq!(vec, managed_vec.into_vec()); } @@ -172,11 +215,6 @@ fn test_sort_by_biguint() { assert!(!managed_vec.is_sorted()); - assert!(!managed_vec.is_sorted_by(|a, b| { - let a_u64 = a.to_u64().unwrap(); - let b_u64 = b.to_u64().unwrap(); - Some(flip(&a_u64).cmp(&flip(&b_u64))) - })); managed_vec.sort_by(|a, b| { let a_u64 = a.to_u64().unwrap(); let b_u64 = b.to_u64().unwrap(); @@ -190,11 +228,6 @@ fn test_sort_by_biguint() { assert!(!managed_vec.is_sorted()); - assert!(managed_vec.is_sorted_by(|a, b| { - let a_u64 = a.to_u64().unwrap(); - let b_u64 = b.to_u64().unwrap(); - Some(flip(&a_u64).cmp(&flip(&b_u64))) - })); assert_eq!(vec, managed_vec.into_vec()); } @@ -209,13 +242,11 @@ fn test_sort_by_key_u64() { assert!(!managed_vec.is_sorted()); - assert!(!managed_vec.is_sorted_by_key(|a| a.to_string().len())); managed_vec.sort_by_key(|a| a.to_string().len()); vec.sort_by_key(|a| a.to_string().len()); assert!(managed_vec.is_sorted()); - assert!(managed_vec.is_sorted_by_key(|a| a.to_string().len())); assert_eq!(vec, managed_vec.into_vec()); } @@ -231,13 +262,11 @@ fn test_sort_by_key_biguint() { assert!(!managed_vec.is_sorted()); - assert!(!managed_vec.is_sorted_by_key(|a| a.to_u64().unwrap().to_string().len())); managed_vec.sort_by_key(|a| a.to_u64().unwrap().to_string().len()); vec.sort_by_key(|a| a.to_u64().unwrap().to_string().len()); assert!(managed_vec.is_sorted()); - assert!(managed_vec.is_sorted_by_key(|a| a.to_u64().unwrap().to_string().len())); assert_eq!(vec, managed_vec.into_vec()); } @@ -252,7 +281,6 @@ fn test_sort_by_cached_key_u64() { managed_vec.sort_by_cached_key(|a| a.to_string()); vec.sort_by_cached_key(|a| a.to_string()); - assert!(managed_vec.is_sorted_by_key(|a| a.to_string())); let managed_vec_as_vec = managed_vec.into_vec(); assert_eq!(managed_vec_as_vec, [1111u64, 222u64, 33u64, 4u64]); assert_eq!(vec, managed_vec_as_vec); @@ -270,7 +298,6 @@ fn test_sort_by_cached_key_biguint() { managed_vec.sort_by_cached_key(|a| a.to_u64().unwrap().to_string()); vec.sort_by_cached_key(|a| a.to_u64().unwrap().to_string()); - assert!(managed_vec.is_sorted_by_key(|a| a.to_u64().unwrap().to_string())); let managed_vec_as_vec = managed_vec.into_vec(); assert_eq!(managed_vec_as_vec, [1111u64, 222u64, 33u64, 4u64]); assert_eq!(vec, managed_vec_as_vec); @@ -316,13 +343,11 @@ fn test_sort_unstable_by_u64() { assert!(!managed_vec.is_sorted()); - assert!(!managed_vec.is_sorted_by(|a, b| Some(flip(a).cmp(&flip(b))))); managed_vec.sort_unstable_by(|a, b| flip(a).cmp(&flip(b))); vec.sort_unstable_by_key(flip); assert!(!managed_vec.is_sorted()); - assert!(managed_vec.is_sorted_by(|a, b| Some(flip(a).cmp(&flip(b))))); assert_eq!(vec, managed_vec.into_vec()); } @@ -338,11 +363,6 @@ fn test_sort_unstable_by_biguint() { assert!(!managed_vec.is_sorted()); - assert!(!managed_vec.is_sorted_by(|a, b| { - let a_u64 = a.to_u64().unwrap(); - let b_u64 = b.to_u64().unwrap(); - Some(flip(&a_u64).cmp(&flip(&b_u64))) - })); managed_vec.sort_unstable_by(|a, b| { let a_u64 = a.to_u64().unwrap(); let b_u64 = b.to_u64().unwrap(); @@ -356,11 +376,6 @@ fn test_sort_unstable_by_biguint() { assert!(!managed_vec.is_sorted()); - assert!(managed_vec.is_sorted_by(|a, b| { - let a_u64 = a.to_u64().unwrap(); - let b_u64 = b.to_u64().unwrap(); - Some(flip(&a_u64).cmp(&flip(&b_u64))) - })); assert_eq!(vec, managed_vec.into_vec()); } @@ -375,13 +390,11 @@ fn test_sort_unstable_by_key_u64() { assert!(!managed_vec.is_sorted()); - assert!(!managed_vec.is_sorted_by_key(|a| a.to_string().len())); managed_vec.sort_unstable_by_key(|a| a.to_string().len()); vec.sort_unstable_by_key(|a| a.to_string().len()); assert!(managed_vec.is_sorted()); - assert!(managed_vec.is_sorted_by_key(|a| a.to_string().len())); assert_eq!(vec, managed_vec.into_vec()); } @@ -397,13 +410,11 @@ fn test_sort_unstable_by_key_biguint() { assert!(!managed_vec.is_sorted()); - assert!(!managed_vec.is_sorted_by_key(|a| a.to_u64().unwrap().to_string().len())); managed_vec.sort_unstable_by_key(|a| a.to_u64().unwrap().to_string().len()); vec.sort_unstable_by_key(|a| a.to_u64().unwrap().to_string().len()); assert!(managed_vec.is_sorted()); - assert!(managed_vec.is_sorted_by_key(|a| a.to_u64().unwrap().to_string().len())); assert_eq!(vec, managed_vec.into_vec()); } diff --git a/framework/scenario/tests/scenarios-io/example_normalized.scen.json b/framework/scenario/tests/scenarios-io/example_normalized.scen.json index e506eef27d..1908c31fba 100644 --- a/framework/scenario/tests/scenarios-io/example_normalized.scen.json +++ b/framework/scenario/tests/scenarios-io/example_normalized.scen.json @@ -152,7 +152,7 @@ ] } }, - "code": "file:smart-contract.wasm", + "code": "mxsc:smart-contract.mxsc.json", "owner": "address:alice", "developerRewards": "100" } @@ -233,7 +233,9 @@ "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b000000000000000000000000", "0x1234123400000000000000000000000000000000000000000000000000000004" ], - "data": "0x00" + "data": [ + "0x00" + ] }, "+" ], @@ -255,8 +257,7 @@ ], "function": "someFunctionName", "arguments": [], - "gasLimit": "0x100000", - "gasPrice": "0" + "gasLimit": "0x100000" } }, { @@ -268,8 +269,7 @@ "to": "0x1000000000000000000000000000000000000000000000000000000000000000", "function": "someFunctionName", "arguments": [], - "gasLimit": "0x100000", - "gasPrice": "0" + "gasLimit": "0x100000" }, "expect": { "status": "" @@ -284,8 +284,7 @@ "to": "0x1000000000000000000000000000000000000000000000000000000000000000", "function": "someFunctionName", "arguments": [], - "gasLimit": "0x100000", - "gasPrice": "0" + "gasLimit": "0x100000" }, "expect": { "out": [], @@ -437,7 +436,7 @@ "str:anything-goes": "*", "+": "" }, - "code": "file:smart-contract.wasm", + "code": "mxsc:smart-contract.mxsc.json", "owner": "address:bob" }, "address:smart_contract_address_2": { diff --git a/framework/scenario/tests/scenarios-io/example_raw.scen.json b/framework/scenario/tests/scenarios-io/example_raw.scen.json index adcb971db3..439eb5b13a 100644 --- a/framework/scenario/tests/scenarios-io/example_raw.scen.json +++ b/framework/scenario/tests/scenarios-io/example_raw.scen.json @@ -153,7 +153,7 @@ ] } }, - "code": "file:smart-contract.wasm", + "code": "mxsc:smart-contract.mxsc.json", "owner": "address:alice", "developerRewards": "100" } @@ -235,7 +235,9 @@ "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b000000000000000000000000", "0x1234123400000000000000000000000000000000000000000000000000000004" ], - "data": "0x00" + "data": [ + "0x00" + ] }, "+" ], @@ -465,7 +467,7 @@ "str:anything-goes": "*", "+": "" }, - "code": "file:smart-contract.wasm", + "code": "mxsc:smart-contract.mxsc.json", "owner": "address:bob" }, "address:smart_contract_address_2": { diff --git a/framework/scenario/tests/scenarios-self/builtin-func-esdt-transfer.scen.json b/framework/scenario/tests/scenarios-self/builtin-func-esdt-transfer.scen.json index 375b63b805..359182460a 100644 --- a/framework/scenario/tests/scenarios-self/builtin-func-esdt-transfer.scen.json +++ b/framework/scenario/tests/scenarios-self/builtin-func-esdt-transfer.scen.json @@ -42,7 +42,7 @@ "100", "address:B" ], - "data": "" + "data": "*" } ], "gas": "*", diff --git a/framework/scenario/tests/scenarios-self/set-check/set-check-codemetadata.err.json b/framework/scenario/tests/scenarios-self/set-check/set-check-codemetadata.err.json new file mode 100644 index 0000000000..f1587f9844 --- /dev/null +++ b/framework/scenario/tests/scenarios-self/set-check/set-check-codemetadata.err.json @@ -0,0 +1,24 @@ +{ + "comment": "verifies that setState and checkState are consistent", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:contract-address": { + "code": "file:set-check-esdt.scen.json", + "codeMetadata": "0x0101" + } + } + }, + { + "step": "checkState", + "id": "check-1", + "accounts": { + "sc:contract-address": { + "code": "*", + "codeMetadata": "0x0000" + } + } + } + ] +} diff --git a/framework/scenario/tests/scenarios-self/set-check/set-check-codemetadata.scen.json b/framework/scenario/tests/scenarios-self/set-check/set-check-codemetadata.scen.json new file mode 100644 index 0000000000..3111b01d9e --- /dev/null +++ b/framework/scenario/tests/scenarios-self/set-check/set-check-codemetadata.scen.json @@ -0,0 +1,52 @@ +{ + "comment": "verifies that setState and checkState are consistent", + "steps": [ + { + "step": "setState", + "accounts": { + "sc:contract-address": { + "code": "file:set-check-esdt.scen.json" + } + } + }, + { + "step": "checkState", + "id": "check-default", + "accounts": { + "sc:contract-address": { + "code": "*", + "codeMetadata": "0x0506" + } + } + }, + { + "step": "setState", + "accounts": { + "sc:contract-address": { + "code": "file:set-check-esdt.scen.json", + "codeMetadata": "0x0102" + } + } + }, + { + "step": "checkState", + "id": "check-1", + "accounts": { + "sc:contract-address": { + "code": "*", + "codeMetadata": "0x0102" + } + } + }, + { + "step": "checkState", + "id": "check-2", + "accounts": { + "sc:contract-address": { + "code": "*", + "codeMetadata": "*" + } + } + } + ] +} diff --git a/framework/scenario/tests/scenarios_self_test.rs b/framework/scenario/tests/scenarios_self_test.rs index 9c07db430d..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. @@ -66,6 +64,17 @@ fn set_check_code() { world().run("tests/scenarios-self/set-check/set-check-code.scen.json"); } +#[test] +#[should_panic] +fn set_check_codemetadata_err_rs() { + world().run("tests/scenarios-self/set-check/set-check-codemetadata.err.json"); +} + +#[test] +fn set_check_codemetadata() { + world().run("tests/scenarios-self/set-check/set-check-codemetadata.scen.json"); +} + #[test] #[should_panic] fn set_check_esdt_err_rs() { diff --git a/framework/scenario/tests/test_hash_set_mapper.rs b/framework/scenario/tests/test_hash_set_mapper.rs index ed4efac19c..44dcf395e2 100644 --- a/framework/scenario/tests/test_hash_set_mapper.rs +++ b/framework/scenario/tests/test_hash_set_mapper.rs @@ -1,6 +1,9 @@ -use multiversx_sc::storage::{ - mappers::{SetMapper, StorageClearable, StorageMapper}, - StorageKey, +use multiversx_sc::{ + storage::{ + mappers::{SetMapper, StorageClearable, StorageMapper, StorageMapperFromAddress}, + StorageKey, + }, + types::ManagedAddress, }; use multiversx_sc_scenario::api::SingleTxApi; @@ -9,6 +12,13 @@ fn create_set() -> SetMapper { SetMapper::new(base_key) } +fn create_set_at_address( + address: ManagedAddress, +) -> SetMapper> { + let base_key = StorageKey::new(&b"my_remote_set"[..]); + SetMapper::new_from_address(address, base_key) +} + fn check_set(set: &SetMapper, expected: Vec) { assert_eq!(set.len(), expected.len()); assert!(set.check_internal_consistency()); @@ -16,6 +26,14 @@ fn check_set(set: &SetMapper, expected: Vec) { assert_eq!(actual, expected); } +fn check_set_at_address( + set: &SetMapper>, + expected_len: usize, +) { + assert_eq!(set.len(), expected_len); + assert!(set.check_internal_consistency()); +} + #[test] fn test_hash_set_simple() { let mut set = create_set(); @@ -80,3 +98,9 @@ fn test_set_clear() { assert_eq!(set.len(), 0); assert!(set.is_empty()); } + +#[test] +fn test_set_at_address() { + let set = create_set_at_address(ManagedAddress::default()); + check_set_at_address(&set, 0usize); +} diff --git a/framework/scenario/tests/test_print_api.rs b/framework/scenario/tests/test_print_api.rs index f61cb78ea1..a15c91601d 100644 --- a/framework/scenario/tests/test_print_api.rs +++ b/framework/scenario/tests/test_print_api.rs @@ -6,13 +6,13 @@ fn test_print_api() { let zero = BigUint::::from(0u64); assert_eq!( format!("{:?}", BigUintPrinter { value: zero }), - "BigUint { handle: -100, hex: \"00\", dec: \"0\" }" + "BigUint { handle: -200, hex: \"00\", dec: \"0\" }" ); let regular = BigUint::::from(257u64); assert_eq!( format!("{:?}", BigUintPrinter { value: regular }), - "BigUint { handle: -101, hex: \"0101\", dec: \"257\" }" + "BigUint { handle: -201, hex: \"0101\", dec: \"257\" }" ); let huge_number = BigUint::::from_bytes_be(&[ @@ -21,6 +21,6 @@ fn test_print_api() { ]); assert_eq!( format!("{:?}", BigUintPrinter { value: huge_number }), - "BigUint { handle: -102, hex: \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\", dec: \"7588550360256754183279148073529370729071901715047420004889892225542594864082845695\" }" + "BigUint { handle: -202, hex: \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\", dec: \"7588550360256754183279148073529370729071901715047420004889892225542594864082845695\" }" ); } diff --git a/framework/scenario/tests/test_vec_mapper.rs b/framework/scenario/tests/test_vec_mapper.rs index f7bc6587e4..92002fcc80 100644 --- a/framework/scenario/tests/test_vec_mapper.rs +++ b/framework/scenario/tests/test_vec_mapper.rs @@ -79,6 +79,20 @@ fn test_vec_swap_remove() { check_vec(&vect, vec![42, 45]); } +#[test] +fn test_vec_update() { + let mut vect = create_vec(); + + vect.extend_from_slice(&[42, 43, 44, 45, 46]); + + assert_eq!(vect.len(), 5); + assert_eq!(vect.get(5), 46); + vect.update(5, |item| *item = 42); + assert_eq!(vect.len(), 5); + assert_eq!(vect.get(5), 42); + check_vec(&vect, vec![42, 43, 44, 45, 42]); +} + #[test] fn test_vec_iter_processing() { let mut vect = create_vec(); diff --git a/framework/snippets/Cargo.toml b/framework/snippets/Cargo.toml index e9922919e7..43ca798a69 100644 --- a/framework/snippets/Cargo.toml +++ b/framework/snippets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sc-snippets" -version = "0.44.0" +version = "0.53.0" edition = "2021" authors = ["MultiversX "] @@ -16,15 +16,22 @@ categories = ["cryptography::cryptocurrencies"] [dependencies] tokio = { version = "1.24", features = ["full"] } hex = "0.4" -base64 = "0.13.0" +base64 = "0.22" log = "0.4.17" -env_logger = "0.10" +env_logger = "0.11" futures = "0.3" [dependencies.multiversx-sc-scenario] -version = "=0.44.0" +version = "=0.53.0" path = "../scenario" +[dependencies.multiversx-chain-scenario-format] +version = "0.23.0" +path = "../../sdk/scenario-format" + [dependencies.multiversx-sdk] -version = "=0.2.0" +version = "=0.6.0" 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..a22c969887 --- /dev/null +++ b/framework/snippets/src/imports.rs @@ -0,0 +1,10 @@ +pub use crate::multiversx_sc_scenario::imports::*; + +pub use crate::{ + dns_address_for_name, test_wallets, Interactor, InteractorPrepareAsync, StepBuffer, +}; + +pub use multiversx_sdk::{data::keystore::InsertPassword, wallet::Wallet}; + +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 80% rename from framework/snippets/src/interactor_sc_call.rs rename to framework/snippets/src/interactor_scenario/interactor_sc_call.rs index e7ab40d419..6802304ae9 100644 --- a/framework/snippets/src/interactor_sc_call.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_call.rs @@ -1,12 +1,11 @@ -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; +use multiversx_sdk::{data::transaction::Transaction, utils::base64_encode}; impl Interactor { pub async fn sc_call(&mut self, mut sc_call_step: S) @@ -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,13 +44,14 @@ 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); let data = if contract_call_tx_data.is_empty() { None } else { - Some(base64::encode(contract_call_tx_data)) + Some(String::from_utf8(base64_encode(contract_call_tx_data).into()).unwrap()) }; Transaction { @@ -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 74% rename from framework/snippets/src/interactor_sc_deploy.rs rename to framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs index f2808fb9ee..59de249e83 100644 --- a/framework/snippets/src/interactor_sc_deploy.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs @@ -1,11 +1,14 @@ -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}, + utils::base64_encode, }; -use multiversx_sdk::data::{address::Address as ErdrsAddress, transaction::Transaction}; const DEPLOY_RECEIVER: [u8; 32] = [0u8; 32]; @@ -18,7 +21,7 @@ impl Interactor { receiver: ErdrsAddress::from_bytes(DEPLOY_RECEIVER), gas_price: self.network_config.min_gas_price, gas_limit: sc_deploy_step.tx.gas_limit.value, - data: Some(base64::encode(sc_deploy_step.tx.to_tx_data())), + data: Some(base64_encode(sc_deploy_step.tx.to_tx_data())), signature: None, chain_id: self.network_config.chain_id.clone(), version: self.network_config.min_transaction_version, @@ -50,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 80% rename from framework/snippets/src/interactor_vm_query.rs rename to framework/snippets/src/interactor_scenario/interactor_vm_query.rs index f4b21e2594..aa9f87efb7 100644 --- a/framework/snippets/src/interactor_vm_query.rs +++ b/framework/snippets/src/interactor_scenario/interactor_vm_query.rs @@ -1,12 +1,14 @@ +#![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; +use multiversx_sdk::{data::vm::VmValueRequest, utils::base64_decode}; impl Interactor { pub async fn sc_query(&mut self, mut step: S) -> &mut Self @@ -39,12 +41,8 @@ impl Interactor { info!("{:#?}", result); - let raw_results: Vec> = result - .data - .return_data - .iter() - .map(|result| base64::decode(result).expect("query result base64 decode error")) - .collect(); + let raw_results: Vec> = result.data.return_data.iter().map(base64_decode).collect(); + step.save_response(TxResponse::from_raw_results(raw_results)); self.pre_runners.run_sc_query_step(step); @@ -55,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..1075cc533f --- /dev/null +++ b/framework/snippets/src/interactor_tx.rs @@ -0,0 +1,24 @@ +#![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_exec_upgrade; +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_exec_upgrade.rs b/framework/snippets/src/interactor_tx/interactor_exec_upgrade.rs new file mode 100644 index 0000000000..af68999830 --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_exec_upgrade.rs @@ -0,0 +1,105 @@ +use multiversx_sc_scenario::{ + imports::{NotPayable, ScCallStep, TxToSpecified, UpgradeCall}, + multiversx_sc::{ + tuple_util::NestedTupleFlatten, + types::{ + Code, DeployCall, RHListExec, Tx, TxBaseWithEnv, TxCodeValue, TxFromSpecified, TxGas, + TxPayment, + }, + }, + scenario::tx_to_step::{address_annotated, code_annotated, StepWrapper, TxToStep}, + scenario_model::{ScDeployStep, TxResponse}, + ScenarioTxEnvData, +}; + +use crate::Interactor; + +use super::{InteractorEnvExec, InteractorExecStep, InteractorPrepareAsync}; + +impl<'w, From, To, Gas, CodeValue, RH> InteractorPrepareAsync + for Tx< + InteractorEnvExec<'w>, + From, + To, + NotPayable, + Gas, + UpgradeCall, Code>, + RH, + > +where + From: TxFromSpecified>, + To: TxToSpecified>, + Gas: TxGas>, + CodeValue: TxCodeValue>, + 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, From, To, Gas, RH, CodeValue> TxToStep, RH> + for Tx< + InteractorEnvExec<'w>, + From, + To, + NotPayable, + Gas, + UpgradeCall, Code>, + RH, + > +where + From: TxFromSpecified>, + To: TxToSpecified>, + Gas: TxGas>, + CodeValue: TxCodeValue>, + RH: RHListExec>, + RH::ListReturns: NestedTupleFlatten, +{ + 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.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_upgrade_step<'a, 'w: 'a, From, To, Gas, CodeValue>( + env: &'a InteractorEnvExec<'w>, + from: From, + to: To, + gas: Gas, + data: UpgradeCall, Code>, +) -> ScCallStep +where + From: TxFromSpecified>, + To: TxToSpecified>, + Gas: TxGas>, + CodeValue: TxCodeValue>, +{ + let mut step = ScCallStep::new() + .from(address_annotated(env, &from)) + .to(address_annotated(env, &to)) + .gas_limit(gas.gas_value(env)) + .function("upgradeContract") + .argument(code_annotated(env, data.code_source)) + .argument(data.code_metadata.to_byte_array().to_vec()); + + for arg in data.arg_buffer.iter_buffers() { + step.tx.arguments.push(arg.to_vec().into()); + } + + step +} 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..073641f811 --- /dev/null +++ b/framework/snippets/src/interactor_tx/interactor_prepare_async.rs @@ -0,0 +1,18 @@ +use multiversx_sc_scenario::{imports::InterpreterContext, ScenarioTxEnvData}; + +use crate::Interactor; + +impl Interactor { + pub(crate) fn new_env_data(&self) -> ScenarioTxEnvData { + ScenarioTxEnvData { + interpreter_context: InterpreterContext::new().with_dir(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..0140dd839e --- /dev/null +++ b/framework/snippets/src/network_response.rs @@ -0,0 +1,232 @@ +use multiversx_sc_scenario::{ + imports::{Address, ESDTSystemSCAddress}, + multiversx_chain_vm::crypto_functions::keccak256, + scenario_model::{Log, 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 tx_error = process_signal_error(&tx); + if !tx_error.is_success() { + return TxResponse { + tx_error, + ..Default::default() + }; + } + + process_success(&tx) +} + +fn process_signal_error(tx: &TransactionOnNetwork) -> TxResponseStatus { + if let Some(event) = find_log(tx, 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_success(tx: &TransactionOnNetwork) -> TxResponse { + TxResponse { + out: process_out(tx), + new_deployed_address: process_new_deployed_address(tx), + new_issued_token_identifier: process_new_issued_token_identifier(tx), + logs: process_logs(tx), + ..Default::default() + } +} + +fn process_out(tx: &TransactionOnNetwork) -> Vec> { + let out_scr = tx.smart_contract_results.iter().find(is_out_scr); + + if let Some(out_scr) = out_scr { + decode_scr_data_or_panic(&out_scr.data) + } else { + process_out_from_log(tx).unwrap_or_default() + } +} + +fn process_logs(tx: &TransactionOnNetwork) -> Vec { + if let Some(api_logs) = &tx.logs { + return api_logs + .events + .iter() + .map(|event| Log { + address: Address::from_slice(&event.address.to_bytes()), + endpoint: event.identifier.clone(), + topics: extract_topics(event), + data: extract_data(event), + }) + .collect::>(); + } + + Vec::new() +} + +fn extract_data(event: &Events) -> Vec> { + let mut out: Vec> = Vec::new(); + event + .data + .for_each(|data_field| out.push(data_field.clone().into_bytes())); + out +} + +fn extract_topics(event: &Events) -> Vec> { + event + .topics + .clone() + .unwrap_or_default() + .into_iter() + .map(|s| s.into_bytes()) + .collect() +} + +fn process_out_from_log(tx: &TransactionOnNetwork) -> Option>> { + if let Some(logs) = &tx.logs { + logs.events.iter().rev().find_map(|event| { + if event.identifier == "writeLog" { + let mut out = Vec::new(); + event.data.for_each(|data_member| { + let decoded_data = String::from_utf8(base64_decode(data_member)).unwrap(); + + if decoded_data.starts_with('@') { + let out_content = decode_scr_data_or_panic(decoded_data.as_str()); + out.extend(out_content); + } + }); + return Some(out); + } + + None + }) + } else { + None + } +} + +fn process_new_deployed_address(tx: &TransactionOnNetwork) -> Option
{ + if tx.processing_type_on_destination != SC_DEPLOY_PROCESSING_TYPE { + return None; + } + + let sender_address_bytes = tx.sender.to_bytes(); + let sender_nonce_bytes = tx.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]); + + Some(Address::from(address)) +} + +fn process_new_issued_token_identifier(tx: &TransactionOnNetwork) -> Option { + let original_tx_data = String::from_utf8(base64_decode(tx.data.as_ref().unwrap())).unwrap(); + + for scr in tx.smart_contract_results.iter() { + if scr.sender.to_bech32_string().unwrap() != ESDTSystemSCAddress.to_bech32_string() { + continue; + } + + let prev_tx_data: &str = if let Some(prev_tx) = tx + .smart_contract_results + .iter() + .find(|e| e.hash == scr.prev_tx_hash) + { + prev_tx.data.as_ref() + } else if &scr.prev_tx_hash == tx.hash.as_ref().unwrap() { + &original_tx_data + } 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); + return Some(String::from_utf8(hex::decode(encoded_tid?).unwrap()).unwrap()); + } else if scr.data.starts_with("@00@") || scr.data.starts_with("@6f6b@") { + let encoded_tid = scr.data.split('@').nth(2); + return Some(String::from_utf8(hex::decode(encoded_tid?).unwrap()).unwrap()); + } + } + None +} + +fn find_log<'a>(tx: &'a TransactionOnNetwork, log_identifier: &str) -> Option<&'a Events> { + if let Some(logs) = &tx.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..4fee781b7f --- /dev/null +++ b/framework/snippets/tests/test_tx_multiple_sc_results.rs @@ -0,0 +1,289 @@ +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; + assert_eq!(tx_on_network.smart_contract_results.len(), 4usize); + assert!(is_out_scr( + &tx_on_network.smart_contract_results.get(2).unwrap() + )); + let _ = network_response::parse_tx_response(tx_on_network); +} 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 e5049c88fd..ada19fe7d3 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.44.0" +version = "0.53.0" edition = "2021" authors = [ @@ -22,5 +22,5 @@ categories = [ ] [dependencies.multiversx-sc] -version = "=0.44.0" +version = "=0.53.0" path = "../base" diff --git a/framework/wasm-adapter/src/api/blockchain_api_node.rs b/framework/wasm-adapter/src/api/blockchain_api_node.rs index 011d4e4e05..0c72cacaf8 100644 --- a/framework/wasm-adapter/src/api/blockchain_api_node.rs +++ b/framework/wasm-adapter/src/api/blockchain_api_node.rs @@ -83,6 +83,10 @@ extern "C" { fn managedIsESDTLimitedTransfer(tokenIDHandle: i32) -> i32; fn getESDTLocalRoles(tokenhandle: i32) -> i64; + + fn managedGetCodeMetadata(addressHandle: i32, resultHandle: i32); + + fn managedIsBuiltinFunction(function_name_handle: i32) -> bool; } impl BlockchainApi for VmApiImpl { @@ -356,10 +360,22 @@ impl BlockchainApiImpl for VmApiImpl { &self, token_id_handle: Self::ManagedBufferHandle, ) -> multiversx_sc::types::EsdtLocalRoleFlags { + multiversx_sc::types::EsdtLocalRoleFlags::from_bits_retain(unsafe { + getESDTLocalRoles(token_id_handle) + } as u64) + } + + fn managed_is_builtin_function(&self, function_name_handle: Self::ManagedBufferHandle) -> bool { + unsafe { managedIsBuiltinFunction(function_name_handle) } + } + + fn managed_get_code_metadata( + &self, + address_handle: Self::ManagedBufferHandle, + response_handle: Self::ManagedBufferHandle, + ) { unsafe { - multiversx_sc::types::EsdtLocalRoleFlags::from_bits_unchecked(getESDTLocalRoles( - token_id_handle, - ) as u64) + managedGetCodeMetadata(address_handle, response_handle); } } } diff --git a/framework/wasm-adapter/src/api/crypto_api_node.rs b/framework/wasm-adapter/src/api/crypto_api_node.rs index eb16e25e6a..df62b30df9 100644 --- a/framework/wasm-adapter/src/api/crypto_api_node.rs +++ b/framework/wasm-adapter/src/api/crypto_api_node.rs @@ -25,6 +25,16 @@ extern "C" { ) -> i32; fn managedEncodeSecp256k1DerSignature(rHandle: i32, sHandle: i32, sigHandle: i32) -> i32; + + fn managedVerifySecp256r1(keyHandle: i32, messageHandle: i32, sigHandle: i32) -> i32; + + fn managedVerifyBLSSignatureShare(keyHandle: i32, messageHandle: i32, sigHandle: i32) -> i32; + + fn managedVerifyBLSAggregatedSignature( + keyHandle: i32, + messageHandle: i32, + sigHandle: i32, + ) -> i32; } impl CryptoApi for VmApiImpl { @@ -74,8 +84,10 @@ impl CryptoApiImpl for VmApiImpl { key: Self::ManagedBufferHandle, message: Self::ManagedBufferHandle, signature: Self::ManagedBufferHandle, - ) -> bool { - unsafe { managedVerifyBLS(key, message, signature) == 0 } + ) { + unsafe { + let _ = managedVerifyBLS(key, message, signature); + } } #[inline] @@ -123,4 +135,37 @@ impl CryptoApiImpl for VmApiImpl { let _ = managedEncodeSecp256k1DerSignature(r, s, dest_sig_handle); } } + + fn verify_secp256r1_managed( + &self, + key: Self::ManagedBufferHandle, + message: Self::ManagedBufferHandle, + signature: Self::ManagedBufferHandle, + ) { + unsafe { + let _ = managedVerifySecp256r1(key, message, signature); + } + } + + fn verify_bls_signature_share_managed( + &self, + key: Self::ManagedBufferHandle, + message: Self::ManagedBufferHandle, + signature: Self::ManagedBufferHandle, + ) { + unsafe { + let _ = managedVerifyBLSSignatureShare(key, message, signature); + } + } + + fn verify_bls_aggregated_signature_managed( + &self, + key: Self::ManagedBufferHandle, + message: Self::ManagedBufferHandle, + signature: Self::ManagedBufferHandle, + ) { + unsafe { + let _ = managedVerifyBLSAggregatedSignature(key, message, signature); + } + } } 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/big_int_api_node.rs b/framework/wasm-adapter/src/api/managed_types/big_int_api_node.rs index d09020f5d6..267db172c0 100644 --- a/framework/wasm-adapter/src/api/managed_types/big_int_api_node.rs +++ b/framework/wasm-adapter/src/api/managed_types/big_int_api_node.rs @@ -109,8 +109,8 @@ impl BigIntApiImpl for crate::api::VmApiImpl { unary_op_wrapper! {bi_sqrt, bigIntSqrt} binary_op_wrapper! {bi_pow, bigIntPow} - fn bi_log2(&self, x: Self::BigIntHandle) -> u32 { - unsafe { bigIntLog2(x) as u32 } + fn bi_log2(&self, x: Self::BigIntHandle) -> i32 { + unsafe { bigIntLog2(x) } } binary_op_wrapper! {bi_and, bigIntAnd} 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 272bbba578..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 @@ -11,6 +11,8 @@ static mut NEXT_HANDLE: i32 = const_handles::NEW_HANDLE_START_FROM; static mut NUM_ARGUMENTS: i32 = 0; static mut CALL_VALUE_EGLD_HANDLE: i32 = const_handles::UNINITIALIZED_HANDLE; static mut CALL_VALUE_MULTI_ESDT_HANDLE: i32 = const_handles::UNINITIALIZED_HANDLE; +static mut SCALING_FACTOR_INIT: [bool; const_handles::SCALING_FACTOR_LENGTH] = + [false; const_handles::SCALING_FACTOR_LENGTH]; // The compiler seems to enjoy inlining this method no matter how many times it shows up. // Hence the rather drastic directive. @@ -31,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) } } @@ -78,4 +81,14 @@ impl StaticVarApiImpl for VmApiImpl { fn get_call_value_multi_esdt_handle(&self) -> RawHandle { unsafe { CALL_VALUE_MULTI_ESDT_HANDLE } } + + fn is_scaling_factor_cached(&self, decimals: usize) -> bool { + unsafe { SCALING_FACTOR_INIT[decimals] } + } + + fn set_scaling_factor_cached(&self, decimals: usize) { + { + unsafe { SCALING_FACTOR_INIT[decimals] = true } + } + } } diff --git a/framework/wasm-adapter/src/lib.rs b/framework/wasm-adapter/src/lib.rs index bf7e6797d0..9bd84315c5 100644 --- a/framework/wasm-adapter/src/lib.rs +++ b/framework/wasm-adapter/src/lib.rs @@ -1,6 +1,5 @@ #![no_std] -#![feature(panic_info_message)] -#![feature(int_roundings)] +#![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..200b3abd00 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() {} }; } @@ -52,14 +46,14 @@ macro_rules! endpoints_old { ($mod_name:ident ( $($endpoint_name:ident)* ) ) => { #[no_mangle] fn init() { - $mod_name::endpoints::init::(); + $mod_name::__wasm__endpoints__::init::(); } $( #[allow(non_snake_case)] #[no_mangle] fn $endpoint_name() { - $mod_name::endpoints::$endpoint_name::(); + $mod_name::__wasm__endpoints__::$endpoint_name::(); } )* }; @@ -72,7 +66,7 @@ macro_rules! endpoints { #[allow(non_snake_case)] #[no_mangle] fn $endpoint_name() { - $mod_name::endpoints::$method_name::(); + $mod_name::__wasm__endpoints__::$method_name::(); } )* }; @@ -85,7 +79,7 @@ macro_rules! external_view_endpoints { #[allow(non_snake_case)] #[no_mangle] fn $endpoint_name() { - $mod_name::endpoints::$method_name::>(); + $mod_name::__wasm__endpoints__::$method_name::>(); } )* }; @@ -103,7 +97,7 @@ macro_rules! external_view_endpoints_old { #[allow(non_snake_case)] #[no_mangle] fn $endpoint_name() { - $mod_name::endpoints::$endpoint_name::>(); + $mod_name::__wasm__endpoints__::$endpoint_name::>(); } )* }; @@ -125,7 +119,8 @@ macro_rules! async_callback { #[allow(non_snake_case)] #[no_mangle] fn callBack() { - $mod_name::endpoints::callBack::(); + $mod_name::__wasm__endpoints__::callBack::( + ); } }; } diff --git a/meta-run-all.sh b/meta-run-all.sh index 208af3cf83..7c71e7fe6c 100755 --- a/meta-run-all.sh +++ b/meta-run-all.sh @@ -4,4 +4,4 @@ cargo install multiversx-sc-meta TARGET_DIR=$PWD/target -sc-meta all update --path ./contracts +sc-meta all update --target-dir-all $TARGET_DIR --path ./contracts diff --git a/publish.sh b/publish.sh index 78d97da4a3..53a5e922af 100755 --- a/publish.sh +++ b/publish.sh @@ -19,6 +19,7 @@ # # 2. Mass replace previous version -> new version. # Be careful to not accidentally replace some of the other dependencies we have. +# Make sure to exclude files with extensions: *.lock, *.md, *.wat, *.txt, *.sh. # # 3. Write release name, date and description in `CHANGELOG.md`. # @@ -30,7 +31,7 @@ # # 6. Make sure that the contract upgrade tool is still sound. # At the very least add the new version to `VERSIONS` and change `DEFAULT_LAST_VERSION` in -# `/home/andreim/multiversx/rs/mx-sdk-rs/framework/meta/src/sc_upgrade/upgrade_versions.rs` +# `/home/andreim/multiversx/rs/mx-sdk-rs/framework/meta/src/sc_upgrade/upgrade_versions.rs`+ # # 7. Run this script, `./publish.sh`. # You can comment out the crates you are not publishing. The script will stop otherwise when it cannot publish them. @@ -87,7 +88,7 @@ cd framework/base cargo publish || return 1 cd ../.. -cd framework/meta +cd framework/meta-lib cargo publish || return 1 cd ../.. @@ -99,6 +100,10 @@ cd framework/snippets cargo publish || return 1 cd ../.. +cd framework/meta +cargo publish || return 1 +cd ../.. + cd framework/wasm-adapter cargo publish || return 1 cd ../.. diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000000..292fe499e3 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +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 f3b22ad471..1dc7b129f5 100644 --- a/sdk/core/Cargo.toml +++ b/sdk/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-sdk" -version = "0.2.0" +version = "0.6.0" edition = "2021" authors = [ @@ -17,21 +17,25 @@ 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" anyhow = "1.0.44" rand = "0.8.5" bip39 = { version = "2.0.0", features = ["rand"] } -sha2 = "0.9.8" -sha3 = "0.9.1" -hmac = { version = "0.11.0", features = ["std"] } +sha2 = "0.10.8" +sha3 = "0.10.8" +hmac = { version = "0.12.1", features = ["std"] } hex = "0.4.3" -base64 = "0.13.0" -ed25519 = "1.2.0" -pbkdf2 = { version = "0.9.0", default-features = false } +base64 = "0.22" +pbkdf2 = { version = "0.12.2", default-features = false } zeroize = "1.4.2" -bech32 = "0.9" -itertools = "0.11" -pem = "1.0.1" +bech32 = "0.11" +itertools = "0.13.0" +pem = "3.0.2" +log = "0.4.17" +scrypt = "0.11" +aes = "0.8" +ctr = "0.9.2" +uuid = {version = "1.10.0", features = ["v4"]} \ No newline at end of file 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 88b5c01fd9..a982b130ec 100644 --- a/sdk/core/examples/tx_cost.rs +++ b/sdk/core/examples/tx_cost.rs @@ -1,6 +1,7 @@ use multiversx_sdk::{ - blockchain::{CommunicationProxy, DEVNET_GATEWAY}, data::{address::Address, transaction::Transaction}, + gateway::{GatewayProxy, DEVNET_GATEWAY}, + utils::base64_encode, }; #[tokio::main] @@ -16,7 +17,7 @@ async fn main() { "erd1rh5ws22jxm9pe7dtvhfy6j3uttuupkepferdwtmslms5fydtrh5sx3xr8r", ) .unwrap(), - data: Some(base64::encode("hello")), + data: Some(base64_encode("hello")), chain_id: "1".to_string(), version: 1, options: 0, @@ -25,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..473a0388fe 100644 --- a/sdk/core/src/crypto/public_key.rs +++ b/sdk/core/src/crypto/public_key.rs @@ -1,6 +1,8 @@ +use std::fmt::Display; + use super::private_key::PrivateKey; use anyhow::Result; -use bech32::{self, ToBase32, Variant}; +use bech32::{self, Bech32, Hrp}; use serde::{ de::{Deserialize, Deserializer}, ser::{Serialize, Serializer}, @@ -21,7 +23,8 @@ impl PublicKey { } pub fn to_address(&self) -> Result { - let address = bech32::encode("erd", self.0.to_base32(), Variant::Bech32)?; + let hrp = Hrp::parse("erd")?; + let address = bech32::encode::(hrp, &self.0)?; Ok(address) } @@ -44,9 +47,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..49d92ea608 100644 --- a/sdk/core/src/data/address.rs +++ b/sdk/core/src/data/address.rs @@ -1,8 +1,8 @@ -use std::fmt::Debug; +use std::fmt::{Debug, Display}; use crate::crypto::public_key::PublicKey; use anyhow::Result; -use bech32::{FromBase32, ToBase32, Variant}; +use bech32::{Bech32, Hrp}; use serde::{ de::{Deserialize, Deserializer}, ser::{Serialize, Serializer}, @@ -21,8 +21,7 @@ impl Address { } pub fn from_bech32_string(bech32: &str) -> Result { - let (_, data, _) = bech32::decode(bech32)?; - let data = Vec::::from_base32(&data)?; + let (_hrp, data) = bech32::decode(bech32)?; let mut bits: [u8; 32] = [0u8; 32]; bits.copy_from_slice(&data); @@ -31,7 +30,8 @@ impl Address { } pub fn to_bech32_string(&self) -> Result { - let address = bech32::encode("erd", self.0.to_base32(), Variant::Bech32)?; + let hrp = Hrp::parse("erd")?; + let address = bech32::encode::(hrp, &self.0)?; Ok(address) } @@ -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/keystore.rs b/sdk/core/src/data/keystore.rs new file mode 100644 index 0000000000..31e6b6538a --- /dev/null +++ b/sdk/core/src/data/keystore.rs @@ -0,0 +1,61 @@ +use serde::{Deserialize, Serialize}; + +pub const KDF_N: u32 = 4096; +pub const KDF_R: u32 = 8; +pub const KDF_P: u32 = 1; +pub const KDF_DKLEN: usize = 32; +pub const KEYSTORE_VERSION: u32 = 4; + +#[derive(Debug)] +pub enum WalletError { + InvalidPassword, + InvalidKdf, + InvalidCipher, +} + +#[derive(Debug)] +pub enum InsertPassword { + Plaintext(String), + StandardInput, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct CryptoParams { + pub iv: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct KdfParams { + pub dklen: u32, + pub salt: String, + pub n: u32, + pub r: u32, + pub p: u32, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Crypto { + pub ciphertext: String, + pub cipherparams: CryptoParams, + pub cipher: String, + pub kdf: String, + pub kdfparams: KdfParams, + pub mac: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Keystore { + pub version: u32, + pub kind: String, + pub id: String, + pub address: String, + pub bech32: String, + pub crypto: Crypto, +} + +#[derive(Clone, Debug)] +pub struct DecryptionParams { + pub derived_key_first_half: Vec, + pub iv: Vec, + pub data: Vec, +} diff --git a/sdk/core/src/data/mod.rs b/sdk/core/src/data/mod.rs index 797ec6e1ce..9a270211df 100644 --- a/sdk/core/src/data/mod.rs +++ b/sdk/core/src/data/mod.rs @@ -3,6 +3,7 @@ pub mod account_storage; pub mod address; pub mod esdt; pub mod hyperblock; +pub mod keystore; pub mod network_config; pub mod network_economics; pub mod network_status; diff --git a/sdk/core/src/data/transaction.rs b/sdk/core/src/data/transaction.rs index 585cdb49ca..664ea3a08e 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,21 @@ 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 smart_contract_results: Option>, + pub hyperblock_nonce: Option, + pub hyperblock_hash: Option, + #[serde(default)] + pub smart_contract_results: Vec, pub logs: Option, } @@ -90,7 +92,27 @@ pub struct Events { pub address: Address, pub identifier: String, pub topics: Option>, - pub data: Option, + #[serde(default)] + pub data: LogData, +} + +#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(untagged)] +pub enum LogData { + #[default] + Empty, + String(String), + Vec(Vec), +} + +impl LogData { + pub fn for_each(&self, mut f: F) { + match self { + LogData::Empty => {}, + LogData::String(s) => f(s), + LogData::Vec(v) => v.iter().for_each(f), + } + } } // ApiLogs represents logs with changed fields' types in order to make it friendly for API's json @@ -131,6 +153,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, @@ -149,6 +172,20 @@ pub struct TransactionStatus { pub data: Option, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TransactionProcessStatusData { + pub reason: String, + pub status: String, +} + +// TransactionProcessStatus holds a transaction's status response from the network obtained through the process-status API +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TransactionProcessStatus { + pub error: String, + pub code: String, + pub data: Option, +} + // ArgCreateTransaction will hold the transaction fields #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ArgCreateTransaction { @@ -194,3 +231,62 @@ pub struct SendTransactionsResponse { pub code: String, pub data: Option, } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn parse_event_log_0() { + let data = r#" +{ + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "completedTxEvent", + "topics": [], + "data": null, + "additionalData": null +} + "#; + + let event_log = serde_json::from_str::(data).unwrap(); + assert_eq!(event_log.data, LogData::Empty); + } + + #[test] + fn parse_event_log_1() { + let data = r#" +{ + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "completedTxEvent", + "topics": [], + "data": "data-string", + "additionalData": null +} + "#; + + let event_log = serde_json::from_str::(data).unwrap(); + assert_eq!(event_log.data, LogData::String("data-string".to_owned())); + } + + #[test] + fn parse_event_log_2() { + let data = r#" +{ + "address": "erd1qqqqqqqqqqqqqpgq0628nau8zydgwu96fn8ksqklzhrggkcfq33sm4vmwv", + "identifier": "completedTxEvent", + "topics": [], + "data": [ + "data1", + "data2" + ], + "additionalData": null +} + "#; + + let event_log = serde_json::from_str::(data).unwrap(); + assert_eq!( + event_log.data, + LogData::Vec(vec!["data1".to_owned(), "data2".to_owned()]) + ); + } +} 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..88d9cd4ece --- /dev/null +++ b/sdk/core/src/gateway/gateway_tx.rs @@ -0,0 +1,204 @@ +use crate::data::{ + address::Address, + network_config::NetworkConfig, + transaction::{ + ArgCreateTransaction, ResponseTxCost, SendTransactionResponse, SendTransactionsResponse, + Transaction, TransactionInfo, TransactionOnNetwork, TransactionProcessStatus, + 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_transaction_process_status retrieves a transaction's status from the network using process-status API + pub async fn get_transaction_process_status(&self, hash: &str) -> Result<(String, String)> { + let endpoint = format!("transaction/{hash}/process-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, b.reason)), + } + } + + // 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..61ba080430 --- /dev/null +++ b/sdk/core/src/gateway/gateway_tx_retrieve.rs @@ -0,0 +1,104 @@ +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_process_status(&tx_hash).await { + Ok((status, reason)) => { + // checks if transaction status is final + match status.as_str() { + "success" => { + // 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; + }, + "fail" => { + // status failed and no reason means invalid transaction + if reason.is_empty() { + info!("Transaction failed. Invalid transaction: {tx_hash}"); + panic!("Transaction failed. Invalid transaction: {tx_hash}"); + } + + let result = parse_reason(&reason); + + match result { + Ok((code, err)) => { + info!("Transaction failed. Code: {code}, message: {err}"); + panic!("Transaction failed. Code: {code}, message: {err}") + }, + Err(err) => { + info!("Reason parsing error for failed transaction: {err}"); + panic!("Reason parsing error for failed transaction: {err}") + }, + } + }, + _ => { + 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() + } +} + +pub fn parse_reason(reason: &str) -> Result<(u64, String), String> { + let parts: Vec<&str> = reason.split('@').collect(); + + if parts.len() < 2 { + return Err("Invalid reason format".to_string()); + } + + let error_code_hex = parts[1]; + let error_message_hex = parts[2]; + + let error_code = + u64::from_str_radix(error_code_hex, 16).expect("Failed to decode error code as u64"); + + let error_message = + String::from_utf8(hex::decode(error_message_hex).expect("Failed to decode error message")) + .expect("Failed to decode error message as UTF-8"); + + Ok((error_code, error_message)) +} diff --git a/sdk/core/src/lib.rs b/sdk/core/src/lib.rs index 8a7b931a56..3a1db99fd7 100644 --- a/sdk/core/src/lib.rs +++ b/sdk/core/src/lib.rs @@ -1,4 +1,5 @@ -pub mod blockchain; pub mod crypto; pub mod data; +pub mod gateway; +pub mod utils; pub mod wallet; diff --git a/sdk/core/src/utils.rs b/sdk/core/src/utils.rs new file mode 100644 index 0000000000..faada02b4f --- /dev/null +++ b/sdk/core/src/utils.rs @@ -0,0 +1,15 @@ +use base64::{engine::general_purpose, Engine as _}; + +pub fn base64_decode(to_decode: T) -> Vec +where + T: AsRef<[u8]>, +{ + general_purpose::STANDARD.decode(to_decode).unwrap() +} + +pub fn base64_encode(to_encode: T) -> String +where + T: AsRef<[u8]>, +{ + general_purpose::STANDARD.encode(to_encode) +} diff --git a/sdk/core/src/wallet.rs b/sdk/core/src/wallet.rs index 469f4be106..df9b9dc43a 100644 --- a/sdk/core/src/wallet.rs +++ b/sdk/core/src/wallet.rs @@ -1,11 +1,21 @@ extern crate rand; +use core::str; +use std::{ + fs::{self}, + io::{self, Read}, +}; + +use aes::{cipher::KeyIvInit, Aes128}; use anyhow::Result; use bip39::{Language, Mnemonic}; -use hmac::{Hmac, Mac, NewMac}; +use ctr::{cipher::StreamCipher, Ctr128BE}; +use hmac::{Hmac, Mac}; use pbkdf2::pbkdf2; +use rand::RngCore; +use scrypt::{scrypt, Params}; use serde_json::json; -use sha2::{Digest, Sha512}; +use sha2::{Digest, Sha256, Sha512}; use sha3::Keccak256; use zeroize::Zeroize; @@ -14,13 +24,19 @@ use crate::{ private_key::{PrivateKey, PRIVATE_KEY_LENGTH}, public_key::PublicKey, }, - data::{address::Address, transaction::Transaction}, + data::{address::Address, keystore::*, transaction::Transaction}, + utils::*, }; +use uuid::Uuid; + const EGLD_COIN_TYPE: u32 = 508; const HARDENED: u32 = 0x80000000; +const CIPHER_ALGORITHM_AES_128_CTR: &str = "aes-128-ctr"; +const KDF_SCRYPT: &str = "scrypt"; -type HmacSha521 = Hmac; +type HmacSha512 = Hmac; +type HmacSha256 = Hmac; #[derive(Copy, Clone, Debug)] pub struct Wallet { @@ -40,7 +56,7 @@ impl Wallet { let mut seed = [0u8; 64]; - pbkdf2::>( + let _ = pbkdf2::>( mnemonic.to_string().as_bytes(), salt.as_bytes(), 2048, @@ -63,7 +79,8 @@ impl Wallet { let hardened_child_padding: u8 = 0; let mut digest = - HmacSha521::new_from_slice(b"ed25519 seed").expect("HMAC can take key of any size"); + HmacSha512::new_from_slice(b"ed25519 seed").expect("HMAC can take key of any size"); + HmacSha512::new_from_slice(b"ed25519 seed").expect("HMAC can take key of any size"); digest.update(&seed); let intermediary: Vec = digest.finalize().into_bytes().into_iter().collect(); let mut key = intermediary[..serialized_key_len].to_vec(); @@ -83,7 +100,8 @@ impl Wallet { buff.push(child_idx as u8); digest = - HmacSha521::new_from_slice(&chain_code).expect("HMAC can take key of any size"); + HmacSha512::new_from_slice(&chain_code).expect("HMAC can take key of any size"); + HmacSha512::new_from_slice(&chain_code).expect("HMAC can take key of any size"); digest.update(&buff); let intermediary: Vec = digest.finalize().into_bytes().into_iter().collect(); key = intermediary[..serialized_key_len].to_vec(); @@ -93,9 +111,20 @@ impl Wallet { PrivateKey::from_bytes(key.as_slice()).unwrap() } + pub fn get_wallet_keys_mnemonic(mnemonic_str: String) -> (String, String) { + let mnemonic = Mnemonic::parse(mnemonic_str.replace('\n', "")).unwrap(); + let private_key = Self::get_private_key_from_mnemonic(mnemonic, 0u32, 0u32); + let public_key = PublicKey::from(&private_key); + + let public_key_str: &str = &public_key.to_string(); + let private_key_str: &str = &private_key.to_string(); + + (private_key_str.to_string(), public_key_str.to_string()) + } + pub fn from_private_key(priv_key: &str) -> Result { - let pri_key = PrivateKey::from_hex_str(priv_key)?; - Ok(Self { priv_key: pri_key }) + let priv_key = PrivateKey::from_hex_str(priv_key)?; + Ok(Self { priv_key }) } pub fn from_pem_file(file_path: &str) -> Result { @@ -105,12 +134,64 @@ impl Wallet { pub fn from_pem_file_contents(contents: String) -> Result { let x = pem::parse(contents)?; - let x = x.contents[..PRIVATE_KEY_LENGTH].to_vec(); + let x = x.contents()[..PRIVATE_KEY_LENGTH].to_vec(); let priv_key_str = std::str::from_utf8(x.as_slice())?; let pri_key = PrivateKey::from_hex_str(priv_key_str)?; Ok(Self { priv_key: pri_key }) } + pub fn get_pem_decoded_content(file: &str) -> Vec { + let pem_content = fs::read_to_string(file).unwrap(); + let lines: Vec<&str> = pem_content.split('\n').collect(); + let pem_encoded_keys = format!("{}{}{}", lines[1], lines[2], lines[3]); + base64_decode(pem_encoded_keys) + } + + pub fn get_wallet_keys_pem(file: &str) -> (String, String) { + let pem_decoded_keys = Self::get_pem_decoded_content(file); + let (private_key, public_key) = pem_decoded_keys.split_at(pem_decoded_keys.len() / 2); + let private_key_str = String::from_utf8(private_key.to_vec()).unwrap(); + let public_key_str = String::from_utf8(public_key.to_vec()).unwrap(); + + (private_key_str, public_key_str) + } + + pub fn from_keystore_secret(file_path: &str, insert_password: InsertPassword) -> Result { + let decryption_params = match insert_password { + InsertPassword::Plaintext(password) => { + Self::validate_keystore_password(file_path, password.to_string()).unwrap_or_else( + |e| { + panic!("Error: {:?}", e); + }, + ) + }, + InsertPassword::StandardInput => { + Self::validate_keystore_password(file_path, Self::get_keystore_password()) + .unwrap_or_else(|e| { + panic!("Error: {:?}", e); + }) + }, + }; + let priv_key = PrivateKey::from_hex_str( + hex::encode(Self::decrypt_secret_key(decryption_params)).as_str(), + )?; + Ok(Self { priv_key }) + } + + pub fn get_private_key_from_keystore_secret( + file_path: &str, + password: &str, + ) -> Result { + let decyption_params = Self::validate_keystore_password(file_path, password.to_string()) + .unwrap_or_else(|e| { + panic!("Error: {:?}", e); + }); + let priv_key = PrivateKey::from_hex_str( + hex::encode(Self::decrypt_secret_key(decyption_params)).as_str(), + )?; + Ok(priv_key) + } + pub fn address(&self) -> Address { let public_key = PublicKey::from(&self.priv_key); Address::from(&public_key) @@ -131,4 +212,157 @@ impl Wallet { self.priv_key.sign(tx_bytes) } + + pub fn get_keystore_password() -> String { + println!( + "Insert password. Press 'Ctrl-D' (Linux / MacOS) or 'Ctrl-Z' (Windows) when done." + ); + let mut password = String::new(); + io::stdin().read_to_string(&mut password).unwrap(); + password = password.trim().to_string(); + password + } + + pub fn validate_keystore_password( + path: &str, + password: String, + ) -> Result { + let json_body = fs::read_to_string(path).unwrap(); + let keystore: Keystore = serde_json::from_str(&json_body).unwrap(); + let ciphertext = hex::decode(&keystore.crypto.ciphertext).unwrap(); + + let cipher = &keystore.crypto.cipher; + if cipher != CIPHER_ALGORITHM_AES_128_CTR { + return Err(WalletError::InvalidCipher); + } + + let iv = hex::decode(&keystore.crypto.cipherparams.iv).unwrap(); + let salt = hex::decode(&keystore.crypto.kdfparams.salt).unwrap(); + let json_mac = hex::decode(&keystore.crypto.mac).unwrap(); + + let kdf = &keystore.crypto.kdf; + if kdf != KDF_SCRYPT { + return Err(WalletError::InvalidKdf); + } + let n = keystore.crypto.kdfparams.n as f64; + let r = keystore.crypto.kdfparams.r as u64; + let p = keystore.crypto.kdfparams.p as u64; + let dklen = keystore.crypto.kdfparams.dklen as usize; + + let params = Params::new(n.log2() as u8, r as u32, p as u32, dklen).unwrap(); + + let mut derived_key = vec![0u8; 32]; + scrypt(password.as_bytes(), &salt, ¶ms, &mut derived_key).unwrap(); + + let derived_key_first_half = derived_key[0..16].to_vec(); + let derived_key_second_half = derived_key[16..32].to_vec(); + + let mut input_mac = HmacSha256::new_from_slice(&derived_key_second_half).unwrap(); + input_mac.update(&ciphertext); + let computed_mac = input_mac.finalize().into_bytes(); + + if computed_mac.as_slice() == json_mac.as_slice() { + println!("Password is correct"); + Ok(DecryptionParams { + derived_key_first_half, + iv, + data: ciphertext, + }) + } else { + println!("Password is incorrect"); + Err(WalletError::InvalidPassword) + } + } + + pub fn decrypt_secret_key(decryption_params: DecryptionParams) -> Vec { + let mut cipher = Ctr128BE::::new( + decryption_params.derived_key_first_half.as_slice().into(), + decryption_params.iv.as_slice().into(), + ); + let mut decrypted = decryption_params.data.to_vec(); + cipher.apply_keystream(&mut decrypted); + + decrypted + } + + pub fn encrypt_keystore( + data: &[u8], + address: &Address, + public_key: &str, + password: &str, + ) -> String { + let params = Params::new((KDF_N as f64).log2() as u8, KDF_R, KDF_P, KDF_DKLEN).unwrap(); + let mut rand_salt: [u8; 32] = [0u8; 32]; + rand::thread_rng().fill_bytes(&mut rand_salt); + let salt_hex = hex::encode(rand_salt); + + let mut rand_iv: [u8; 16] = [0u8; 16]; + rand::thread_rng().fill_bytes(&mut rand_iv); + let iv_hex = hex::encode(rand_iv); + + let mut derived_key = vec![0u8; 32]; + scrypt(password.as_bytes(), &rand_salt, ¶ms, &mut derived_key).unwrap(); + + let derived_key_first_half = derived_key[0..16].to_vec(); + let derived_key_second_half = derived_key[16..32].to_vec(); + + let decryption_params = DecryptionParams { + derived_key_first_half, + iv: rand_iv.to_vec(), + data: data.to_vec(), + }; + + let ciphertext = Self::decrypt_secret_key(decryption_params); + + let mut h = HmacSha256::new_from_slice(&derived_key_second_half).unwrap(); + h.update(&ciphertext); + let mac = h.finalize().into_bytes(); + let keystore = Keystore { + crypto: Crypto { + cipher: CIPHER_ALGORITHM_AES_128_CTR.to_string(), + cipherparams: CryptoParams { iv: iv_hex }, + ciphertext: hex::encode(&ciphertext), + kdf: KDF_SCRYPT.to_string(), + kdfparams: KdfParams { + salt: salt_hex, + n: KDF_N, + r: KDF_R, + p: KDF_P, + dklen: KDF_DKLEN as u32, + }, + mac: hex::encode(mac), + }, + id: Uuid::new_v4().to_string(), + version: KEYSTORE_VERSION, + kind: "secretKey".to_string(), + address: public_key.to_string(), + bech32: address.to_string(), + }; + + let mut keystore_json: String = serde_json::to_string_pretty(&keystore).unwrap(); + keystore_json.push('\n'); + keystore_json + } + + pub fn generate_pem_content(address: &Address, private_key: &str, public_key: &str) -> String { + let concat_keys = format!("{}{}", private_key, public_key); + let concat_keys_b64 = base64_encode(concat_keys); + + // Split the base64 string into 64-character lines + let formatted_key = concat_keys_b64 + .as_bytes() + .chunks(64) + .map(|chunk| std::str::from_utf8(chunk).unwrap()) + .collect::>() + .join("\n"); + + let pem_content = format!( + "-----BEGIN PRIVATE KEY for {}-----\n{}\n-----END PRIVATE KEY for {}-----\n", + address.to_bech32_string().unwrap(), + formatted_key, + address.to_bech32_string().unwrap() + ); + + pem_content + } } diff --git a/sdk/core/tests/wallet_test.rs b/sdk/core/tests/wallet_test.rs index d076980084..103166e430 100644 --- a/sdk/core/tests/wallet_test.rs +++ b/sdk/core/tests/wallet_test.rs @@ -1,6 +1,16 @@ use bip39::Mnemonic; use multiversx_sdk::{crypto::public_key::PublicKey, data::address::Address, wallet::Wallet}; +use std::fs::{self, File}; +use std::io::Write; + +const ALICE_PEM_PATH: &str = "tests/alice.pem"; +const ALICE_KEYSTORE_PATH_TEST_1: &str = "tests/alice1.json"; +const ALICE_KEYSTORE_PATH_TEST_2: &str = "tests/alice2.json"; +const ALICE_PEM_PATH_TEST: &str = "tests/alice_test.pem"; +const KEYSTORE_PASSWORD: &str = "abcd"; +const ALICE_PUBLIC_KEY: &str = "0139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e1"; +const ALICE_PRIVATE_KEY: &str = "413f42575f7f26fad3317a778771212fdb80245850981e48b58a4f25e344e8f9"; #[test] fn test_private_key_from_mnemonic() { @@ -48,3 +58,59 @@ fn test_load_from_pem() { "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th" ); } + +fn write_to_file(content: &str, file: &str) { + let mut file = File::create(file).unwrap(); + file.write_all(content.as_bytes()).unwrap(); +} + +fn create_keystore_file_from_scratch(file: &str) -> Address { + let wallet = Wallet::from_private_key(ALICE_PRIVATE_KEY).unwrap(); + let address = wallet.address(); + + let concatenated_keys = format!("{}{}", ALICE_PRIVATE_KEY, ALICE_PUBLIC_KEY); + let hex_decoded_keys = hex::decode(concatenated_keys).unwrap(); + let json_result = Wallet::encrypt_keystore( + hex_decoded_keys.as_slice(), + &address, + ALICE_PUBLIC_KEY, + KEYSTORE_PASSWORD, + ); + write_to_file(&json_result, file); + address +} + +#[test] +fn test_wallet_convert_pem_to_keystore() { + let _ = create_keystore_file_from_scratch(ALICE_KEYSTORE_PATH_TEST_1); + let (private_key_pem, _public_key_pem) = Wallet::get_wallet_keys_pem(ALICE_PEM_PATH); + assert_eq!( + Wallet::get_private_key_from_keystore_secret(ALICE_KEYSTORE_PATH_TEST_1, KEYSTORE_PASSWORD) + .unwrap() + .to_string(), + private_key_pem + ); + fs::remove_file(ALICE_KEYSTORE_PATH_TEST_1).unwrap(); +} + +#[test] +fn test_wallet_convert_keystore_to_pem() { + let address = create_keystore_file_from_scratch(ALICE_KEYSTORE_PATH_TEST_2); + + let private_key = + Wallet::get_private_key_from_keystore_secret(ALICE_KEYSTORE_PATH_TEST_2, KEYSTORE_PASSWORD) + .unwrap(); + let private_key_str = private_key.to_string(); + let public_key = PublicKey::from(&private_key); + let public_key_str = public_key.to_string(); + + let pem_content = Wallet::generate_pem_content(&address, &private_key_str, &public_key_str); + write_to_file(&pem_content, ALICE_PEM_PATH_TEST); + assert_eq!( + private_key_str, + Wallet::get_wallet_keys_pem(ALICE_PEM_PATH_TEST).0 + ); + + fs::remove_file(ALICE_PEM_PATH_TEST).unwrap(); + fs::remove_file(ALICE_KEYSTORE_PATH_TEST_2).unwrap(); +} diff --git a/sdk/scenario-format/Cargo.toml b/sdk/scenario-format/Cargo.toml index ee541dc856..fd3892fe75 100644 --- a/sdk/scenario-format/Cargo.toml +++ b/sdk/scenario-format/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-chain-scenario-format" -version = "0.20.0" +version = "0.23.0" edition = "2021" authors = ["Andrei Marinica ", "MultiversX "] @@ -19,5 +19,5 @@ serde_json = "1.0" num-bigint = "0.4" num-traits = "0.2" hex = "0.4" -sha3 = "0.9" -bech32 = "0.9.0" +sha3 = "0.10.8" +bech32 = "0.11.0" diff --git a/sdk/scenario-format/src/interpret_trait.rs b/sdk/scenario-format/src/interpret_trait.rs index a89bb1bbbe..306349661f 100644 --- a/sdk/scenario-format/src/interpret_trait.rs +++ b/sdk/scenario-format/src/interpret_trait.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use crate::value_interpreter::VMIdentifier; -#[derive(Default, Clone)] +#[derive(Default, Clone, Debug)] pub struct InterpreterContext { pub context_path: PathBuf, pub vm_type: VMIdentifier, diff --git a/sdk/scenario-format/src/serde_raw/account_data_raw/account_raw.rs b/sdk/scenario-format/src/serde_raw/account_data_raw/account_raw.rs index d9ee01c93d..2d0fced91b 100644 --- a/sdk/scenario-format/src/serde_raw/account_data_raw/account_raw.rs +++ b/sdk/scenario-format/src/serde_raw/account_data_raw/account_raw.rs @@ -34,6 +34,10 @@ pub struct AccountRaw { #[serde(skip_serializing_if = "Option::is_none")] pub code: Option, + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + pub code_metadata: Option, + #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")] pub owner: Option, diff --git a/sdk/scenario-format/src/serde_raw/account_data_raw/account_raw_check.rs b/sdk/scenario-format/src/serde_raw/account_data_raw/account_raw_check.rs index 12ba7952d3..50a87fee96 100644 --- a/sdk/scenario-format/src/serde_raw/account_data_raw/account_raw_check.rs +++ b/sdk/scenario-format/src/serde_raw/account_data_raw/account_raw_check.rs @@ -32,6 +32,10 @@ pub struct CheckAccountRaw { #[serde(skip_serializing_if = "CheckBytesValueRaw::is_unspecified")] pub code: CheckBytesValueRaw, + #[serde(default)] + #[serde(skip_serializing_if = "CheckBytesValueRaw::is_unspecified")] + pub code_metadata: CheckBytesValueRaw, + #[serde(default)] #[serde(skip_serializing_if = "CheckBytesValueRaw::is_unspecified")] pub owner: CheckBytesValueRaw, diff --git a/sdk/scenario-format/src/serde_raw/log_raw.rs b/sdk/scenario-format/src/serde_raw/log_raw.rs index b33135259d..4b38023f64 100644 --- a/sdk/scenario-format/src/serde_raw/log_raw.rs +++ b/sdk/scenario-format/src/serde_raw/log_raw.rs @@ -12,5 +12,7 @@ pub struct CheckLogRaw { #[serde(skip_serializing_if = "CheckValueListRaw::is_unspecified")] pub topics: CheckValueListRaw, - pub data: CheckBytesValueRaw, + #[serde(default)] + #[serde(skip_serializing_if = "CheckValueListRaw::is_unspecified")] + pub data: CheckValueListRaw, } diff --git a/sdk/scenario-format/src/serde_raw/transaction_raw/tx_call_raw.rs b/sdk/scenario-format/src/serde_raw/transaction_raw/tx_call_raw.rs index 7fe0d4fa91..f9804325f0 100644 --- a/sdk/scenario-format/src/serde_raw/transaction_raw/tx_call_raw.rs +++ b/sdk/scenario-format/src/serde_raw/transaction_raw/tx_call_raw.rs @@ -28,5 +28,8 @@ pub struct TxCallRaw { pub arguments: Vec, pub gas_limit: ValueSubTree, - pub gas_price: ValueSubTree, + + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + pub gas_price: Option, } diff --git a/sdk/scenario-format/src/serde_raw/transaction_raw/tx_deploy_raw.rs b/sdk/scenario-format/src/serde_raw/transaction_raw/tx_deploy_raw.rs index b4b58880dd..d21080a1a3 100644 --- a/sdk/scenario-format/src/serde_raw/transaction_raw/tx_deploy_raw.rs +++ b/sdk/scenario-format/src/serde_raw/transaction_raw/tx_deploy_raw.rs @@ -21,5 +21,8 @@ pub struct TxDeployRaw { pub arguments: Vec, pub gas_limit: ValueSubTree, - pub gas_price: ValueSubTree, + + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + pub gas_price: Option, } diff --git a/sdk/scenario-format/src/value_interpreter/file_loader.rs b/sdk/scenario-format/src/value_interpreter/file_loader.rs index e2dfdaeb91..658944359a 100644 --- a/sdk/scenario-format/src/value_interpreter/file_loader.rs +++ b/sdk/scenario-format/src/value_interpreter/file_loader.rs @@ -1,3 +1,4 @@ +use serde::{Deserialize, Serialize}; use std::{ fs, path::{Component, Path, PathBuf}, @@ -5,17 +6,28 @@ use std::{ use crate::interpret_trait::InterpreterContext; -pub fn load_file(file_path: &str, context: &InterpreterContext) -> Vec { +#[derive(Serialize, Deserialize)] +pub struct MxscFileJson { + pub code: String, +} + +pub fn load_file) -> Vec>( + file_path: &str, + context: &InterpreterContext, + process_content: F, +) -> Vec { let mut path_buf = context.context_path.clone(); path_buf.push(file_path); path_buf = normalize_path(path_buf); - fs::read(&path_buf).unwrap_or_else(|_| { - if context.allow_missing_files { - missing_file_value(&path_buf) - } else { - panic!("not found: {path_buf:#?}") - } - }) + fs::read(&path_buf) + .map(process_content) + .unwrap_or_else(|_| { + if context.allow_missing_files { + missing_file_value(&path_buf) + } else { + panic!("not found: {path_buf:#?}") + } + }) } fn missing_file_value(path_buf: &Path) -> Vec { diff --git a/sdk/scenario-format/src/value_interpreter/functions.rs b/sdk/scenario-format/src/value_interpreter/functions.rs index 32895e84d7..b4ce547ad7 100644 --- a/sdk/scenario-format/src/value_interpreter/functions.rs +++ b/sdk/scenario-format/src/value_interpreter/functions.rs @@ -1,5 +1,4 @@ use crate::value_interpreter::*; -use bech32::FromBase32; use sha3::{Digest, Keccak256}; pub const SC_ADDRESS_NUM_LEADING_ZEROS: usize = 8; @@ -71,6 +70,6 @@ pub(crate) fn sc_address_expression(input: &str, vm_type: &VMIdentifier) -> Vec< } pub(crate) fn bech32(input: &str) -> Vec { - let (_, decoded, _) = bech32::decode(input).expect("bech32 decode error"); - Vec::::from_base32(&decoded).expect("bech32 base64 decode error") + let (_hrp, decoded) = bech32::decode(input).expect("bech32 decode error"); + decoded } diff --git a/sdk/scenario-format/src/value_interpreter/interpreter.rs b/sdk/scenario-format/src/value_interpreter/interpreter.rs index 24d2524492..66f9be297b 100644 --- a/sdk/scenario-format/src/value_interpreter/interpreter.rs +++ b/sdk/scenario-format/src/value_interpreter/interpreter.rs @@ -1,6 +1,11 @@ use crate::{interpret_trait::InterpreterContext, serde_raw::ValueSubTree}; -use super::{file_loader::load_file, functions::*, parse_num::*, prefixes::*}; +use super::{ + file_loader::{load_file, MxscFileJson}, + functions::*, + parse_num::*, + prefixes::*, +}; pub fn interpret_subtree(vst: &ValueSubTree, context: &InterpreterContext) -> Vec { match vst { @@ -60,7 +65,14 @@ pub fn interpret_string(s: &str, context: &InterpreterContext) -> Vec { } if let Some(stripped) = s.strip_prefix(FILE_PREFIX) { - return load_file(stripped, context); + return load_file(stripped, context, |c| c); + } + + if let Some(stripped) = s.strip_prefix(MXSC_PREFIX) { + return load_file(stripped, context, |content| { + let mxsc_json: MxscFileJson = serde_json::from_slice(&content).unwrap(); + hex::decode(mxsc_json.code).expect("Could not decode contract code") + }); } if let Some(stripped) = s.strip_prefix(KECCAK256_PREFIX) { diff --git a/sdk/scenario-format/src/value_interpreter/prefixes.rs b/sdk/scenario-format/src/value_interpreter/prefixes.rs index 451ecd6a99..584b73433f 100644 --- a/sdk/scenario-format/src/value_interpreter/prefixes.rs +++ b/sdk/scenario-format/src/value_interpreter/prefixes.rs @@ -3,6 +3,7 @@ pub(super) const STR_PREFIXES: &[&str] = &["str:", "``", "''"]; pub(super) const ADDR_PREFIX: &str = "address:"; pub(super) const SC_ADDR_PREFIX: &str = "sc:"; pub(super) const FILE_PREFIX: &str = "file:"; +pub(super) const MXSC_PREFIX: &str = "mxsc:"; pub(super) const KECCAK256_PREFIX: &str = "keccak256:"; pub(super) const BECH32_PREFIX: &str = "bech32:"; 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/sdk/scenario-format/src/value_interpreter/vm_identifier.rs b/sdk/scenario-format/src/value_interpreter/vm_identifier.rs index a3c533b137..8c46cc9673 100644 --- a/sdk/scenario-format/src/value_interpreter/vm_identifier.rs +++ b/sdk/scenario-format/src/value_interpreter/vm_identifier.rs @@ -1,6 +1,12 @@ pub const VM_TYPE_LENGTH: usize = 2; -#[derive(Default, Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct VMIdentifier { pub vm_type: [u8; VM_TYPE_LENGTH], } + +impl Default for VMIdentifier { + fn default() -> Self { + Self { vm_type: [5, 0] } + } +} diff --git a/sdk/scenario-format/tests/interpreter_test.rs b/sdk/scenario-format/tests/interpreter_test.rs index 19dafb3453..b3a455a9ff 100644 --- a/sdk/scenario-format/tests/interpreter_test.rs +++ b/sdk/scenario-format/tests/interpreter_test.rs @@ -31,6 +31,25 @@ fn test_string() { assert_eq!(EMPTY, interpret_string("str:", &context)); } +#[test] +fn test_mxsc_pack() { + let context = &InterpreterContext::default(); + assert_eq!( + b"test".to_vec(), + interpret_string("mxsc:tests/test.json", context) + ); +} + +#[test] +fn test_mxsc_no_pack() { + let context = &mut InterpreterContext::default().with_allowed_missing_files(); + + assert_eq!( + b"MISSING:\"no_file.json\"".to_vec(), + interpret_string("mxsc:no_file.json", context) + ); +} + #[test] fn test_address() { let context = InterpreterContext::default(); @@ -89,16 +108,16 @@ fn test_address_with_shard_id() { fn test_sc_address() { let context = InterpreterContext::default(); assert_eq!( - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a_____________________".to_vec(), + b"\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00a_____________________".to_vec(), interpret_string("sc:a", &context) ); assert_eq!( - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001234567890123456789012".to_vec(), + b"\x00\x00\x00\x00\x00\x00\x00\x00\x05\x001234567890123456789012".to_vec(), interpret_string("sc:12345678901234567890120s", &context) ); // trims excess assert_eq!( - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001234567890123456789012".to_vec(), + b"\x00\x00\x00\x00\x00\x00\x00\x00\x05\x001234567890123456789012".to_vec(), interpret_string("sc:12345678901234567890120sx", &context) ); } @@ -107,16 +126,16 @@ fn test_sc_address() { fn test_sc_address_with_shard_id() { let context = InterpreterContext::default(); assert_eq!( - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a____________________\x44".to_vec(), + b"\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00a____________________\x44".to_vec(), interpret_string("sc:a#44", &context) ); assert_eq!( - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00123456789012345678901\x88".to_vec(), + b"\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00123456789012345678901\x88".to_vec(), interpret_string("sc:12345678901234567890120#88", &context) ); // trims excess assert_eq!( - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00123456789012345678901\x88".to_vec(), + b"\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00123456789012345678901\x88".to_vec(), interpret_string("sc:12345678901234567890120x#88", &context) ); } diff --git a/sdk/scenario-format/tests/test.json b/sdk/scenario-format/tests/test.json new file mode 100644 index 0000000000..e5ccfe1e65 --- /dev/null +++ b/sdk/scenario-format/tests/test.json @@ -0,0 +1,3 @@ +{ + "code": "74657374" +} \ No newline at end of file diff --git a/tool-update.sh b/tool-update.sh index 2e84043a66..f4db0f552b 100755 --- a/tool-update.sh +++ b/tool-update.sh @@ -2,16 +2,13 @@ # Locally update the VM version -VM_TAG="v1.5.1" +VM_TAG="v1.5.19" echo "Before:" mxpy config dump mxpy config set dependencies.vmtools.tag $VM_TAG +mxpy config set dependencies.vmtools.urlTemplate.linux https://github.com/multiversx/mx-chain-vm-go/archive/{TAG}.tar.gz echo "After:" mxpy config dump mxpy deps install vmtools --overwrite - -# Also update the Rust version - -mxpy deps install rust --tag="nightly" --overwrite diff --git a/tools/interactor-system-func-calls/.gitignore b/tools/interactor-system-func-calls/.gitignore new file mode 100644 index 0000000000..ae87d15dcd --- /dev/null +++ b/tools/interactor-system-func-calls/.gitignore @@ -0,0 +1,9 @@ +# Pem files are used for interactions, but shouldn't be committed +*.pem +!adder-owner.pem + +# Temporary storage of deployed contract address, so we can preserve the context between executions. +state.toml + +# Trace file of interactor tooling +interactor_trace.scen.json \ No newline at end of file diff --git a/tools/interactor-system-func-calls/Cargo.toml b/tools/interactor-system-func-calls/Cargo.toml new file mode 100644 index 0000000000..e9522fccb8 --- /dev/null +++ b/tools/interactor-system-func-calls/Cargo.toml @@ -0,0 +1,25 @@ +[[bin]] +name = "system-sc-interact" +path = "src/system_sc_interact.rs" + +[package] +name = "system-sc-interact" +version = "0.0.0" +publish = false +edition = "2021" +authors = ["you"] + +[dependencies] +toml = "0.8.6" + +[dependencies.clap] +version = "4.4.7" +features = ["derive"] + +[dependencies.serde] +version = "1.0" +features = ["derive"] + +[dependencies.multiversx-sc-snippets] +version = "=0.53.0" +path = "../../framework/snippets" diff --git a/tools/interactor-system-func-calls/README.md b/tools/interactor-system-func-calls/README.md new file mode 100644 index 0000000000..18d1501cf7 --- /dev/null +++ b/tools/interactor-system-func-calls/README.md @@ -0,0 +1,75 @@ +# System SC function calls interactor + +Fungible Tokens docs: https://docs.multiversx.com/tokens/fungible-tokens/ +NFT/SFT/Meta-ESDT docs: https://docs.multiversx.com/tokens/nft-tokens/ + +### Functions: + +- `issue_fungible_token`: Issues a fungible token, it registers the token and sends the initial supply to your wallet +- `issue_non_fungible_collection`: Issues an NFT Collection +- `issue_semi_fungible_collection`: Issues an SFT Collection +- `issue_token`: Registers any kind of token (Fungible/NFT/SFT/Meta-ESDT) and sets all the roles for it. This function doesn't transfer any tokens to your wallet +- `set_roles`: Sets the roles for your address over a specified token ID +- `mint_sft`: Mints an SFT/Meta-ESDT corresponding to a collection +- `register_meta_esdt`: Registers a Meta-ESDT token +- `change_sft_meta_esdt`: Changes an SFT to a Meta-ESDT +- `mint_token`: Mints a fungible token +- `burn_token`: Burns a token +- `pause_token`: Pauses all the transfers for a token +- `unpause_token`: Reverse function of `pause_token` +- `freeze_token`: Freezes a token for an address +- `unfreeze_token`: Reverse function of `freeze_token` +- `freeze_nft`: Freezes an NFT/SFT/Meta-ESDT token for an address +- `unfreeze_nft`: Reverse function of `freeze_nft` +- `wipe_token`: Wipes a token from an address +- `wipe_nft`: Wipes an NFT/SFT/Meta-ESDT token from an address +- `mint_nft`: Mints an NFT corresponding to a collection +- `unset roles`: Unsets the roles for an address over a specified tokenID +- `transfer_ownership`: Transfers the ownership of your token to another address +- `transfer_nft_create_role`: Transfers the NFT Create role to a new address +- `control_changes`: Sets/Unsets properties of a specified tokenID + +### How to use tips + +#### Token types for `issue_token` function + +For CLI use, insert one of the numbers below for the `token-type` parameter + +- 0 => `Fungible` +- 1 => `NonFungible` +- 2 => `SemiFungible` +- 3 => `Meta` +- any other number => `Invalid` + +#### Set/Unset roles + +Before trying to make any kind of interaction with a token (e.g. Mint, Burn, Transfer) you should set the neccessary roles, even if you are the owner of the token. For CLI use, insert one or more numbers from below for the `roles` parameter, each corresponding to a role, each separated by one comma `e.g. --roles 1,2,8` + +- 1 => `Mint` +- 2 => `Burn` +- 3 => `NftCreate` +- 4 => `NftAddQuantity` +- 5 => `NftBurn` +- 6 => `NftAddUri` +- 7 => `NftUpdateAttributes` +- 8 => `Transfer` +- any other number => `None` + +#### Issue fungible token + +- Method 1: `issue_fungible_token` (set the token properties inside the function) +- Method 2: `issue_token`-> `set_roles` (**Mint** role needed for minting the tokens) -> `mint_token` to receive the tokens in your wallet + +#### Issue NFT Collection + Mint an NFT + +- `issue_non_fungible_collection`/`issue_token` -> `set_roles` (**NFTCreate** role needed for minting) -> Mint an NFT by calling `mint_nft` + +#### Issue SFT Collection + +- Issue Collection: `issue_semi_fungible_collection`/`issue_token` -> `set_roles` (**NFTCreate** role needed for minting) -> Mint the amount of SFTs wantes by calling `mint_sft` + +### Register a Meta-ESDT + +- `register_meta_esdt` -> `set_roles`(**NFTCreate**) -> `mint_sft` to mint the Meta-ESDT + +By using `set_roles`(**NFTAddQuantity**) -> `mint_token` you can add quantity to a Meta-ESDT/SFT with a specified nonce diff --git a/tools/interactor-system-func-calls/config.toml b/tools/interactor-system-func-calls/config.toml new file mode 100644 index 0000000000..61ac8dbf87 --- /dev/null +++ b/tools/interactor-system-func-calls/config.toml @@ -0,0 +1 @@ +gateway = 'https://devnet-gateway.multiversx.com' diff --git a/tools/interactor-system-func-calls/src/system_sc_interact.rs b/tools/interactor-system-func-calls/src/system_sc_interact.rs new file mode 100644 index 0000000000..0558eba3c1 --- /dev/null +++ b/tools/interactor-system-func-calls/src/system_sc_interact.rs @@ -0,0 +1,761 @@ +mod system_sc_interact_cli; +mod system_sc_interact_config; +mod system_sc_interact_state; + +use clap::Parser; +use system_sc_interact_cli::NftDummyAttributes; +use system_sc_interact_config::Config; +use system_sc_interact_state::State; + +use multiversx_sc_snippets::imports::*; + +#[tokio::main] +async fn main() { + env_logger::init(); + + let mut basic_interact = SysFuncCallsInteract::init().await; + + let cli = system_sc_interact_cli::InteractCli::parse(); + match &cli.command { + Some(system_sc_interact_cli::InteractCliCommand::IssueToken(args)) => { + basic_interact + .issue_token( + args.cost.clone(), + args.display_name.as_bytes(), + args.ticker.as_bytes(), + args.num_decimals, + args.token_type.into(), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::Mint(args)) => { + basic_interact + .mint_token( + args.token_id.clone().as_bytes(), + args.nonce, + args.amount.clone(), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::SetRoles(args)) => { + basic_interact + .set_roles( + args.token_id.as_bytes(), + args.roles + .clone() + .into_iter() + .map(EsdtLocalRole::from) + .collect(), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::Burn(args)) => { + basic_interact + .burn_token(args.token_id.as_bytes(), args.nonce, args.amount.clone()) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::PauseToken(args)) => { + basic_interact.pause_token(args.token_id.as_bytes()).await; + }, + Some(system_sc_interact_cli::InteractCliCommand::UnpauseToken(args)) => { + basic_interact.unpause_token(args.token_id.as_bytes()).await; + }, + Some(system_sc_interact_cli::InteractCliCommand::FreezeToken(args)) => { + basic_interact + .freeze_token( + args.token_id.as_bytes(), + &Bech32Address::from_bech32_string(args.address.clone()), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::UnfreezeToken(args)) => { + basic_interact + .unfreeze_token( + args.token_id.as_bytes(), + &Bech32Address::from_bech32_string(args.address.clone()), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::FreezeNFT(args)) => { + basic_interact + .freeze_nft( + args.token_id.as_bytes(), + args.nft_nonce, + &Bech32Address::from_bech32_string(args.address.clone()), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::UnfreezeNFT(args)) => { + basic_interact + .unfreeze_nft( + args.token_id.as_bytes(), + args.nft_nonce, + &Bech32Address::from_bech32_string(args.address.clone()), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::WipeToken(args)) => { + basic_interact + .wipe_token( + args.token_id.as_bytes(), + &Bech32Address::from_bech32_string(args.address.clone()), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::WipeNFT(args)) => { + basic_interact + .wipe_nft( + args.token_id.as_bytes(), + args.nft_nonce, + &Bech32Address::from_bech32_string(args.address.clone()), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::IssueNFTCollection(args)) => { + basic_interact + .issue_non_fungible_collection( + args.cost.clone(), + args.display_name.as_bytes(), + args.ticker.as_bytes(), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::CreateNFT(args)) => { + basic_interact + .mint_nft( + args.token_id.as_bytes(), + args.amount.clone(), + args.name.as_bytes(), + args.royalties, + args.hash.as_bytes(), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::IssueFungible(args)) => { + basic_interact + .issue_fungible_token( + args.cost.clone(), + args.display_name.as_bytes(), + args.ticker.as_bytes(), + args.supply.clone(), + args.num_decimals, + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::IssueSftCollection(args)) => { + basic_interact + .issue_semi_fungible_collection( + args.cost.clone(), + args.display_name.as_bytes(), + args.ticker.as_bytes(), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::MintSft(args)) => { + basic_interact + .mint_sft( + args.token_id.as_bytes(), + args.amount.clone(), + args.name.as_bytes(), + args.royalties, + args.hash.as_bytes(), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::RegisterMetaEsdt(args)) => { + basic_interact + .register_meta_esdt( + args.cost.clone(), + args.display_name.as_bytes(), + args.ticker.as_bytes(), + args.num_decimals, + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::ChangeSftMetaEsdt(args)) => { + basic_interact + .change_sft_meta_esdt(args.token_id.as_bytes(), args.num_decimals) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::UnsetRoles(args)) => { + basic_interact + .unset_roles( + &Bech32Address::from_bech32_string(args.address.clone()), + args.token_id.as_bytes(), + args.roles + .clone() + .into_iter() + .map(EsdtLocalRole::from) + .collect(), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::TransferOwnership(args)) => { + basic_interact + .transfer_ownership( + args.token_id.as_bytes(), + &Bech32Address::from_bech32_string(args.new_owner.clone()), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::TransferNftCreateRole(args)) => { + basic_interact + .transfer_nft_create_role( + args.token_id.as_bytes(), + &Bech32Address::from_bech32_string(args.old_owner.clone()), + &Bech32Address::from_bech32_string(args.new_owner.clone()), + ) + .await; + }, + Some(system_sc_interact_cli::InteractCliCommand::ControlChanges(args)) => { + basic_interact + .control_changes(args.token_id.as_bytes()) + .await; + }, + + None => {}, + } +} + +#[allow(unused)] +struct SysFuncCallsInteract { + interactor: Interactor, + wallet_address: Bech32Address, + state: State, +} + +impl SysFuncCallsInteract { + async fn init() -> Self { + let config = Config::load_config(); + let mut interactor = Interactor::new(config.gateway()).await; + + let wallet_address = interactor.register_wallet(test_wallets::alice()); + + Self { + interactor, + wallet_address: wallet_address.into(), + state: State::load_state(), + } + } + + async fn issue_fungible_token( + &mut self, + issue_cost: RustBigUint, + token_display_name: &[u8], + token_ticker: &[u8], + initial_supply: RustBigUint, + num_decimals: usize, + ) { + println!("Issuing fungible token..."); + + let res = self + .interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .issue_fungible( + issue_cost.into(), + &token_display_name, + &token_ticker, + &initial_supply, + FungibleTokenProperties { + num_decimals, + 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, + }, + ) + .returns(ReturnsNewTokenIdentifier) + .prepare_async() + .run() + .await; + + println!("TOKEN ID: {:?}", res); + } + + async fn issue_non_fungible_collection( + &mut self, + issue_cost: RustBigUint, + token_display_name: &[u8], + token_ticker: &[u8], + ) { + println!("Issuing NFT Collection..."); + + let nft_collection_id = self + .interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .issue_non_fungible( + issue_cost.into(), + &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, + }, + ) + .returns(ReturnsNewTokenIdentifier) + .prepare_async() + .run() + .await; + + println!("NFT Collection ID: {:?}", nft_collection_id); + } + + async fn issue_semi_fungible_collection( + &mut self, + issue_cost: RustBigUint, + token_display_name: &[u8], + token_ticker: &[u8], + ) { + println!("Issuing SFT Collection..."); + + let sft_collection_id = self + .interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .issue_semi_fungible( + issue_cost.into(), + &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, + }, + ) + .returns(ReturnsNewTokenIdentifier) + .prepare_async() + .run() + .await; + + println!("SFT Collection ID: {:?}", sft_collection_id); + } + + async fn issue_token( + &mut self, + issue_cost: RustBigUint, + token_display_name: &[u8], + token_ticker: &[u8], + num_decimals: usize, + token_type: EsdtTokenType, + ) { + println!("Registering token..."); + + let token_id = self + .interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .issue_and_set_all_roles( + issue_cost.into(), + token_display_name, + token_ticker, + token_type, + num_decimals, + ) + .returns(ReturnsNewTokenIdentifier) + .prepare_async() + .run() + .await; + + println!("TOKEN ID: {:?}", token_id); + } + + async fn set_roles(&mut self, token_id: &[u8], roles: Vec) { + let wallet_address = &self.wallet_address.clone().into_address(); + println!("Setting the following roles: {:?}", roles); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .set_special_roles( + &ManagedAddress::from_address(wallet_address), + &TokenIdentifier::from(token_id), + roles.into_iter(), + ) + .prepare_async() + .run() + .await; + } + + async fn mint_sft( + &mut self, + token_id: &[u8], + amount: RustBigUint, + name: &[u8], + royalties: u64, + hash: &[u8], + ) { + println!("Minting SFT..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_nft_create( + &token_id, + &amount, + &name, + &royalties, + &hash, + &NftDummyAttributes { + creation_epoch: 2104, + cool_factor: 5, + }, + &ManagedVec::new(), + ) + .prepare_async() + .run() + .await; + } + + async fn register_meta_esdt( + &mut self, + issue_cost: RustBigUint, + token_display_name: &[u8], + token_ticker: &[u8], + num_decimals: usize, + ) { + println!("Registering meta ESDT..."); + + let meta_esdt = self + .interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .register_meta_esdt( + issue_cost.into(), + &token_display_name, + &token_ticker, + MetaTokenProperties { + num_decimals, + can_freeze: true, + can_wipe: true, + can_transfer_create_role: true, + can_change_owner: true, + can_upgrade: true, + can_pause: true, + can_add_special_roles: true, + }, + ) + .returns(ReturnsNewTokenIdentifier) + .prepare_async() + .run() + .await; + + println!("Meta-ESDT ID: {:?}", meta_esdt); + } + + async fn change_sft_meta_esdt(&mut self, token_id: &[u8], num_decimals: usize) { + println!("Changing SFT to Meta-ESDT..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .change_sft_to_meta_esdt(&token_id, num_decimals) + .prepare_async() + .run() + .await; + } + + async fn mint_token(&mut self, token_id: &[u8], nonce: u64, amount: RustBigUint) { + println!("Minting tokens..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_local_mint(&token_id, nonce, &amount) + .prepare_async() + .run() + .await; + } + + async fn burn_token(&mut self, token_id: &[u8], nonce: u64, amount: RustBigUint) { + println!("Burning tokens..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_local_burn(&token_id, nonce, &amount) + .prepare_async() + .run() + .await; + } + + async fn pause_token(&mut self, token_id: &[u8]) { + println!("Pausing token..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .pause(&token_id) + .prepare_async() + .run() + .await; + } + + async fn unpause_token(&mut self, token_id: &[u8]) { + println!("Unpausing token..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .unpause(&token_id) + .prepare_async() + .run() + .await; + } + + async fn freeze_token(&mut self, token_id: &[u8], address: &Bech32Address) { + println!("Freezing token..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .freeze(&token_id, &address) + .prepare_async() + .run() + .await; + } + + async fn unfreeze_token(&mut self, token_id: &[u8], address: &Bech32Address) { + println!("Unfreezing token..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .unfreeze(&token_id, &address) + .prepare_async() + .run() + .await; + } + + async fn freeze_nft(&mut self, token_id: &[u8], nonce: u64, address: &Bech32Address) { + println!("Freezing NFT/SFT/Meta-ESDT..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .freeze_nft(&token_id, nonce, &address) + .prepare_async() + .run() + .await; + } + + async fn unfreeze_nft(&mut self, token_id: &[u8], nonce: u64, address: &Bech32Address) { + println!("Unfreezing NFT/SFT/Meta-ESDT..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .unfreeze_nft(&token_id, nonce, &address) + .prepare_async() + .run() + .await; + } + + async fn wipe_token(&mut self, token_id: &[u8], address: &Bech32Address) { + println!("Wiping token..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .wipe(&token_id, &address) + .prepare_async() + .run() + .await; + } + + async fn wipe_nft(&mut self, token_id: &[u8], nonce: u64, address: &Bech32Address) { + println!("Wiping NFT/SFT/Meta-ESDT..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .wipe_nft(&token_id, nonce, &address) + .prepare_async() + .run() + .await; + } + + async fn mint_nft( + &mut self, + token_id: &[u8], + amount: RustBigUint, + name: &[u8], + royalties: u64, + hash: &[u8], + ) { + println!("Minting NFT..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(&self.wallet_address) + .gas(100_000_000u64) + .typed(UserBuiltinProxy) + .esdt_nft_create( + &token_id, + &amount, + &name, + &royalties, + &hash, + &NftDummyAttributes { + creation_epoch: 2104, + cool_factor: 5, + }, + &ManagedVec::new(), + ) + .prepare_async() + .run() + .await; + } + + async fn unset_roles( + &mut self, + address: &Bech32Address, + token_id: &[u8], + roles: Vec, + ) { + println!("Unsetting the following roles: {:?}", roles); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .unset_special_roles(&address, &token_id, roles.into_iter()) + .prepare_async() + .run() + .await; + } + + async fn transfer_ownership(&mut self, token_id: &[u8], new_owner: &Bech32Address) { + println!("Transferring token ownership..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .transfer_ownership(&token_id, &new_owner) + .prepare_async() + .run() + .await; + } + + async fn transfer_nft_create_role( + &mut self, + token_id: &[u8], + old_owner: &Bech32Address, + new_owner: &Bech32Address, + ) { + println!("Transferring NFT create role..."); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .transfer_nft_create_role(&token_id, &old_owner, &new_owner) + .prepare_async() + .run() + .await; + } + + async fn control_changes(&mut self, token_id: &[u8]) { + println!("Control changes"); + + self.interactor + .tx() + .from(&self.wallet_address) + .to(ESDTSystemSCAddress) + .gas(100_000_000u64) + .typed(ESDTSystemSCProxy) + .control_changes( + &token_id, + &TokenPropertyArguments { + can_freeze: Some(true), + can_wipe: Some(true), + can_pause: Some(true), + can_transfer_create_role: Some(true), + can_mint: Some(true), + can_burn: Some(true), + can_change_owner: Some(true), + can_upgrade: Some(true), + can_add_special_roles: Some(true), + }, + ) + .prepare_async() + .run() + .await; + } +} diff --git a/tools/interactor-system-func-calls/src/system_sc_interact_cli.rs b/tools/interactor-system-func-calls/src/system_sc_interact_cli.rs new file mode 100644 index 0000000000..6e958fbdb3 --- /dev/null +++ b/tools/interactor-system-func-calls/src/system_sc_interact_cli.rs @@ -0,0 +1,286 @@ +use clap::{Args, Parser, Subcommand}; +use multiversx_sc_snippets::{imports::*, multiversx_sc::proxy_imports::*}; + +/// SysFuncCalls Interact CLI +#[derive(Default, PartialEq, Eq, Debug, Parser)] +#[command(version, about)] +#[command(propagate_version = true)] +pub struct InteractCli { + #[command(subcommand)] + pub command: Option, +} + +/// SysFuncCalls Interact CLI Commands +#[derive(Clone, PartialEq, Eq, Debug, Subcommand)] +pub enum InteractCliCommand { + #[command(name = "issue-token", about = "Issues a token")] + IssueToken(IssueTokenArgs), + #[command(name = "mint", about = "Mints fungible tokens")] + Mint(MintArgs), + #[command(name = "set-roles", about = "Sets roles")] + SetRoles(SetRolesArgs), + #[command(name = "burn", about = "Burns fungible tokens")] + Burn(BurnArgs), + #[command(name = "pause-token", about = "Pauses a fungible token")] + PauseToken(PauseTokenArgs), + #[command(name = "unpause-token", about = "Unpauses a fungible token")] + UnpauseToken(PauseTokenArgs), + #[command( + name = "freeze-token", + about = "Freezes a fungible token for an address" + )] + FreezeToken(FreezeTokenArgs), + #[command( + name = "unfreeze-token", + about = "Unfreezes a fungible token for an address" + )] + UnfreezeToken(FreezeTokenArgs), + #[command( + name = "freeze-nft", + about = "Freezes a non-fungible token for an address" + )] + FreezeNFT(FreezeNFTArgs), + #[command( + name = "unfreeze-nft", + about = "Unfreezes a non-fungible token for an address" + )] + UnfreezeNFT(FreezeNFTArgs), + #[command(name = "wipe-token", about = "Wipes a fungible token for an address")] + WipeToken(WipeTokenArgs), + #[command( + name = "wipe-nft", + about = "Freezes a non-fungible token for an address" + )] + WipeNFT(WipeNFTArgs), + #[command(name = "issue-nft-collection", about = "Create a NFT Collection")] + IssueNFTCollection(IssueNftCollectionArgs), + #[command(name = "create-nft", about = "Issue a NFT")] + CreateNFT(CreateNFTArgs), + #[command( + name = "issue-fungible", + about = "Issues fungible tokens and sends them to your wallet" + )] + IssueFungible(IssueFungibleArgs), + #[command(name = "issue-sft-collection", about = "Issues a SFT")] + IssueSftCollection(IssueSftArgs), + #[command(name = "mint-sft", about = "Mints a SFT")] + MintSft(MintSFTArgs), + #[command(name = "register-meta-esdt", about = "Registers a meta ESDT")] + RegisterMetaEsdt(RegisterMetaEsdtArgs), + #[command(name = "change-sft-meta-esdt", about = "Changes a SFT to a Meta ESDT")] + ChangeSftMetaEsdt(ChangeSftMetaEsdtArgs), + #[command(name = "unset-roles", about = "Unsets the roles of a token")] + UnsetRoles(UnsetRolesArgs), + #[command(name = "transfer-ownership", about = "Transfers ownership of a token")] + TransferOwnership(TransferOwnershipArgs), + #[command(name = "transfer-nft-create-role", about = "Transfers NFT create role")] + TransferNftCreateRole(TransferNftCreateRoleArgs), + #[command(name = "control-changes", about = "Controls changes")] + ControlChanges(ControlChangesArgs), +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct IssueTokenArgs { + #[arg(short = 'c', long = "cost", default_value = "50000000000000000")] + pub cost: RustBigUint, + #[arg(short = 'd', long = "display-name")] + pub display_name: String, + #[arg(long = "token-ticker")] + pub ticker: String, + #[arg(long = "token-type")] + pub token_type: u8, + #[arg(long = "num-decimals")] + pub num_decimals: usize, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct MintArgs { + #[arg(long = "token-id")] + pub token_id: String, + #[arg(short = 'n', long = "nonce")] + pub nonce: u64, + #[arg(long = "amount")] + pub amount: RustBigUint, +} + +#[derive(Clone, Debug, PartialEq, Eq, Parser)] +pub struct SetRolesArgs { + #[arg(long = "token-id")] + pub token_id: String, + #[arg(long = "roles", value_delimiter = ',')] + pub roles: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct BurnArgs { + #[arg(long = "token-id")] + pub token_id: String, + #[arg(short = 'n', long = "nonce")] + pub nonce: u64, + #[arg(long = "amount")] + pub amount: RustBigUint, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct IssueFungibleArgs { + #[arg(short = 'c', long = "cost", default_value = "50000000000000000")] + pub cost: RustBigUint, + #[arg(long = "display-name")] + pub display_name: String, + #[arg(long = "token-ticker")] + pub ticker: String, + #[arg(long = "num-decimals")] + pub num_decimals: usize, + #[arg(short = 's', long = "supply")] + pub supply: RustBigUint, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct IssueNftCollectionArgs { + #[arg(short = 'c', long = "cost", default_value = "50000000000000000")] + pub cost: RustBigUint, + #[arg(short = 'd', long = "display-name")] + pub display_name: String, + #[arg(long = "token-ticker")] + pub ticker: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct IssueSftArgs { + #[arg(short = 'c', long = "cost", default_value = "50000000000000000")] + pub cost: RustBigUint, + #[arg(short = 'd', long = "display-name")] + pub display_name: String, + #[arg(long = "token-ticker")] + pub ticker: String, +} + +#[derive(TopEncode, Clone, Debug, PartialEq, Eq)] +pub struct NftDummyAttributes { + pub creation_epoch: u64, + pub cool_factor: u8, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct MintSFTArgs { + #[arg(long = "token-id")] + pub token_id: String, + #[arg(short = 'a', long = "amount")] + pub amount: RustBigUint, + #[arg(short = 'n', long = "name")] + pub name: String, + #[arg(short = 'r', long = "royalties")] + pub royalties: u64, + #[arg(long = "hash")] + pub hash: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct RegisterMetaEsdtArgs { + #[arg(short = 'c', long = "cost", default_value = "50000000000000000")] + pub cost: RustBigUint, + #[arg(short = 'd', long = "display-name")] + pub display_name: String, + #[arg(long = "token-ticker")] + pub ticker: String, + #[arg(long = "num-decimals")] + pub num_decimals: usize, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct ChangeSftMetaEsdtArgs { + #[arg(long = "token-id")] + pub token_id: String, + #[arg(long = "num-decimals")] + pub num_decimals: usize, +} + +#[derive(Clone, Debug, PartialEq, Eq, Parser)] +pub struct UnsetRolesArgs { + #[arg(short = 'a', long = "address")] + pub address: String, + #[arg(long = "token-id")] + pub token_id: String, + #[arg(long = "roles", value_delimiter = ',')] + pub roles: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct TransferOwnershipArgs { + #[arg(long = "token-id")] + pub token_id: String, + #[arg(long = "new-owner")] + pub new_owner: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct TransferNftCreateRoleArgs { + #[arg(long = "token-id")] + pub token_id: String, + #[arg(long = "old-owner")] + pub old_owner: String, + #[arg(long = "new-owner")] + pub new_owner: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct PauseTokenArgs { + #[arg(long = "token-id", default_value = "")] + pub token_id: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct FreezeTokenArgs { + #[arg(long = "token-id", default_value = "")] + pub token_id: String, + #[arg(short = 'a', long = "address")] + pub address: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct FreezeNFTArgs { + #[arg(long = "token-id", default_value = "")] + pub token_id: String, + #[arg(long = "nonce")] + pub nft_nonce: u64, + #[arg(short = 'a', long = "address")] + pub address: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct WipeTokenArgs { + #[arg(long = "token-id", default_value = "")] + pub token_id: String, + #[arg(short = 'a', long = "address")] + pub address: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct WipeNFTArgs { + #[arg(long = "token-id", default_value = "")] + pub token_id: String, + #[arg(long = "nonce")] + pub nft_nonce: u64, + #[arg(short = 'a', long = "address")] + pub address: String, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct CreateNFTArgs { + #[arg(long = "token-id")] + pub token_id: String, + #[arg(short = 'a', long = "amount")] + pub amount: RustBigUint, + #[arg(short = 'n', long = "name")] + pub name: String, + #[arg(long = "hash")] + pub hash: String, + #[arg(short = 'r', long = "royalities")] + pub royalties: u64, +} + +#[derive(Clone, Debug, PartialEq, Eq, Args)] +pub struct ControlChangesArgs { + #[arg(long = "token-id")] + pub token_id: String, +} diff --git a/tools/interactor-system-func-calls/src/system_sc_interact_config.rs b/tools/interactor-system-func-calls/src/system_sc_interact_config.rs new file mode 100644 index 0000000000..4495f069b8 --- /dev/null +++ b/tools/interactor-system-func-calls/src/system_sc_interact_config.rs @@ -0,0 +1,26 @@ +use serde::Deserialize; +use std::io::Read; + +/// Config file +const CONFIG_FILE: &str = "../config.toml"; + +/// SysFuncCalls Interact configuration +#[derive(Debug, Deserialize)] +pub struct Config { + gateway: String, +} + +impl Config { + // Deserializes config from file + pub fn load_config() -> Self { + let mut file = std::fs::File::open(CONFIG_FILE).unwrap(); + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + toml::from_str(&content).unwrap() + } + + // Returns the gateway + pub fn gateway(&self) -> &str { + &self.gateway + } +} diff --git a/tools/interactor-system-func-calls/src/system_sc_interact_state.rs b/tools/interactor-system-func-calls/src/system_sc_interact_state.rs new file mode 100644 index 0000000000..459b6f0bf5 --- /dev/null +++ b/tools/interactor-system-func-calls/src/system_sc_interact_state.rs @@ -0,0 +1,38 @@ +use multiversx_sc_snippets::imports::*; +use serde::{Deserialize, Serialize}; +use std::{ + io::{Read, Write}, + path::Path, +}; + +/// State file +const STATE_FILE: &str = "state.toml"; + +/// Multisig Interact state +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct State { + adder_address: Option, +} + +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() + } + } +} + +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(); + } +} diff --git a/tools/mxpy-snippet-generator/Cargo.toml b/tools/mxpy-snippet-generator/Cargo.toml index 04e71cffe5..bf43d776ac 100644 --- a/tools/mxpy-snippet-generator/Cargo.toml +++ b/tools/mxpy-snippet-generator/Cargo.toml @@ -10,11 +10,11 @@ name = "mxpy-snippet-generator" path = "src/mxpy_snippet_generator.rs" [dependencies.multiversx-sc] -version = "0.44.0" +version = "0.53.0" path = "../../framework/base" [dependencies] -bech32 = "0.9" -num-bigint = "0.4.2" +bech32 = "0.11" +num-bigint = "0.4" num-traits = "0.2" hex = "0.4" diff --git a/tools/mxpy-snippet-generator/src/helper_types.rs b/tools/mxpy-snippet-generator/src/helper_types.rs index d2cb746a51..e012ef2cb6 100644 --- a/tools/mxpy-snippet-generator/src/helper_types.rs +++ b/tools/mxpy-snippet-generator/src/helper_types.rs @@ -1,4 +1,3 @@ -use bech32::FromBase32; use multiversx_sc::types::heap::Address; use crate::constants::*; @@ -79,8 +78,7 @@ impl TransactionType { } pub fn bech32_to_bytes(bech32_address: &str) -> Address { - let (_, dest_address_bytes_u5, _) = bech32::decode(bech32_address).unwrap(); - let dest_address_bytes = Vec::::from_base32(&dest_address_bytes_u5).unwrap(); + let (_hrp, dest_address_bytes) = bech32::decode(bech32_address).unwrap(); if dest_address_bytes.len() != ADDRESS_LEN { panic!("Invalid address length after decoding") } 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/plotter/.gitignore b/tools/plotter/.gitignore new file mode 100644 index 0000000000..769dfbb4ba --- /dev/null +++ b/tools/plotter/.gitignore @@ -0,0 +1,3 @@ +/target +.*.sw* +.vscode/* diff --git a/tools/plotter/Cargo.toml b/tools/plotter/Cargo.toml new file mode 100644 index 0000000000..a3b31c38d4 --- /dev/null +++ b/tools/plotter/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "sc-plotter-wasm" +version = "0.0.0" +authors = ["MultiversX "] +license = "GPL-3.0-only" +repository = "https://github.com/multiversx/mx-sdk-rs" +description = "Web app for displaying function graphs from the framework" +edition = "2021" +publish = false + +[lib] +crate-type=["cdylib"] + +[dependencies] +plotters = "^0.3.2" +wasm-bindgen = "0.2.78" +web-sys = { version = "0.3.39", features = ["HtmlCanvasElement"] } +plotters-canvas = "^0.3.0" + +[profile.release] +lto = true + +[dependencies.multiversx-sc] +version = "=0.53.0" +path = "../../framework/base" + +[dependencies.multiversx-sc-scenario] +version = "=0.53.0" +path = "../../framework/scenario" +default-features = false + +[workspace] +members = ["."] diff --git a/tools/plotter/README.md b/tools/plotter/README.md new file mode 100644 index 0000000000..cfe2983da2 --- /dev/null +++ b/tools/plotter/README.md @@ -0,0 +1,54 @@ +# Example Project of Plotters + WASM + +This is a minimal project that uses Plotters in WASM application. + +- For more information about Plotters project, check our [core repository](https://github.com/plotters-rs/plotters). + +- This demo has been deployed at this [link](https://plotters-rs.github.io/wasm-demo/www/index.html). + +## Try this example locally + +To build the demo you need [wasm-pack](https://rustwasm.github.io/docs/book/game-of-life/setup.html). + +Then you can run it locally either using `npm` and `webpack-dev-server` or +just with static web server. + +The following script will install needed software and run the server via `npm`. +``` +./start-server.sh +``` + +For Windows users without Bash, `start-server.bat` can be used to +launch the server. + +``` +start-server.bat +``` + +## Developing with NPM +Please use [rust-wasm guide](https://rustwasm.github.io/docs/book/game-of-life/setup.html) for initial setup . +Then you can run the demo locally using `npm`: +```bash +wasm-pack build +cd www +npm install +npm start +``` + +This will start a dev server which will automatically reload your page +whenever you change anything in `www` directory. To update `rust` code +call `wasm-pack build` manually. + +## Developing without dependenices +If you don't want to use `npm` here's how you can run the example +using any web server. We are using rust [basic-http-server](https://github.com/brson/basic-http-server), but +any web server will do. + +```bash +# Install web server (instead you can use your local nginx for example) +cargo install basic-http-server +wasm-pack build --target web # Note `--target web` +basic-http-server +``` + +Then open http://127.0.0.1:4000/www diff --git a/tools/plotter/build-wasm.sh b/tools/plotter/build-wasm.sh new file mode 100755 index 0000000000..fc7fe6fb1b --- /dev/null +++ b/tools/plotter/build-wasm.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +CONFIG=release + +rustup target add wasm32-unknown-unknown + +if [ -z "$(cargo install --list | grep wasm-pack)" ] +then + cargo install wasm-pack +fi + +if [ "${CONFIG}" = "release" ] +then + wasm-pack build +else + wasm-pack build --release +fi diff --git a/tools/plotter/src/lib.rs b/tools/plotter/src/lib.rs new file mode 100644 index 0000000000..0e444acc13 --- /dev/null +++ b/tools/plotter/src/lib.rs @@ -0,0 +1,107 @@ +#![allow(clippy::type_complexity)] + +use wasm_bindgen::prelude::*; +use web_sys::HtmlCanvasElement; + +pub mod plotter_ln_big_float; +pub mod plotter_ln_big_uint; +pub mod plotter_ln_managed_decimal; +mod plotter_log2_managed_decimal; + +/// Type alias for the result of a drawing function. +pub type DrawResult = Result>; + +/// Type used on the JS side to convert screen coordinates to chart +/// coordinates. +#[wasm_bindgen] +pub struct Chart { + convert: Box Option<(f64, f64)>>, +} + +/// Result of screen to chart coordinates conversion. +#[wasm_bindgen] +pub struct Point { + pub x: f64, + pub y: f64, +} + +#[wasm_bindgen] +impl Chart { + /// Draw provided functions on the canvas. + /// Return `Chart` struct suitable for coordinate conversion. + pub fn ln_big_uint(canvas: HtmlCanvasElement, max_x: f32) -> Result { + let map_coord = + plotter_ln_big_uint::draw_bu_ln(canvas, max_x).map_err(|err| err.to_string())?; + Ok(Chart { + convert: Box::new(move |coord| map_coord(coord).map(|(x, y)| (x.into(), y.into()))), + }) + } + + pub fn ln_big_uint_error(canvas: HtmlCanvasElement, max_x: f32) -> Result { + let map_coord = + plotter_ln_big_uint::draw_bu_ln_error(canvas, max_x).map_err(|err| err.to_string())?; + Ok(Chart { + convert: Box::new(move |coord| map_coord(coord).map(|(x, y)| (x.into(), y.into()))), + }) + } + + pub fn ln_managed_decimal(canvas: HtmlCanvasElement, max_x: f32) -> Result { + let map_coord = + plotter_ln_managed_decimal::draw_md_ln(canvas, max_x).map_err(|err| err.to_string())?; + Ok(Chart { + convert: Box::new(move |coord| map_coord(coord).map(|(x, y)| (x.into(), y.into()))), + }) + } + + pub fn ln_managed_decimal_error( + canvas: HtmlCanvasElement, + max_x: f32, + ) -> Result { + let map_coord = plotter_ln_managed_decimal::draw_md_ln_error(canvas, max_x) + .map_err(|err| err.to_string())?; + Ok(Chart { + convert: Box::new(move |coord| map_coord(coord).map(|(x, y)| (x.into(), y.into()))), + }) + } + + pub fn log2_managed_decimal(canvas: HtmlCanvasElement, max_x: f32) -> Result { + let map_coord = plotter_log2_managed_decimal::draw_md_log2(canvas, max_x) + .map_err(|err| err.to_string())?; + Ok(Chart { + convert: Box::new(move |coord| map_coord(coord).map(|(x, y)| (x.into(), y.into()))), + }) + } + + pub fn log2_managed_decimal_error( + canvas: HtmlCanvasElement, + max_x: f32, + ) -> Result { + let map_coord = plotter_log2_managed_decimal::draw_md_log2_error(canvas, max_x) + .map_err(|err| err.to_string())?; + Ok(Chart { + convert: Box::new(move |coord| map_coord(coord).map(|(x, y)| (x.into(), y.into()))), + }) + } + + pub fn ln_big_float(canvas: HtmlCanvasElement, max_x: f32) -> Result { + let map_coord = + plotter_ln_big_float::draw_bf_ln(canvas, max_x).map_err(|err| err.to_string())?; + Ok(Chart { + convert: Box::new(move |coord| map_coord(coord).map(|(x, y)| (x.into(), y.into()))), + }) + } + + pub fn ln_big_float_error(canvas: HtmlCanvasElement, max_x: f32) -> Result { + let map_coord = + plotter_ln_big_float::draw_bf_ln_error(canvas, max_x).map_err(|err| err.to_string())?; + Ok(Chart { + convert: Box::new(move |coord| map_coord(coord).map(|(x, y)| (x.into(), y.into()))), + }) + } + + /// This function can be used to convert screen coordinates to + /// chart coordinates. + pub fn coord(&self, x: i32, y: i32) -> Option { + (self.convert)((x, y)).map(|(x, y)| Point { x, y }) + } +} diff --git a/tools/plotter/src/plotter_ln_big_float.rs b/tools/plotter/src/plotter_ln_big_float.rs new file mode 100644 index 0000000000..bc3bc195ce --- /dev/null +++ b/tools/plotter/src/plotter_ln_big_float.rs @@ -0,0 +1,104 @@ +use crate::DrawResult; +use multiversx_sc::types::BigFloat; +use multiversx_sc_scenario::api::StaticApi; +use plotters::prelude::*; +use plotters_canvas::CanvasBackend; +use web_sys::HtmlCanvasElement; + +pub fn draw_bf_ln( + canvas: HtmlCanvasElement, + max_x: f32, +) -> DrawResult Option<(f32, f32)>> { + let root = CanvasBackend::with_canvas_object(canvas) + .unwrap() + .into_drawing_area(); + + let font: FontDesc = ("sans-serif", 20.0).into(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .margin(20u32) + .caption(format!("y=ln(x), x=1..{max_x}"), font) + .x_label_area_size(30u32) + .y_label_area_size(30u32) + .build_cartesian_2d(0f32..max_x, -5f32..5f32)?; + + chart.configure_mesh().x_labels(3).y_labels(3).draw()?; + + const RANGE_MAX: i32 = 1000; + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, ln_baseline(x))), + &RED, + ))?; + + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, big_float_ln(x))), + &GREEN, + ))?; + + root.present()?; + return Ok(chart.into_coord_trans()); +} + +pub fn draw_bf_ln_error( + canvas: HtmlCanvasElement, + max_x: f32, +) -> DrawResult Option<(f32, f32)>> { + let root = CanvasBackend::with_canvas_object(canvas) + .unwrap() + .into_drawing_area(); + + let font: FontDesc = ("sans-serif", 20.0).into(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .margin(20u32) + .caption(format!("y=logarithm error, x=1..{max_x}"), font) + .x_label_area_size(30u32) + .y_label_area_size(50u32) + .build_cartesian_2d(0f32..max_x, -0.0001f32..0.0001f32)?; + + chart.configure_mesh().x_labels(3).y_labels(3).draw()?; + + const RANGE_MAX: i32 = 1000; + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, big_float_ln(x) - ln_baseline(x))), + &RED, + ))?; + + root.present()?; + return Ok(chart.into_coord_trans()); +} + +fn big_float_ln(x: f32) -> f32 { + if let Some(ln) = BigFloat::::from(x).ln() { + ln.to_f64() as f32 + } else { + 0.0 + } +} + +fn ln_baseline(x: f32) -> f32 { + x.ln() +} + +#[cfg(test)] +mod test { + #[test] + fn sc_ln_test() { + assert_eq!(super::big_float_ln(0.0), 0.0); + assert_eq!(super::big_float_ln(1.0), 0.0); + assert!(super::big_float_ln(0.5) < -0.693); + assert!(super::big_float_ln(0.5) > -0.694); + assert!(super::big_float_ln(1.0) < 0.01); + assert!(super::big_float_ln(2.0) > 0.6); + } +} diff --git a/tools/plotter/src/plotter_ln_big_uint.rs b/tools/plotter/src/plotter_ln_big_uint.rs new file mode 100644 index 0000000000..ee1025c400 --- /dev/null +++ b/tools/plotter/src/plotter_ln_big_uint.rs @@ -0,0 +1,108 @@ +use crate::DrawResult; +use multiversx_sc::types::BigUint; +use multiversx_sc_scenario::api::StaticApi; +use plotters::prelude::*; +use plotters_canvas::CanvasBackend; +use web_sys::HtmlCanvasElement; + +pub fn draw_bu_ln( + canvas: HtmlCanvasElement, + max_x: f32, +) -> DrawResult Option<(f32, f32)>> { + let root = CanvasBackend::with_canvas_object(canvas) + .unwrap() + .into_drawing_area(); + + let font: FontDesc = ("sans-serif", 20.0).into(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .margin(20u32) + .caption(format!("y=ln(x), x=1..{max_x}"), font) + .x_label_area_size(30u32) + .y_label_area_size(30u32) + .build_cartesian_2d(0f32..max_x, -1f32..5f32)?; + + chart.configure_mesh().x_labels(3).y_labels(3).draw()?; + + const RANGE_MAX: i32 = 1000; + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, int_ln_baseline(x))), + &RED, + ))?; + + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, big_uint_ln(x))), + &GREEN, + ))?; + + root.present()?; + return Ok(chart.into_coord_trans()); +} + +pub fn draw_bu_ln_error( + canvas: HtmlCanvasElement, + max_x: f32, +) -> DrawResult Option<(f32, f32)>> { + let root = CanvasBackend::with_canvas_object(canvas) + .unwrap() + .into_drawing_area(); + + let font: FontDesc = ("sans-serif", 20.0).into(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .margin(20u32) + .caption(format!("y=logarithm error, x=1..{max_x}"), font) + .x_label_area_size(30u32) + .y_label_area_size(50u32) + .build_cartesian_2d(0f32..max_x, -0.0001f32..0.0001f32)?; + + chart.configure_mesh().x_labels(3).y_labels(3).draw()?; + + const RANGE_MAX: i32 = 1000; + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, big_uint_ln(x) - int_ln_baseline(x))), + &RED, + ))?; + + root.present()?; + return Ok(chart.into_coord_trans()); +} + +fn big_uint_ln(x: f32) -> f32 { + let bu = BigUint::::from(x as u32); + if let Some(ln_dec) = bu.ln() { + ln_dec.into_signed().to_big_float().to_f64() as f32 + } else { + 0.0 + } +} + +fn int_ln_baseline(x: f32) -> f32 { + let floor = x.trunc(); + if floor == 0.0 { + 0.0 + } else { + floor.ln() + } +} + +#[cfg(test)] +mod test { + #[test] + fn sc_ln_test() { + assert_eq!(super::big_uint_ln(0.0), 0.0); + assert!(super::big_uint_ln(1.0) >= 0.0); + assert!(super::big_uint_ln(1.0) < 0.01); + assert!(super::big_uint_ln(2.0) > 0.6); + } +} diff --git a/tools/plotter/src/plotter_ln_managed_decimal.rs b/tools/plotter/src/plotter_ln_managed_decimal.rs new file mode 100644 index 0000000000..58eccd9f65 --- /dev/null +++ b/tools/plotter/src/plotter_ln_managed_decimal.rs @@ -0,0 +1,105 @@ +use crate::DrawResult; +use multiversx_sc::types::{ConstDecimals, ManagedDecimalSigned}; +use multiversx_sc_scenario::api::StaticApi; +use plotters::prelude::*; +use plotters_canvas::CanvasBackend; +use web_sys::HtmlCanvasElement; + +pub fn draw_md_ln( + canvas: HtmlCanvasElement, + max_x: f32, +) -> DrawResult Option<(f32, f32)>> { + let root = CanvasBackend::with_canvas_object(canvas) + .unwrap() + .into_drawing_area(); + + let font: FontDesc = ("sans-serif", 20.0).into(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .margin(20u32) + .caption(format!("y=ln(x), x=1..{max_x}"), font) + .x_label_area_size(30u32) + .y_label_area_size(30u32) + .build_cartesian_2d(0f32..max_x, -5f32..5f32)?; + + chart.configure_mesh().x_labels(3).y_labels(3).draw()?; + + const RANGE_MAX: i32 = 1000; + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, ln_baseline(x))), + &RED, + ))?; + + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, managed_decimal_ln(x))), + &GREEN, + ))?; + + root.present()?; + return Ok(chart.into_coord_trans()); +} + +pub fn draw_md_ln_error( + canvas: HtmlCanvasElement, + max_x: f32, +) -> DrawResult Option<(f32, f32)>> { + let root = CanvasBackend::with_canvas_object(canvas) + .unwrap() + .into_drawing_area(); + + let font: FontDesc = ("sans-serif", 20.0).into(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .margin(20u32) + .caption(format!("y=logarithm error, x=1..{max_x}"), font) + .x_label_area_size(30u32) + .y_label_area_size(50u32) + .build_cartesian_2d(0f32..max_x, -0.0001f32..0.0001f32)?; + + chart.configure_mesh().x_labels(3).y_labels(3).draw()?; + + const RANGE_MAX: i32 = 1000; + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, managed_decimal_ln(x) - ln_baseline(x))), + &RED, + ))?; + + root.present()?; + return Ok(chart.into_coord_trans()); +} + +fn managed_decimal_ln(x: f32) -> f32 { + let dec = ManagedDecimalSigned::>::from(x); + if let Some(ln_dec) = dec.ln() { + ln_dec.to_big_float().to_f64() as f32 + } else { + 0.0 + } +} + +fn ln_baseline(x: f32) -> f32 { + x.ln() +} + +#[cfg(test)] +mod test { + #[test] + fn sc_ln_test() { + assert_eq!(super::managed_decimal_ln(0.0), 0.0); + println!("{}", super::managed_decimal_ln(1.0)); + println!("{}", super::managed_decimal_ln(2.0)); + // assert!(super::big_uint_ln(1.0) >= 0.0); + // assert!(super::big_uint_ln(1.0) < 0.01); + // assert!(super::big_uint_ln(2.0) > 0.6); + } +} diff --git a/tools/plotter/src/plotter_log2_managed_decimal.rs b/tools/plotter/src/plotter_log2_managed_decimal.rs new file mode 100644 index 0000000000..a5e7315fe5 --- /dev/null +++ b/tools/plotter/src/plotter_log2_managed_decimal.rs @@ -0,0 +1,109 @@ +use crate::DrawResult; +use multiversx_sc::types::{ConstDecimals, ManagedDecimalSigned}; +use multiversx_sc_scenario::api::StaticApi; +use plotters::prelude::*; +use plotters_canvas::CanvasBackend; +use web_sys::HtmlCanvasElement; + +pub fn draw_md_log2( + canvas: HtmlCanvasElement, + max_x: f32, +) -> DrawResult Option<(f32, f32)>> { + let root = CanvasBackend::with_canvas_object(canvas) + .unwrap() + .into_drawing_area(); + + let font: FontDesc = ("sans-serif", 20.0).into(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .margin(20u32) + .caption(format!("y=log2(x), x=1..{max_x}"), font) + .x_label_area_size(30u32) + .y_label_area_size(30u32) + .build_cartesian_2d(0f32..max_x, -5f32..5f32)?; + + chart.configure_mesh().x_labels(3).y_labels(3).draw()?; + + const RANGE_MAX: i32 = 1000; + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, log2_baseline(x))), + &RED, + ))?; + + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, managed_decimal_log2(x))), + &GREEN, + ))?; + + root.present()?; + return Ok(chart.into_coord_trans()); +} + +pub fn draw_md_log2_error( + canvas: HtmlCanvasElement, + max_x: f32, +) -> DrawResult Option<(f32, f32)>> { + let root = CanvasBackend::with_canvas_object(canvas) + .unwrap() + .into_drawing_area(); + + let font: FontDesc = ("sans-serif", 20.0).into(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root) + .margin(20u32) + .caption(format!("y=logarithm error, x=1..{max_x}"), font) + .x_label_area_size(30u32) + .y_label_area_size(50u32) + .build_cartesian_2d(0f32..max_x, -0.0001f32..0.0001f32)?; + + chart.configure_mesh().x_labels(3).y_labels(3).draw()?; + + const RANGE_MAX: i32 = 1000; + chart.draw_series(LineSeries::new( + (0..=RANGE_MAX) + .map(|x| x as f32 * max_x / RANGE_MAX as f32) + .map(|x| (x, managed_decimal_log2(x) - log2_baseline(x))), + &RED, + ))?; + + root.present()?; + return Ok(chart.into_coord_trans()); +} + +fn managed_decimal_log2(x: f32) -> f32 { + let dec = ManagedDecimalSigned::>::from(x); + if let Some(ln_dec) = dec.log2() { + ln_dec.to_big_float().to_f64() as f32 + } else { + 0.0 + } +} + +fn log2_baseline(x: f32) -> f32 { + x.log2() +} + +#[cfg(test)] +mod test { + #[test] + fn sc_log2_test() { + assert_eq!(super::managed_decimal_log2(0.0), 0.0); + println!("{}", super::managed_decimal_log2(1.0)); + println!("{}", super::managed_decimal_log2(2.0)); + println!("{}", super::managed_decimal_log2(3.0)); + println!("{}", super::managed_decimal_log2(4.0)); + println!("{}", super::managed_decimal_log2(5.0)); + println!("{}", super::managed_decimal_log2(200.0)); + // assert!(super::big_uint_ln(1.0) >= 0.0); + // assert!(super::big_uint_ln(1.0) < 0.01); + // assert!(super::big_uint_ln(2.0) > 0.6); + } +} diff --git a/tools/plotter/start-server.bat b/tools/plotter/start-server.bat new file mode 100644 index 0000000000..aee88705f2 --- /dev/null +++ b/tools/plotter/start-server.bat @@ -0,0 +1,8 @@ +if not exist "www\pkg" mkdir www\pkg +rustup target add wasm32-unknown-unknown +wasm-pack build --release +if errorlevel 1 cargo install wasm-pack +wasm-pack build --release +cd www +call npm install +npm start diff --git a/tools/plotter/start-server.sh b/tools/plotter/start-server.sh new file mode 100755 index 0000000000..3a5698f05e --- /dev/null +++ b/tools/plotter/start-server.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e + +./build-wasm.sh + +cd www +npm install +npm start diff --git a/tools/plotter/www/.gitignore b/tools/plotter/www/.gitignore new file mode 100644 index 0000000000..16acd49d7f --- /dev/null +++ b/tools/plotter/www/.gitignore @@ -0,0 +1,3 @@ +node_modules +dist +package-lock.json diff --git a/tools/plotter/www/bootstrap.js b/tools/plotter/www/bootstrap.js new file mode 100644 index 0000000000..2520df8952 --- /dev/null +++ b/tools/plotter/www/bootstrap.js @@ -0,0 +1,21 @@ +init(); + +async function init() { + if (typeof process == "object") { + // We run in the npm/webpack environment. + const [{Chart}, {main, setup}] = await Promise.all([ + import("sc-plotter-wasm"), + import("./index.js"), + ]); + setup(Chart); + main(); + } else { + const [{Chart, default: init}, {main, setup}] = await Promise.all([ + import("../pkg/sc_plotter_wasm.js"), + import("./index.js"), + ]); + await init(); + setup(Chart); + main(); + } +} diff --git a/tools/plotter/www/index.html b/tools/plotter/www/index.html new file mode 100644 index 0000000000..b7785a1347 --- /dev/null +++ b/tools/plotter/www/index.html @@ -0,0 +1,41 @@ + + + + + + MultiversX SC function plots + + + + + +
+

MultiversX SC function plots

+
+ +
Loading WebAssembly...
+
+ + +
+ +
+
+
+
+ + diff --git a/tools/plotter/www/index.js b/tools/plotter/www/index.js new file mode 100644 index 0000000000..e5c3e2085c --- /dev/null +++ b/tools/plotter/www/index.js @@ -0,0 +1,115 @@ +// If you only use `npm` you can simply +// import { Chart } from "wasm-demo" and remove `setup` call from `bootstrap.js`. +class Chart { } + +const canvas = document.getElementById("canvas"); +const coord = document.getElementById("coord"); +const plotType = document.getElementById("plot-type"); +const logMax = document.getElementById("logMax"); +const logControl = document.getElementById("logControl"); +const status = document.getElementById("status"); + +let chart = null; + +/** Main entry point */ +export function main() { + let hash = location.hash.substr(1); + for (var i = 0; i < plotType.options.length; i++) { + if (hash == plotType.options[i].value) { + plotType.value = hash; + } + } + setupUI(); + setupCanvas(); +} + +/** This function is used in `bootstrap.js` to setup imports. */ +export function setup(WasmChart) { + Chart = WasmChart; +} + +/** Add event listeners. */ +function setupUI() { + status.innerText = "WebAssembly loaded!"; + plotType.addEventListener("change", updatePlot); + logMax.addEventListener("input", updatePlot); + window.addEventListener("resize", setupCanvas); + window.addEventListener("mousemove", onMouseMove); +} + +/** Setup canvas to properly handle high DPI and redraw current plot. */ +function setupCanvas() { + const dpr = window.devicePixelRatio || 1.0; + const aspectRatio = canvas.width / canvas.height; + const size = canvas.parentNode.offsetWidth * 0.8; + canvas.style.width = size + "px"; + canvas.style.height = size / aspectRatio + "px"; + canvas.width = size; + canvas.height = size / aspectRatio; + updatePlot(); +} + +/** Update displayed coordinates. */ +function onMouseMove(event) { + if (chart) { + var text = "Mouse pointer is out of range"; + + if (event.target == canvas) { + let actualRect = canvas.getBoundingClientRect(); + let logicX = event.offsetX * canvas.width / actualRect.width; + let logicY = event.offsetY * canvas.height / actualRect.height; + const point = chart.coord(logicX, logicY); + text = (point) + ? `(${point.x.toFixed(3)}, ${point.y.toFixed(3)})` + : text; + } + coord.innerText = text; + } +} + +/** Redraw currently selected plot. */ +function updatePlot() { + const selected = plotType.selectedOptions[0]; + status.innerText = `Rendering ${selected.innerText}...`; + chart = null; + const start = performance.now(); + switch (selected.value) { + case "ln-bu": + logControl.classList.remove("hide"); + chart = Chart.ln_big_uint(canvas, Number(logMax.value)); + break; + case "ln-bu-error": + logControl.classList.remove("hide"); + chart = Chart.ln_big_uint_error(canvas, Number(logMax.value)); + break; + case "ln-dec": + logControl.classList.remove("hide"); + chart = Chart.ln_managed_decimal(canvas, Number(logMax.value)); + break; + case "ln-dec-error": + logControl.classList.remove("hide"); + chart = Chart.ln_managed_decimal_error(canvas, Number(logMax.value)); + break; + case "log2-dec": + logControl.classList.remove("hide"); + chart = Chart.log2_managed_decimal(canvas, Number(logMax.value)); + break; + case "log2-dec-error": + logControl.classList.remove("hide"); + chart = Chart.log2_managed_decimal_error(canvas, Number(logMax.value)); + break; + case "ln-bf": + logControl.classList.remove("hide"); + chart = Chart.ln_big_float(canvas, Number(logMax.value)); + break; + case "ln-bf-error": + logControl.classList.remove("hide"); + chart = Chart.ln_big_float_error(canvas, Number(logMax.value)); + break; + default: + logControl.classList.add("hide"); + } + + const end = performance.now(); + status.innerText = `Rendered ${selected.innerText} in ${Math.ceil(end - start)}ms`; +} diff --git a/tools/plotter/www/package.json b/tools/plotter/www/package.json new file mode 100644 index 0000000000..87f6fd3412 --- /dev/null +++ b/tools/plotter/www/package.json @@ -0,0 +1,36 @@ +{ + "name": "plotters-wasm-demo", + "version": "0.1.0", + "description": "Plotters WASM Demo", + "main": "index.js", + "scripts": { + "build": "webpack --config webpack.config.js", + "start": "webpack-dev-server" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/38/plotters.git" + }, + "keywords": [ + "webassembly", + "wasm", + "rust", + "webpack", + "visualization" + ], + "author": "Plotters Developers", + "license": "MIT", + "bugs": { + "url": "https://github.com/38/plotters/issues" + }, + "homepage": "https://github.com/38/plotters", + "dependencies": { + "sc-plotter-wasm": "file:../pkg" + }, + "devDependencies": { + "webpack": "^4.43.0", + "webpack-cli": "^3.3.11", + "webpack-dev-server": "^3.10.3", + "copy-webpack-plugin": "^5.0.0" + } +} diff --git a/tools/plotter/www/style.css b/tools/plotter/www/style.css new file mode 100644 index 0000000000..404d385be6 --- /dev/null +++ b/tools/plotter/www/style.css @@ -0,0 +1,55 @@ +html, body, main { + width: 100%; + margin: 0; + padding: 0; +} + +body { + margin: auto; + max-width: 800px; + display: flex; + flex-direction: column; +} + +@media (max-width: 800px) { + body { + padding: 10px; + box-sizing: border-box; + } +} + +main { + display: flex; + flex-direction: column; + align-items: center; +} + +#coord, #status { + color: grey; + font-size: 10px; + height: 15px +} + +#control { + margin-top: 1em; +} + +#control label { + font-weight: bold; + margin-right: 1em; +} + +#control select { + padding: 0.25em 0.5em; +} + +footer { + margin-top: 2em; + font-size: 12px; + text-align: center; +} + +.hide { + visibility: hidden; + height: 0px; +} diff --git a/tools/plotter/www/webpack.config.js b/tools/plotter/www/webpack.config.js new file mode 100644 index 0000000000..80ad8142d2 --- /dev/null +++ b/tools/plotter/www/webpack.config.js @@ -0,0 +1,14 @@ +const CopyWebpackPlugin = require("copy-webpack-plugin"); +const path = require('path'); + +module.exports = { + entry: "./bootstrap.js", + output: { + path: path.resolve(__dirname, "dist"), + filename: "bootstrap.js", + }, + mode: "development", + plugins: [ + new CopyWebpackPlugin(['index.html']) + ], +}; diff --git a/tools/rust-debugger/format-tests/Cargo.toml b/tools/rust-debugger/format-tests/Cargo.toml index af6c7a436d..8d08a0f8ad 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.44.0" +version = "=0.53.0" path = "../../../framework/base" [dependencies.multiversx-sc-scenario] -version = "0.44.0" +version = "=0.53.0" path = "../../../framework/scenario" [dependencies.multiversx-chain-vm] -version = "0.6.0" +version = "=0.10.0" 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..2c72e4acda 100644 --- a/tools/rust-debugger/format-tests/src/format_tests.rs +++ b/tools/rust-debugger/format-tests/src/format_tests.rs @@ -1,16 +1,13 @@ 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}, - num_bigint::{BigInt as RustBigInt, BigUint as RustBigUint}, -}; +use multiversx_sc_scenario::imports::*; macro_rules! push { ($list: ident, $name:ident, $expected: expr ) => {{ @@ -65,8 +62,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/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py b/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py index 31bf1a7724..1232201e28 100644 --- a/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py +++ b/tools/rust-debugger/pretty-printers/multiversx_sc_lldb_pretty_printers.py @@ -19,13 +19,13 @@ MOD_PATH = "multiversx_sc::types::managed::basic" BIG_INT_TYPE = f"{MOD_PATH}::big_int::BigInt<{DEBUG_API_TYPE}>" -BIG_UINT_TYPE = f"{MOD_PATH}::big_uint::BigUint<{DEBUG_API_TYPE}>" BIG_FLOAT_TYPE = f"{MOD_PATH}::big_float::BigFloat<{DEBUG_API_TYPE}>" MANAGED_BUFFER_TYPE = f"{MOD_PATH}::managed_buffer::ManagedBuffer<{DEBUG_API_TYPE}>" # 3. SC wasm - Managed wrapped types MOD_PATH = "multiversx_sc::types::managed::wrapped" +BIG_UINT_TYPE = f"{MOD_PATH}::big_uint::BigUint<{DEBUG_API_TYPE}>" TOKEN_IDENTIFIER_TYPE = f"{MOD_PATH}::token_identifier::TokenIdentifier<{DEBUG_API_TYPE}>" MANAGED_ADDRESS_TYPE = f"{MOD_PATH}::managed_address::ManagedAddress<{DEBUG_API_TYPE}>" MANAGED_BYTE_ARRAY_TYPE = f"{MOD_PATH}::managed_byte_array::ManagedByteArray<{DEBUG_API_TYPE}, {ANY_NUMBER}>" @@ -320,6 +320,17 @@ def value_summary(self, buffer: lldb.value, context: lldb.value, type_info: lldb return format_buffer_hex(buffer) +class BigUint(PlainManagedVecItem, ManagedType): + def map_picker(self) -> Callable: + return pick_big_int + + def lookup(self, big_uint: lldb.value) -> lldb.value: + return big_uint.value + + def value_summary(self, big_uint: lldb.value, context: lldb.value, type_info: lldb.SBType) -> str: + return big_uint.sbvalue.GetSummary() + + class TokenIdentifier(PlainManagedVecItem, ManagedType): def lookup(self, token_identifier: lldb.value) -> lldb.value: return token_identifier.buffer @@ -462,10 +473,10 @@ def summary(self, optional_value: lldb.value) -> str: (NUM_BIG_UINT_TYPE, NumBigUint), # 2. SC wasm - Managed basic types (BIG_INT_TYPE, BigInt), - (BIG_UINT_TYPE, BigInt), (BIG_FLOAT_TYPE, BigFloat), (MANAGED_BUFFER_TYPE, ManagedBuffer), # 3. SC wasm - Managed wrapped types + (BIG_UINT_TYPE, BigUint), (TOKEN_IDENTIFIER_TYPE, TokenIdentifier), (MANAGED_ADDRESS_TYPE, ManagedAddress), (MANAGED_BYTE_ARRAY_TYPE, ManagedByteArray), diff --git a/vm-test-build-copy.sh b/vm-test-build-copy.sh index 7ccd210ca0..debee4c513 100755 --- a/vm-test-build-copy.sh +++ b/vm-test-build-copy.sh @@ -14,8 +14,9 @@ build_and_copy() { sc-meta all build --target-dir $TARGET_DIR --path $contract_path || return 1 mkdir -p $vm_contract_path/output - cp $contract_path/output/*.wasm \ + cp $contract_path/output/*.mxsc.json \ $vm_contract_path/output + rm $vm_contract_path/output/*.wasm } build_and_copy_with_scenarios() { @@ -26,10 +27,14 @@ build_and_copy_with_scenarios() { sc-meta all build --target-dir $TARGET_DIR --path $contract_path || return 1 mkdir -p $vm_contract_path/output rm -rf $vm_contract_path/scenarios - cp $contract_path/output/*.wasm \ + cp $contract_path/output/*.mxsc.json \ $vm_contract_path/output - cp -R $contract_path/scenarios \ - $vm_contract_path + rm $vm_contract_path/output/*.wasm + + # copying scenarios ... + rsync -av \ + $contract_path/scenarios/ \ + $vm_contract_path/scenarios/ } # building all contracts takes a lot of time, only the ones for the wasm-vm tests are built below @@ -56,20 +61,21 @@ build_and_copy_composability() { contract_with_underscores="${contract//-/_}" sc-meta all build --target-dir $TARGET_DIR --path ./contracts/feature-tests/composability/$contract || return 1 - cp -R contracts/feature-tests/composability/$contract/output/${contract}.wasm \ - $VM_REPO_PATH/test/features/composability/$contract/output/${contract}.wasm + cp -R contracts/feature-tests/composability/$contract/output/${contract}.mxsc.json \ + $VM_REPO_PATH/test/features/composability/$contract/output/${contract}.mxsc.json + rm contracts/feature-tests/composability/$contract/output/*.wasm } -build_and_copy ./contracts/feature-tests/composability/forwarder $VM_REPO_PATH/test/features/composability/forwarder -build_and_copy ./contracts/feature-tests/composability/forwarder-raw $VM_REPO_PATH/test/features/composability/forwarder-raw -build_and_copy ./contracts/feature-tests/composability/proxy-test-first $VM_REPO_PATH/test/features/composability/proxy-test-first -build_and_copy ./contracts/feature-tests/composability/proxy-test-second $VM_REPO_PATH/test/features/composability/proxy-test-second -build_and_copy ./contracts/feature-tests/composability/recursive-caller $VM_REPO_PATH/test/features/composability/recursive-caller -build_and_copy ./contracts/feature-tests/composability/promises-features $VM_REPO_PATH/test/features/composability/promises-features -build_and_copy ./contracts/feature-tests/composability/vault $VM_REPO_PATH/test/features/composability/vault +build_and_copy ./contracts/feature-tests/composability/builtin-func-features $VM_REPO_PATH/test/features/composability/builtin-func-features +build_and_copy ./contracts/feature-tests/composability/forwarder $VM_REPO_PATH/test/features/composability/forwarder +build_and_copy ./contracts/feature-tests/composability/forwarder-queue $VM_REPO_PATH/test/features/composability/forwarder-queue +build_and_copy ./contracts/feature-tests/composability/forwarder-raw $VM_REPO_PATH/test/features/composability/forwarder-raw +build_and_copy ./contracts/feature-tests/composability/proxy-test-first $VM_REPO_PATH/test/features/composability/proxy-test-first +build_and_copy ./contracts/feature-tests/composability/proxy-test-second $VM_REPO_PATH/test/features/composability/proxy-test-second +build_and_copy ./contracts/feature-tests/composability/recursive-caller $VM_REPO_PATH/test/features/composability/recursive-caller +build_and_copy ./contracts/feature-tests/composability/promises-features $VM_REPO_PATH/test/features/composability/promises-features +build_and_copy ./contracts/feature-tests/composability/vault $VM_REPO_PATH/test/features/composability/vault rm -f $VM_REPO_PATH/test/features/composability/scenarios/* cp -R contracts/feature-tests/composability/scenarios \ $VM_REPO_PATH/test/features/composability -cp -R contracts/feature-tests/composability/scenarios-promises \ - $VM_REPO_PATH/test/features/composability diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 860fb4a30d..78c36567af 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multiversx-chain-vm" -version = "0.6.0" +version = "0.10.0" edition = "2021" authors = [ @@ -16,18 +16,23 @@ description = "MultiversX VM implementation and tooling" keywords = ["multiversx", "blockchain", "vm", "tools"] categories = ["cryptography::cryptocurrencies", "development-tools::debugging"] +[features] +# not supported when compiling to wasm +wasm-incompatible = ["rand"] + [dependencies] num-bigint = "0.4" num-traits = "0.2" hex = "0.4" sha2 = "0.10.6" sha3 = "0.10.6" -rand = "0.8.5" -rand_seeder = "0.2.2" -ed25519-dalek = "2.0.0" -itertools = "0.11" -hex-literal = "0.4.1" -bitflags = "1.3.2" +itertools = "0.13.0" +hex-literal = "=0.4.1" +bitflags = "=2.6.0" +colored = "2.1.0" +rand = { version= "0.8.5", optional = true } +rand_seeder = "0.3.0" +ed25519-dalek = "2.1.0" [dependencies.multiversx-chain-vm-executor] version = "0.2.0" diff --git a/vm/src/crypto_functions.rs b/vm/src/crypto_functions.rs index 3e64b7f9a2..3dae63aad7 100644 --- a/vm/src/crypto_functions.rs +++ b/vm/src/crypto_functions.rs @@ -1,4 +1,3 @@ -use ed25519_dalek::*; use sha2::Sha256; use sha3::{Digest, Keccak256}; @@ -18,6 +17,8 @@ pub fn keccak256(data: &[u8]) -> [u8; KECCAK256_RESULT_LEN] { } pub fn verify_ed25519(key: &[u8], message: &[u8], signature: &[u8]) -> bool { + use ed25519_dalek::{Signature, Verifier, VerifyingKey}; + let key_32: [u8; 32] = if let Ok(key_32) = key.try_into() { key_32 } else { diff --git a/vm/src/tx_execution.rs b/vm/src/tx_execution.rs index a3082074b9..f81b94ffce 100644 --- a/vm/src/tx_execution.rs +++ b/vm/src/tx_execution.rs @@ -9,7 +9,5 @@ mod system_sc; pub use blockchain_vm::{BlockchainVM, BlockchainVMRef}; pub use builtin_function_mocks::*; pub use exec_call::*; -pub use exec_contract_endpoint::*; -pub use exec_create::*; -pub use exec_general_tx::*; +pub(crate) use exec_general_tx::*; pub use system_sc::*; 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_execution/builtin_function_mocks/general/upgrade_contract.rs b/vm/src/tx_execution/builtin_function_mocks/general/upgrade_contract.rs index d72bb353ae..7de2032273 100644 --- a/vm/src/tx_execution/builtin_function_mocks/general/upgrade_contract.rs +++ b/vm/src/tx_execution/builtin_function_mocks/general/upgrade_contract.rs @@ -1,6 +1,11 @@ -use crate::tx_execution::{builtin_function_names::UPGRADE_CONTRACT_FUNC_NAME, BlockchainVMRef}; +use crate::tx_execution::{ + builtin_function_names::UPGRADE_CONTRACT_FUNC_NAME, create_transfer_value_log, BlockchainVMRef, +}; -use crate::tx_mock::{BlockchainUpdate, TxCache, TxFunctionName, TxInput, TxResult}; +use crate::{ + tx_mock::{BlockchainUpdate, CallType, TxCache, TxFunctionName, TxInput, TxResult}, + types::VMCodeMetadata, +}; use super::super::builtin_func_trait::BuiltinFunction; @@ -29,9 +34,7 @@ impl BuiltinFunction for UpgradeContract { } let new_code = tx_input.args[0].clone(); - - // tx_input.args[1] is the code metadata, we ignore for now - // TODO: model code metadata in Mandos + let code_metadata = VMCodeMetadata::from(&tx_input.args[1]); let args = if tx_input.args.len() > 2 { tx_input.args[2..].to_vec() @@ -41,21 +44,37 @@ impl BuiltinFunction for UpgradeContract { tx_cache.with_account_mut(&tx_input.to, |account| { account.contract_path = Some(new_code); + account.code_metadata = code_metadata; }); + let transfer_value_log = create_transfer_value_log(&tx_input, CallType::UpgradeFromSource); + let exec_input = TxInput { from: tx_input.from, to: tx_input.to, egld_value: tx_input.egld_value, esdt_values: Vec::new(), - func_name: TxFunctionName::INIT, + func_name: TxFunctionName::UPGRADE, args, gas_limit: tx_input.gas_limit, gas_price: tx_input.gas_price, tx_hash: tx_input.tx_hash, + call_type: CallType::UpgradeFromSource, ..Default::default() }; - vm.default_execution(exec_input, tx_cache, f) + let (mut tx_result, blockchain_updates) = vm.default_execution(exec_input, tx_cache, f); + adjust_upgrade_log_endpoint(&mut tx_result); + tx_result.result_logs.insert(0, transfer_value_log); + (tx_result, blockchain_updates) + } +} + +/// A small anomaly in the VM: logs from the "upgrade" function appear under "upgradeContract". +fn adjust_upgrade_log_endpoint(tx_result: &mut TxResult) { + for log in &mut tx_result.result_logs { + if log.endpoint == TxFunctionName::UPGRADE { + log.endpoint = UPGRADE_CONTRACT_FUNC_NAME.into(); + } } } diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs index ea891d8079..183819f372 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs @@ -1,6 +1,7 @@ use crate::{ tx_execution::{builtin_function_names::ESDT_MULTI_TRANSFER_FUNC_NAME, BlockchainVMRef}, - types::top_decode_u64, + tx_mock::TxLog, + types::{top_decode_u64, top_encode_u64}, }; use crate::{ @@ -12,7 +13,8 @@ use crate::{ use super::{ super::BuiltinFunction, transfer_common::{ - execute_transfer_builtin_func, extract_transfer_info, ParsedTransferBuiltinFunCall, + adjust_call_type, execute_transfer_builtin_func, extract_transfer_info, + push_func_name_if_necessary, push_transfer_bytes, ParsedTransferBuiltinFunCall, RawEsdtTransfer, }, }; @@ -44,7 +46,8 @@ impl BuiltinFunction for ESDTMultiTransfer { { match try_parse_input(&tx_input) { Ok(parsed_tx) => { - execute_transfer_builtin_func(vm, parsed_tx, self.name(), tx_input, tx_cache, f) + let log = build_log(&tx_input, &parsed_tx); + execute_transfer_builtin_func(vm, parsed_tx, tx_input, tx_cache, log, f) }, Err(message) => { let err_result = TxResult::from_vm_error(message); @@ -54,6 +57,29 @@ impl BuiltinFunction for ESDTMultiTransfer { } } +fn build_log(tx_input: &TxInput, call: &ParsedTransferBuiltinFunCall) -> TxLog { + let call_type = adjust_call_type(tx_input.call_type, call); + let mut topics = Vec::new(); + push_transfer_bytes(&call.raw_esdt_transfers, &mut topics); + topics.push(call.destination.to_vec()); + + let mut data = vec![ + call_type.to_log_bytes(), + ESDT_MULTI_TRANSFER_FUNC_NAME.into(), + call.destination.to_vec(), + top_encode_u64(call.raw_esdt_transfers.len() as u64), + ]; + push_transfer_bytes(&call.raw_esdt_transfers, &mut data); + push_func_name_if_necessary(call_type, &call.func_name, &mut data); + + TxLog { + address: tx_input.from.clone(), + endpoint: ESDT_MULTI_TRANSFER_FUNC_NAME.into(), + topics, + data, + } +} + fn try_parse_input(tx_input: &TxInput) -> Result { if tx_input.args.len() < 2 { return Err("MultiESDTNFTTransfer too few arguments"); diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_nft_transfer_mock.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_nft_transfer_mock.rs index 9cd55bda73..24d5925662 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_nft_transfer_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_nft_transfer_mock.rs @@ -3,14 +3,15 @@ use crate::{ builtin_function_names::ESDT_NFT_TRANSFER_FUNC_NAME, BlockchainVMRef, BuiltinFunctionEsdtTransferInfo, }, - tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}, + tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, types::VMAddress, }; use super::{ super::BuiltinFunction, transfer_common::{ - execute_transfer_builtin_func, extract_transfer_info, ParsedTransferBuiltinFunCall, + adjust_call_type, execute_transfer_builtin_func, extract_transfer_info, + push_func_name_if_necessary, push_transfer_bytes, ParsedTransferBuiltinFunCall, RawEsdtTransfer, }, }; @@ -42,7 +43,8 @@ impl BuiltinFunction for ESDTNftTransfer { { match try_parse_input(&tx_input) { Ok(parsed_tx) => { - execute_transfer_builtin_func(vm, parsed_tx, self.name(), tx_input, tx_cache, f) + let log = build_log(&tx_input, &parsed_tx); + execute_transfer_builtin_func(vm, parsed_tx, tx_input, tx_cache, log, f) }, Err(message) => { let err_result = TxResult::from_vm_error(message); @@ -52,6 +54,28 @@ impl BuiltinFunction for ESDTNftTransfer { } } +fn build_log(tx_input: &TxInput, call: &ParsedTransferBuiltinFunCall) -> TxLog { + let call_type = adjust_call_type(tx_input.call_type, call); + let mut topics = Vec::new(); + push_transfer_bytes(&call.raw_esdt_transfers, &mut topics); + topics.push(call.destination.to_vec()); + + let mut data = Vec::new(); + + data.push(call_type.to_log_bytes()); + data.push(ESDT_NFT_TRANSFER_FUNC_NAME.into()); + push_transfer_bytes(&call.raw_esdt_transfers, &mut data); + data.push(call.destination.to_vec()); + push_func_name_if_necessary(call_type, &call.func_name, &mut data); + + TxLog { + address: tx_input.from.clone(), + endpoint: ESDT_NFT_TRANSFER_FUNC_NAME.into(), + topics, + data, + } +} + fn try_parse_input(tx_input: &TxInput) -> Result { if tx_input.args.len() < 4 { return Err("ESDTNFTTransfer too few arguments"); diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_transfer_mock.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_transfer_mock.rs index f9bd268ddf..8f5a912a2a 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_transfer_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_transfer_mock.rs @@ -3,13 +3,14 @@ use crate::{ builtin_function_names::ESDT_TRANSFER_FUNC_NAME, BlockchainVMRef, BuiltinFunctionEsdtTransferInfo, }, - tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}, + tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, }; use super::{ super::builtin_func_trait::BuiltinFunction, transfer_common::{ - execute_transfer_builtin_func, extract_transfer_info, ParsedTransferBuiltinFunCall, + adjust_call_type, execute_transfer_builtin_func, extract_transfer_info, + push_func_name_if_necessary, push_transfer_bytes, ParsedTransferBuiltinFunCall, RawEsdtTransfer, }, }; @@ -41,7 +42,8 @@ impl BuiltinFunction for ESDTTransfer { { match try_parse_input(&tx_input) { Ok(parsed_tx) => { - execute_transfer_builtin_func(vm, parsed_tx, self.name(), tx_input, tx_cache, f) + let log = build_log(&tx_input, &parsed_tx); + execute_transfer_builtin_func(vm, parsed_tx, tx_input, tx_cache, log, f) }, Err(message) => { let err_result = TxResult::from_vm_error(message); @@ -51,6 +53,28 @@ impl BuiltinFunction for ESDTTransfer { } } +fn build_log(tx_input: &TxInput, call: &ParsedTransferBuiltinFunCall) -> TxLog { + let call_type = adjust_call_type(tx_input.call_type, call); + let mut topics = Vec::new(); + push_transfer_bytes(&call.raw_esdt_transfers, &mut topics); + topics.push(call.destination.to_vec()); + + let mut data = vec![ + call_type.to_log_bytes(), + ESDT_TRANSFER_FUNC_NAME.into(), + call.raw_esdt_transfers[0].token_identifier.clone(), + call.raw_esdt_transfers[0].value_bytes.clone(), + ]; + push_func_name_if_necessary(call_type, &call.func_name, &mut data); + + TxLog { + address: tx_input.from.clone(), + endpoint: ESDT_TRANSFER_FUNC_NAME.into(), + topics, + data, + } +} + fn try_parse_input(tx_input: &TxInput) -> Result { if tx_input.args.len() < 2 { return Err("ESDTTransfer too few arguments"); diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/transfer_common.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/transfer_common.rs index 089ca8e18e..635d1be258 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/transfer_common.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/transfer_common.rs @@ -4,7 +4,8 @@ use crate::{ BlockchainVMRef, }, tx_mock::{ - BlockchainUpdate, TxCache, TxFunctionName, TxInput, TxLog, TxResult, TxTokenTransfer, + BlockchainUpdate, CallType, TxCache, TxFunctionName, TxInput, TxLog, TxResult, + TxTokenTransfer, }, types::{top_decode_u64, VMAddress}, }; @@ -24,6 +25,15 @@ pub(super) struct RawEsdtTransfer { pub value_bytes: Vec, } +/// Convenience function for populating log topics and data with transfer fields as bytes. +pub(super) fn push_transfer_bytes(transfers: &[RawEsdtTransfer], dest: &mut Vec>) { + for transfer in transfers { + dest.push(transfer.token_identifier.clone()); + dest.push(transfer.nonce_bytes.clone()); + dest.push(transfer.value_bytes.clone()); + } +} + pub(super) fn process_raw_esdt_transfer(raw_esdt_transfer: RawEsdtTransfer) -> TxTokenTransfer { TxTokenTransfer { token_identifier: raw_esdt_transfer.token_identifier, @@ -51,29 +61,14 @@ pub(super) fn extract_transfer_info( pub(super) fn execute_transfer_builtin_func( vm: &BlockchainVMRef, parsed_tx: ParsedTransferBuiltinFunCall, - builtin_function_name: &str, tx_input: TxInput, tx_cache: TxCache, + log: TxLog, f: F, ) -> (TxResult, BlockchainUpdate) where F: FnOnce(), { - let mut builtin_logs = Vec::new(); - for raw_esdt_transfer in &parsed_tx.raw_esdt_transfers { - builtin_logs.push(TxLog { - address: tx_input.from.clone(), - endpoint: builtin_function_name.into(), - topics: vec![ - raw_esdt_transfer.token_identifier.clone(), - raw_esdt_transfer.nonce_bytes.clone(), - raw_esdt_transfer.value_bytes.clone(), - parsed_tx.destination.to_vec(), - ], - data: vec![], - }); - } - let exec_input = TxInput { from: tx_input.from, to: parsed_tx.destination, @@ -90,7 +85,35 @@ where let (mut tx_result, blockchain_updates) = vm.default_execution(exec_input, tx_cache, f); // prepends esdt log - tx_result.result_logs = [builtin_logs.as_slice(), tx_result.result_logs.as_slice()].concat(); + // tx_result.result_logs = [builtin_logs.as_slice(), tx_result.result_logs.as_slice()].concat(); + tx_result.result_logs.insert(0, log); (tx_result, blockchain_updates) } + +pub(super) fn adjust_call_type( + call_type: CallType, + call: &ParsedTransferBuiltinFunCall, +) -> CallType { + if call_type == CallType::TransferExecute && call.func_name.is_empty() { + CallType::DirectCall + } else { + call_type + } +} + +pub(super) fn push_func_name_if_necessary( + call_type: CallType, + func_name: &TxFunctionName, + data: &mut Vec>, +) { + if call_type == CallType::DirectCall { + return; + } + + if func_name.is_empty() { + return; + } + + data.push(func_name.clone().into_bytes()); +} diff --git a/vm/src/tx_execution/exec_call.rs b/vm/src/tx_execution/exec_call.rs index 35d3536fe4..ffc48e12ae 100644 --- a/vm/src/tx_execution/exec_call.rs +++ b/vm/src/tx_execution/exec_call.rs @@ -1,10 +1,10 @@ use crate::{ tx_mock::{ - async_call_tx_input, async_callback_tx_input, async_promise_tx_input, merge_results, - AsyncCallTxData, BlockchainUpdate, Promise, TxCache, TxContext, TxContextStack, TxInput, - TxPanic, TxResult, TxResultCalls, + async_call_tx_input, async_callback_tx_input, async_promise_callback_tx_input, + merge_results, AsyncCallTxData, BlockchainUpdate, CallType, Promise, TxCache, TxContext, + TxContextStack, TxInput, TxPanic, TxResult, TxResultCalls, }, - types::VMAddress, + types::VMCodeMetadata, with_shared::Shareable, world_mock::{AccountData, AccountEsdt, BlockchainState}, }; @@ -105,7 +105,7 @@ impl BlockchainVMRef { state: &mut Shareable, ) -> (TxResult, TxResult) { if state.accounts.contains_key(&async_data.to) { - let async_input = async_call_tx_input(&async_data); + let async_input = async_call_tx_input(&async_data, CallType::AsyncCall); let async_result = self.sc_call_with_async_and_callback( async_input, @@ -148,7 +148,6 @@ impl BlockchainVMRef { F: FnOnce(), { // main call - let contract_address = tx_input.to.clone(); let mut tx_result = self.execute_sc_call_lambda(tx_input, state, f); // take & clear pending calls @@ -172,7 +171,7 @@ impl BlockchainVMRef { // the promises are also reset for promise in pending_calls.promises { let (async_result, callback_result) = - self.execute_promise_call_and_callback(&contract_address, &promise, state); + self.execute_promise_call_and_callback(&promise, state); tx_result = merge_results(tx_result, async_result.clone()); tx_result = merge_results(tx_result, callback_result.clone()); @@ -183,28 +182,17 @@ impl BlockchainVMRef { pub fn execute_promise_call_and_callback( &self, - address: &VMAddress, promise: &Promise, state: &mut Shareable, ) -> (TxResult, TxResult) { if state.accounts.contains_key(&promise.call.to) { - let async_input = async_call_tx_input(&promise.call); + let async_input = async_call_tx_input(&promise.call, CallType::AsyncCall); let async_result = self.sc_call_with_async_and_callback( async_input, state, execute_current_tx_context_input, ); - - let callback_input = async_promise_tx_input(address, promise, &async_result); - let callback_result = self.execute_sc_call_lambda( - callback_input, - state, - execute_current_tx_context_input, - ); - assert!( - callback_result.pending_calls.promises.is_empty(), - "successive promises currently not supported" - ); + let callback_result = self.execute_promises_callback(&async_result, promise, state); (async_result, callback_result) } else { let result = self.insert_ghost_account(&promise.call, state); @@ -218,6 +206,26 @@ impl BlockchainVMRef { } } + fn execute_promises_callback( + &self, + async_result: &TxResult, + promise: &Promise, + state: &mut Shareable, + ) -> TxResult { + if !promise.has_callback() { + return TxResult::empty(); + } + let callback_input = + async_promise_callback_tx_input(promise, async_result, &self.builtin_functions); + let callback_result = + self.execute_sc_call_lambda(callback_input, state, execute_current_tx_context_input); + assert!( + callback_result.pending_calls.promises.is_empty(), + "successive promises currently not supported" + ); + callback_result + } + /// When calling a contract that is unknown to the state, we insert a ghost account. fn insert_ghost_account( &self, @@ -235,6 +243,7 @@ impl BlockchainVMRef { username: Vec::new(), storage: HashMap::new(), contract_path: None, + code_metadata: VMCodeMetadata::empty(), contract_owner: None, developer_rewards: BigUint::zero(), }); diff --git a/vm/src/tx_execution/exec_create.rs b/vm/src/tx_execution/exec_create.rs index 9755c6211c..a67ef61056 100644 --- a/vm/src/tx_execution/exec_create.rs +++ b/vm/src/tx_execution/exec_create.rs @@ -1,6 +1,6 @@ use crate::{ tx_mock::{TxCache, TxInput, TxResult}, - types::VMAddress, + types::{VMAddress, VMCodeMetadata}, with_shared::Shareable, world_mock::BlockchainState, }; @@ -12,6 +12,7 @@ impl BlockchainVMRef { &self, tx_input: TxInput, contract_path: &[u8], + code_metadata: VMCodeMetadata, state: &mut Shareable, f: F, ) -> (VMAddress, TxResult) @@ -26,7 +27,7 @@ impl BlockchainVMRef { let (tx_result, new_address, blockchain_updates) = state.with_shared(|state_arc| { let tx_cache = TxCache::new(state_arc); - self.deploy_contract(tx_input, contract_path.to_vec(), tx_cache, f) + self.deploy_contract(tx_input, contract_path.to_vec(), code_metadata, tx_cache, f) }); blockchain_updates.apply(state); diff --git a/vm/src/tx_execution/exec_general_tx.rs b/vm/src/tx_execution/exec_general_tx.rs index 3fd572abd4..2100e3fb20 100644 --- a/vm/src/tx_execution/exec_general_tx.rs +++ b/vm/src/tx_execution/exec_general_tx.rs @@ -3,10 +3,10 @@ use num_traits::Zero; use crate::{ tx_execution::execute_system_sc, tx_mock::{ - BlockchainUpdate, TxCache, TxContext, TxContextStack, TxFunctionName, TxInput, TxLog, - TxResult, + BlockchainUpdate, CallType, TxCache, TxContext, TxContextStack, TxFunctionName, TxInput, + TxLog, TxResult, }, - types::VMAddress, + types::{top_encode_big_uint, VMAddress, VMCodeMetadata}, with_shared::Shareable, }; @@ -27,6 +27,45 @@ fn should_execute_sc_call(tx_input: &TxInput) -> bool { !tx_input.func_name.is_empty() } +fn should_add_transfer_value_log(tx_input: &TxInput) -> bool { + if tx_input.call_type == CallType::AsyncCallback + && !tx_input.callback_payments.esdt_values.is_empty() + { + // edge case in the VM + return false; + } + + if tx_input.call_type == CallType::UpgradeFromSource { + // already handled in upgradeContract builtin function + return false; + } + + if tx_input.call_type != CallType::DirectCall { + return true; + } + + // skip for transactions coming directly from scenario json, which should all be coming from user wallets + tx_input.from.is_smart_contract_address() && !tx_input.egld_value.is_zero() +} + +pub(crate) fn create_transfer_value_log(tx_input: &TxInput, call_type: CallType) -> TxLog { + let mut data = vec![call_type.to_log_bytes(), tx_input.func_name.to_bytes()]; + data.append(&mut tx_input.args.clone()); + + let egld_value = if tx_input.call_type == CallType::AsyncCallback { + &tx_input.callback_payments.egld_value + } else { + &tx_input.egld_value + }; + + TxLog { + address: tx_input.from.clone(), + endpoint: "transferValueOnly".into(), + topics: vec![top_encode_big_uint(egld_value), tx_input.to.to_vec()], + data, + } +} + impl BlockchainVMRef { /// Executes without builtin functions, directly on the contract or the given lambda closure. pub fn default_execution( @@ -44,21 +83,8 @@ impl BlockchainVMRef { return (TxResult::from_panic_obj(&err), BlockchainUpdate::empty()); } - // skip for transactions coming directly from scenario json, which should all be coming from user wallets - // TODO: reorg context logic - let add_transfer_log = - tx_input.from.is_smart_contract_address() && !tx_input.egld_value.is_zero(); - let transfer_value_log = if add_transfer_log { - Some(TxLog { - address: VMAddress::zero(), // TODO: figure out the real VM behavior - endpoint: "transferValueOnly".into(), - topics: vec![ - tx_input.from.to_vec(), - tx_input.to.to_vec(), - tx_input.egld_value.to_bytes_be(), - ], - data: Vec::new(), - }) + let transfer_value_log = if should_add_transfer_value_log(&tx_input) { + Some(create_transfer_value_log(&tx_input, tx_input.call_type)) } else { None }; @@ -102,6 +128,7 @@ impl BlockchainVMRef { &self, mut tx_input: TxInput, contract_path: Vec, + code_metadata: VMCodeMetadata, tx_cache: TxCache, f: F, ) -> (TxResult, VMAddress, BlockchainUpdate) @@ -125,7 +152,12 @@ impl BlockchainVMRef { BlockchainUpdate::empty(), ); } - tx_context_sh.create_new_contract(&new_address, contract_path, tx_input_ref.from.clone()); + tx_context_sh.create_new_contract( + &new_address, + contract_path, + code_metadata, + tx_input_ref.from.clone(), + ); tx_context_sh .tx_cache .increase_egld_balance(&new_address, &tx_input_ref.egld_value); diff --git a/vm/src/tx_mock.rs b/vm/src/tx_mock.rs index 8738e62482..ce63ddfe7a 100644 --- a/vm/src/tx_mock.rs +++ b/vm/src/tx_mock.rs @@ -1,6 +1,5 @@ #![allow(clippy::type_complexity)] -mod blockchain_rng; mod blockchain_update; mod tx_async_call_data; mod tx_async_promise; @@ -12,6 +11,7 @@ mod tx_context; mod tx_context_ref; mod tx_context_stack; mod tx_input; +mod tx_input_call_type; mod tx_input_function; mod tx_log; mod tx_managed_types; @@ -19,7 +19,6 @@ mod tx_panic; mod tx_result; mod tx_result_calls; -pub use blockchain_rng::*; pub use blockchain_update::BlockchainUpdate; pub use tx_async_call_data::*; pub use tx_async_promise::*; @@ -30,9 +29,20 @@ pub use tx_context::*; pub use tx_context_ref::*; pub use tx_context_stack::*; pub use tx_input::*; +pub use tx_input_call_type::CallType; pub use tx_input_function::*; pub use tx_log::*; pub use tx_managed_types::*; pub use tx_panic::*; pub use tx_result::*; pub use tx_result_calls::*; + +#[cfg(feature = "wasm-incompatible")] +mod blockchain_rng; +#[cfg(feature = "wasm-incompatible")] +pub use blockchain_rng::BlockchainRng; + +#[cfg(not(feature = "wasm-incompatible"))] +mod blockchain_rng_unsupported; +#[cfg(not(feature = "wasm-incompatible"))] +pub use blockchain_rng_unsupported::BlockchainRng; diff --git a/vm/src/tx_mock/blockchain_rng.rs b/vm/src/tx_mock/blockchain_rng.rs index bbcfafee8d..b16e9e2062 100644 --- a/vm/src/tx_mock/blockchain_rng.rs +++ b/vm/src/tx_mock/blockchain_rng.rs @@ -31,7 +31,7 @@ impl BlockchainRng { } } - pub fn fill(&mut self, dest: &mut T) { + fn fill(&mut self, dest: &mut T) { self.rng.fill(dest); } diff --git a/vm/src/tx_mock/blockchain_rng_unsupported.rs b/vm/src/tx_mock/blockchain_rng_unsupported.rs new file mode 100644 index 0000000000..6339cbaffc --- /dev/null +++ b/vm/src/tx_mock/blockchain_rng_unsupported.rs @@ -0,0 +1,14 @@ +use super::{TxCache, TxInput}; + +#[derive(Debug)] +pub struct BlockchainRng; + +impl BlockchainRng { + pub fn new(_tx_input: &TxInput, _tx_cache: &TxCache) -> Self { + BlockchainRng + } + + pub fn next_bytes(&mut self, _length: usize) -> Vec { + panic!("BlockchainRng not supported for wasm builds, feature `wasm-incompatible` needs to be enabled") + } +} diff --git a/vm/src/tx_mock/tx_async_call_data.rs b/vm/src/tx_mock/tx_async_call_data.rs index 2a7e0af46e..45cbce639c 100644 --- a/vm/src/tx_mock/tx_async_call_data.rs +++ b/vm/src/tx_mock/tx_async_call_data.rs @@ -6,7 +6,7 @@ use crate::{ use num_bigint::BigUint; -use super::{CallbackPayments, Promise, TxFunctionName}; +use super::{CallType, CallbackPayments, Promise, TxFunctionName}; #[derive(Debug, Clone)] pub struct AsyncCallTxData { @@ -18,7 +18,7 @@ pub struct AsyncCallTxData { pub tx_hash: H256, } -pub fn async_call_tx_input(async_call: &AsyncCallTxData) -> TxInput { +pub fn async_call_tx_input(async_call: &AsyncCallTxData, call_type: CallType) -> TxInput { TxInput { from: async_call.from.clone(), to: async_call.to.clone(), @@ -26,6 +26,7 @@ pub fn async_call_tx_input(async_call: &AsyncCallTxData) -> TxInput { esdt_values: Vec::new(), func_name: async_call.endpoint_name.clone(), args: async_call.arguments.clone(), + call_type, gas_limit: 1000, gas_price: 0, tx_hash: async_call.tx_hash.clone(), @@ -41,6 +42,15 @@ fn result_status_bytes(result_status: u64) -> Vec { } } +fn real_recipient( + async_data: &AsyncCallTxData, + builtin_functions: &BuiltinFunctionContainer, +) -> VMAddress { + let tx_input = async_call_tx_input(async_data, CallType::AsyncCall); + let transfers = builtin_functions.extract_token_transfers(&tx_input); + transfers.real_recipient +} + pub fn async_callback_tx_input( async_data: &AsyncCallTxData, async_result: &TxResult, @@ -55,12 +65,13 @@ pub fn async_callback_tx_input( let callback_payments = extract_callback_payments(&async_data.from, async_result, builtin_functions); TxInput { - from: async_data.to.clone(), + from: real_recipient(async_data, builtin_functions), to: async_data.from.clone(), egld_value: 0u32.into(), esdt_values: Vec::new(), func_name: TxFunctionName::CALLBACK, args, + call_type: CallType::AsyncCallback, gas_limit: 1000, gas_price: 0, tx_hash: async_data.tx_hash.clone(), @@ -76,13 +87,15 @@ fn extract_callback_payments( ) -> CallbackPayments { let mut callback_payments = CallbackPayments::default(); for async_call in &async_result.all_calls { - let tx_input = async_call_tx_input(async_call); + let tx_input = async_call_tx_input(async_call, CallType::AsyncCall); let token_transfers = builtin_functions.extract_token_transfers(&tx_input); if &token_transfers.real_recipient == callback_contract_address { 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; } @@ -90,35 +103,22 @@ fn extract_callback_payments( callback_payments } -pub fn async_promise_tx_input( - address: &VMAddress, +pub fn async_promise_callback_tx_input( promise: &Promise, async_result: &TxResult, + builtin_functions: &BuiltinFunctionContainer, ) -> TxInput { - let mut args: Vec> = Vec::new(); - let serialized_bytes = async_result.result_status.to_be_bytes().to_vec(); - args.push(serialized_bytes); let callback_name = if async_result.result_status == 0 { - args.extend_from_slice(async_result.result_values.as_slice()); promise.success_callback.clone() } else { - args.push(async_result.result_message.clone().into_bytes()); promise.error_callback.clone() }; - TxInput { - from: promise.call.from.clone(), - to: address.clone(), - egld_value: 0u32.into(), - esdt_values: Vec::new(), - func_name: callback_name, - args, - gas_limit: 1000, - gas_price: 0, - tx_hash: promise.call.tx_hash.clone(), - promise_callback_closure_data: promise.callback_closure_data.clone(), - ..Default::default() - } + let mut callback_input = + async_callback_tx_input(&promise.call, async_result, builtin_functions); + callback_input.func_name = callback_name; + callback_input.promise_callback_closure_data = Some(promise.callback_closure_data.clone()); + callback_input } pub fn merge_results(mut original: TxResult, mut new: TxResult) -> TxResult { diff --git a/vm/src/tx_mock/tx_async_promise.rs b/vm/src/tx_mock/tx_async_promise.rs index 8b32a8c23c..ae29dcfbcb 100644 --- a/vm/src/tx_mock/tx_async_promise.rs +++ b/vm/src/tx_mock/tx_async_promise.rs @@ -7,3 +7,9 @@ pub struct Promise { pub error_callback: TxFunctionName, pub callback_closure_data: Vec, } + +impl Promise { + pub fn has_callback(&self) -> bool { + !self.success_callback.is_empty() && !self.error_callback.is_empty() + } +} diff --git a/vm/src/tx_mock/tx_back_transfers.rs b/vm/src/tx_mock/tx_back_transfers.rs index beca6ce6a2..19a5ed2ca3 100644 --- a/vm/src/tx_mock/tx_back_transfers.rs +++ b/vm/src/tx_mock/tx_back_transfers.rs @@ -1,6 +1,8 @@ use num_bigint::BigUint; -use super::{TxResult, TxTokenTransfer}; +use crate::{tx_execution::BuiltinFunctionContainer, types::VMAddress}; + +use super::{async_call_tx_input, CallType, TxResult, TxTokenTransfer}; #[derive(Default)] pub struct BackTransfers { @@ -13,7 +15,30 @@ impl BackTransfers { BackTransfers::default() } - pub fn append_from_result(&mut self, _result: &TxResult) { - todo!() + pub fn new_from_result( + &mut self, + own_address: &VMAddress, + result: &TxResult, + builtin_functions: &BuiltinFunctionContainer, + ) { + let mut bt = BackTransfers::default(); + + for call in &result.all_calls { + // TODO: refactor, check type + + if call.endpoint_name.is_empty() { + bt.call_value += &call.call_value; + continue; + } + + let tx_input = async_call_tx_input(call, CallType::BackTransfer); + let mut token_transfers = builtin_functions.extract_token_transfers(&tx_input); + if &token_transfers.real_recipient == own_address { + bt.esdt_transfers.append(&mut token_transfers.transfers); + } + } + + self.call_value = bt.call_value; + self.esdt_transfers = bt.esdt_transfers; } } diff --git a/vm/src/tx_mock/tx_cache.rs b/vm/src/tx_mock/tx_cache.rs index a52fc998f5..5925f3dd20 100644 --- a/vm/src/tx_mock/tx_cache.rs +++ b/vm/src/tx_mock/tx_cache.rs @@ -4,6 +4,8 @@ use std::{ sync::{Arc, Mutex}, }; +use colored::Colorize; + use crate::{ display_util::address_hex, types::VMAddress, @@ -51,13 +53,24 @@ impl TxCache { pub fn with_account(&self, address: &VMAddress, f: F) -> R where F: FnOnce(&AccountData) -> R, + { + self.with_account_or_else(address, f, || { + panic!("Account {} not found", address_hex(address)) + }) + } + + pub fn with_account_or_else(&self, address: &VMAddress, f: F, or_else: Else) -> R + where + F: FnOnce(&AccountData) -> R, + Else: FnOnce() -> R, { self.load_account_if_necessary(address); let accounts = self.accounts.lock().unwrap(); - let account = accounts - .get(address) - .unwrap_or_else(|| panic!("Account {} not found", address_hex(address))); - f(account) + if let Some(account) = accounts.get(address) { + f(account) + } else { + or_else() + } } pub fn with_account_mut(&self, address: &VMAddress, f: F) -> R @@ -91,7 +104,18 @@ impl TxCache { self.blockchain_ref() .get_new_address(creator_address.clone(), current_nonce - 1) .unwrap_or_else(|| { - panic!("Missing new address. Only explicit new deploy addresses supported") + let new_mock_address = + VMAddress::generate_mock_address(&creator_address.to_vec(), current_nonce - 1); + println!( + "{}", + format!( + "Missing new address for {:?}.\nCreating a new mock address...: {:?}", + address_hex(creator_address), + address_hex(&new_mock_address) + ) + .yellow() + ); + new_mock_address }) } 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_context.rs b/vm/src/tx_mock/tx_context.rs index ae60f232da..fca9d58363 100644 --- a/vm/src/tx_mock/tx_context.rs +++ b/vm/src/tx_mock/tx_context.rs @@ -1,6 +1,6 @@ use crate::{ tx_execution::BlockchainVMRef, - types::VMAddress, + types::{VMAddress, VMCodeMetadata}, world_mock::{AccountData, AccountEsdt, BlockchainState, FailingExecutor}, }; use num_bigint::BigUint; @@ -49,6 +49,7 @@ impl TxContext { esdt: AccountEsdt::default(), username: Vec::new(), contract_path: None, + code_metadata: VMCodeMetadata::empty(), contract_owner: None, developer_rewards: BigUint::zero(), }); @@ -95,6 +96,14 @@ impl TxContext { self.tx_cache.with_account(address, f) } + pub fn with_account_or_else(&self, address: &VMAddress, f: F, or_else: Else) -> R + where + F: FnOnce(&AccountData) -> R, + Else: FnOnce() -> R, + { + self.tx_cache.with_account_or_else(address, f, or_else) + } + pub fn with_contract_account(&self, f: F) -> R where F: FnOnce(&AccountData) -> R, @@ -140,6 +149,7 @@ impl TxContext { &self, new_address: &VMAddress, contract_path: Vec, + code_metadata: VMCodeMetadata, contract_owner: VMAddress, ) { assert!( @@ -155,6 +165,7 @@ impl TxContext { esdt: AccountEsdt::default(), username: Vec::new(), contract_path: Some(contract_path), + code_metadata, contract_owner: Some(contract_owner), developer_rewards: BigUint::zero(), }); diff --git a/vm/src/tx_mock/tx_input.rs b/vm/src/tx_mock/tx_input.rs index cf16bbab8e..1e7de12424 100644 --- a/vm/src/tx_mock/tx_input.rs +++ b/vm/src/tx_mock/tx_input.rs @@ -7,7 +7,7 @@ use crate::{ }; use std::fmt; -use super::TxFunctionName; +use super::{CallType, TxFunctionName}; #[derive(Clone, Debug)] pub struct TxInput { @@ -17,10 +17,11 @@ pub struct TxInput { pub esdt_values: Vec, pub func_name: TxFunctionName, pub args: Vec>, + pub call_type: CallType, pub gas_limit: u64, pub gas_price: u64, pub tx_hash: H256, - pub promise_callback_closure_data: Vec, + pub promise_callback_closure_data: Option>, pub callback_payments: CallbackPayments, } @@ -33,10 +34,11 @@ impl Default for TxInput { esdt_values: Vec::new(), func_name: TxFunctionName::EMPTY, args: Vec::new(), + call_type: CallType::DirectCall, gas_limit: 0, gas_price: 0, tx_hash: H256::zero(), - promise_callback_closure_data: Vec::new(), + promise_callback_closure_data: None, callback_payments: Default::default(), } } diff --git a/vm/src/tx_mock/tx_input_call_type.rs b/vm/src/tx_mock/tx_input_call_type.rs new file mode 100644 index 0000000000..a190908379 --- /dev/null +++ b/vm/src/tx_mock/tx_input_call_type.rs @@ -0,0 +1,28 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CallType { + DirectCall, + ExecuteOnDestContext, + AsyncCall, + AsyncCallback, + TransferExecute, + BackTransfer, + UpgradeFromSource, +} + +impl CallType { + pub fn to_log_bytes(&self) -> Vec { + self.as_log_str().into() + } + + fn as_log_str(&self) -> &'static str { + match self { + Self::DirectCall => "DirectCall", + Self::ExecuteOnDestContext => "ExecuteOnDestContext", + Self::AsyncCall => "AsyncCall", + Self::AsyncCallback => "AsyncCallback", + Self::TransferExecute => "TransferAndExecute", + Self::BackTransfer => "BackTransfer", + Self::UpgradeFromSource => "UpgradeFromSource", + } + } +} diff --git a/vm/src/tx_mock/tx_input_function.rs b/vm/src/tx_mock/tx_input_function.rs index 7616ba5753..7bc93179c4 100644 --- a/vm/src/tx_mock/tx_input_function.rs +++ b/vm/src/tx_mock/tx_input_function.rs @@ -53,6 +53,10 @@ impl TxFunctionName { /// The constructor name of any smart contract. pub const INIT: TxFunctionName = TxFunctionName::from_static("init"); + /// Gets called exactly once when upgrading to a new version of a smart contract. + /// Can be viewed as an "upgrade constructor". + pub const UPGRADE: TxFunctionName = TxFunctionName::from_static("upgrade"); + /// The the legacy async central callback name of any smart contract. pub const CALLBACK: TxFunctionName = TxFunctionName::from_static("callBack"); @@ -71,6 +75,10 @@ impl TxFunctionName { self.into_string().into_bytes() } + pub fn to_bytes(&self) -> Vec { + self.0.as_bytes().to_vec() + } + pub fn as_str(&self) -> &str { &self.0 } diff --git a/vm/src/tx_mock/tx_log.rs b/vm/src/tx_mock/tx_log.rs index d2a0a696da..26d61a81db 100644 --- a/vm/src/tx_mock/tx_log.rs +++ b/vm/src/tx_mock/tx_log.rs @@ -7,5 +7,5 @@ pub struct TxLog { pub address: VMAddress, pub endpoint: TxFunctionName, pub topics: Vec>, - pub data: Vec, + pub data: Vec>, } 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/types/vm_address.rs b/vm/src/types/vm_address.rs index 044e49509e..75786787cc 100644 --- a/vm/src/types/vm_address.rs +++ b/vm/src/types/vm_address.rs @@ -4,6 +4,10 @@ use core::fmt::Debug; const SC_ADDRESS_NUM_LEADING_ZEROS: u8 = 8; +pub const NUM_INT_CHARACTERS_FOR_ADDRESS: usize = 10; +pub const VM_TYPE_LEN: usize = 2; +pub const DEFAULT_VM_TYPE: &[u8] = &[5, 0]; + /// Address type being used in the VM only. /// /// Its implementation is similar to that of the heap Address in the framework, @@ -15,6 +19,24 @@ impl VMAddress { pub const fn new(bytes: [u8; 32]) -> Self { VMAddress(H256::new(bytes)) } + + pub fn generate_mock_address(creator_address: &[u8], creator_nonce: u64) -> Self { + let mut result = [0x00; 32]; + + result[10] = 0x11; + result[11] = 0x11; + result[12] = 0x11; + result[13] = 0x11; + + result[14..29].copy_from_slice(&creator_address[..15]); + result[29] = creator_nonce as u8; + result[30..].copy_from_slice(&creator_address[30..]); + + let start_index = NUM_INT_CHARACTERS_FOR_ADDRESS - VM_TYPE_LEN; + result[start_index..(start_index + DEFAULT_VM_TYPE.len())].copy_from_slice(DEFAULT_VM_TYPE); + + VMAddress::from(result) + } } impl From for VMAddress { @@ -111,3 +133,21 @@ impl VMAddress { .all(|item| item == &0u8) } } + +#[cfg(test)] +mod tests { + use crate::{display_util::address_hex, types::VMAddress}; + + #[test] + fn generate_mock_address_test() { + let creator_address = VMAddress::new([ + 111, 119, 110, 101, 114, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + ]); + let mock_address = VMAddress::generate_mock_address(&creator_address.to_vec(), 1u64); + assert_eq!( + address_hex(&mock_address), + "0x00000000000000000500111111116f776e65725f5f5f5f5f5f5f5f5f5f015f5f" + ); + } +} diff --git a/vm/src/types/vm_code_metadata.rs b/vm/src/types/vm_code_metadata.rs index 27f54f0277..5073d9ffe1 100644 --- a/vm/src/types/vm_code_metadata.rs +++ b/vm/src/types/vm_code_metadata.rs @@ -3,7 +3,7 @@ use bitflags::bitflags; bitflags! { - #[derive(Default)] + #[derive(Default, PartialEq, Debug, Clone, Copy)] pub struct VMCodeMetadata: u16 { const DEFAULT = 0; const UPGRADEABLE = 0b0000_0001_0000_0000; // LSB of first byte @@ -40,12 +40,24 @@ impl VMCodeMetadata { } impl From<[u8; 2]> for VMCodeMetadata { - #[inline] fn from(arr: [u8; 2]) -> Self { VMCodeMetadata::from(u16::from_be_bytes(arr)) } } +impl From<&[u8]> for VMCodeMetadata { + fn from(slice: &[u8]) -> Self { + let arr: [u8; 2] = slice.try_into().unwrap_or_default(); + VMCodeMetadata::from(arr) + } +} + +impl From<&Vec> for VMCodeMetadata { + fn from(v: &Vec) -> Self { + VMCodeMetadata::from(v.as_slice()) + } +} + impl From for VMCodeMetadata { #[inline] fn from(value: u16) -> Self { diff --git a/vm/src/types/vm_esdt_local_role_flags.rs b/vm/src/types/vm_esdt_local_role_flags.rs index e386db5917..2b47879ec8 100644 --- a/vm/src/types/vm_esdt_local_role_flags.rs +++ b/vm/src/types/vm_esdt_local_role_flags.rs @@ -9,6 +9,7 @@ bitflags! { /// There is another near-identical implementation in the framework, used for communicating with the VM. /// /// It might be a good idea to move it to some "common ground" crate, between the framework and the VM. + #[derive(PartialEq, Clone, Copy)] pub struct EsdtLocalRoleFlags: u64 { const NONE = 0b00000000; const MINT = 0b00000001; diff --git a/vm/src/vm_err_msg.rs b/vm/src/vm_err_msg.rs index 894bbfa654..339e926f4f 100644 --- a/vm/src/vm_err_msg.rs +++ b/vm/src/vm_err_msg.rs @@ -11,3 +11,6 @@ pub const NUMBER_IS_NOT_NORMAL: &str = pub const CANNOT_COMPARE_VALUES: &str = "values are not comparable"; pub const ERROR_SIGNALLED_BY_SMARTCONTRACT: &str = "error signalled by smartcontract"; + +pub const ERROR_NO_CALLBACK_CLOSURE: &str = + "no callback for closure, cannot call callback directly"; diff --git a/vm/src/vm_hooks/vh_dispatcher.rs b/vm/src/vm_hooks/vh_dispatcher.rs index 694e65eead..0dbfc54051 100644 --- a/vm/src/vm_hooks/vh_dispatcher.rs +++ b/vm/src/vm_hooks/vh_dispatcher.rs @@ -697,12 +697,9 @@ impl VMHooks for VMHooksDispatcher { ); } - fn managed_get_back_transfers( - &self, - _esdt_transfer_value_handle: i32, - _call_value_handle: i32, - ) { - panic!("Unavailable: managed_get_back_transfers"); + fn managed_get_back_transfers(&self, esdt_transfer_value_handle: i32, call_value_handle: i32) { + self.handler + .managed_get_back_transfers(esdt_transfer_value_handle, call_value_handle); } fn managed_async_call( @@ -942,11 +939,15 @@ impl VMHooks for VMHooksDispatcher { } fn managed_get_code_metadata(&self, address_handle: i32, response_handle: i32) { - panic!("Unavailable: managed_get_code_metadata") + self.handler + .managed_get_code_metadata(address_handle, response_handle); } fn managed_is_builtin_function(&self, function_name_handle: i32) -> i32 { - panic!("Unavailable: managed_is_builtin_function") + bool_to_i32( + self.handler + .managed_is_builtin_function(function_name_handle), + ) } fn big_float_new_from_parts( diff --git a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs index d140f8c106..43940d4a57 100644 --- a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs +++ b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs @@ -1,4 +1,5 @@ use crate::{ + tx_execution::vm_builtin_function_names::*, types::{EsdtLocalRole, EsdtLocalRoleFlags, RawHandle, VMAddress}, vm_hooks::VMHooksHandlerSource, world_mock::{EsdtData, EsdtInstance}, @@ -8,6 +9,24 @@ use num_traits::Zero; // The Go VM doesn't do it, but if we change that, we can enable it easily here too via this constant. const ESDT_TOKEN_DATA_FUNC_RESETS_VALUES: bool = false; +const VM_BUILTIN_FUNCTION_NAMES: [&str; 16] = [ + ESDT_LOCAL_MINT_FUNC_NAME, + ESDT_LOCAL_BURN_FUNC_NAME, + ESDT_MULTI_TRANSFER_FUNC_NAME, + ESDT_NFT_TRANSFER_FUNC_NAME, + ESDT_NFT_CREATE_FUNC_NAME, + ESDT_NFT_ADD_QUANTITY_FUNC_NAME, + ESDT_NFT_ADD_URI_FUNC_NAME, + ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME, + ESDT_NFT_BURN_FUNC_NAME, + ESDT_TRANSFER_FUNC_NAME, + CHANGE_OWNER_BUILTIN_FUNC_NAME, + CLAIM_DEVELOPER_REWARDS_FUNC_NAME, + SET_USERNAME_FUNC_NAME, + MIGRATE_USERNAME_FUNC_NAME, + DELETE_USERNAME_FUNC_NAME, + UPGRADE_CONTRACT_FUNC_NAME, +]; pub trait VMHooksBlockchain: VMHooksHandlerSource { fn is_contract_address(&self, address_bytes: &[u8]) -> bool { @@ -138,6 +157,28 @@ pub trait VMHooksBlockchain: VMHooksHandlerSource { self.m_types_lock().bi_overwrite(dest, esdt_balance.into()); } + fn managed_get_code_metadata(&self, address_handle: i32, response_handle: i32) { + let address = VMAddress::from_slice(self.m_types_lock().mb_get(address_handle)); + let Some(data) = self.account_data(&address) else { + self.vm_error(&format!( + "account not found: {}", + hex::encode(address.as_bytes()) + )) + }; + let code_metadata_bytes = data.code_metadata.to_byte_array(); + self.m_types_lock() + .mb_set(response_handle, code_metadata_bytes.to_vec()) + } + + fn managed_is_builtin_function(&self, function_name_handle: i32) -> bool { + VM_BUILTIN_FUNCTION_NAMES.contains( + &self + .m_types_lock() + .mb_to_function_name(function_name_handle) + .as_str(), + ) + } + #[allow(clippy::too_many_arguments)] fn managed_get_esdt_token_data( &self, @@ -155,48 +196,38 @@ pub trait VMHooksBlockchain: VMHooksHandlerSource { ) { let address = VMAddress::from_slice(self.m_types_lock().mb_get(address_handle)); let token_id_bytes = self.m_types_lock().mb_get(token_id_handle).to_vec(); - let account = self.account_data(&address); - if let Some(esdt_data) = account.esdt.get_by_identifier(token_id_bytes.as_slice()) { - if let Some(instance) = esdt_data.instances.get_by_nonce(nonce) { - self.set_esdt_data_values( - esdt_data, - instance, - value_handle, - properties_handle, - hash_handle, - name_handle, - attributes_handle, - creator_handle, - royalties_handle, - uris_handle, - ) - } else { - // missing nonce - self.reset_esdt_data_values( - value_handle, - properties_handle, - hash_handle, - name_handle, - attributes_handle, - creator_handle, - royalties_handle, - uris_handle, - ); + if let Some(account) = self.account_data(&address) { + if let Some(esdt_data) = account.esdt.get_by_identifier(token_id_bytes.as_slice()) { + if let Some(instance) = esdt_data.instances.get_by_nonce(nonce) { + self.set_esdt_data_values( + esdt_data, + instance, + value_handle, + properties_handle, + hash_handle, + name_handle, + attributes_handle, + creator_handle, + royalties_handle, + uris_handle, + ); + return; + } } - } else { - // missing token identifier - self.reset_esdt_data_values( - value_handle, - properties_handle, - hash_handle, - name_handle, - attributes_handle, - creator_handle, - royalties_handle, - uris_handle, - ); } + + // missing account/token identifier/nonce + self.reset_esdt_data_values( + value_handle, + properties_handle, + hash_handle, + name_handle, + attributes_handle, + creator_handle, + royalties_handle, + uris_handle, + ); } fn managed_get_back_transfers( @@ -221,9 +252,10 @@ pub trait VMHooksBlockchain: VMHooksHandlerSource { ) -> bool { let address = VMAddress::from_slice(self.m_types_lock().mb_get(address_handle)); let token_id_bytes = self.m_types_lock().mb_get(token_id_handle).to_vec(); - let account = self.account_data(&address); - if let Some(esdt_data) = account.esdt.get_by_identifier(token_id_bytes.as_slice()) { - return esdt_data.frozen; + if let Some(account) = self.account_data(&address) { + if let Some(esdt_data) = account.esdt.get_by_identifier(token_id_bytes.as_slice()) { + return esdt_data.frozen; + } } false diff --git a/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs b/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs index 8b7e9d053c..4feb3b8042 100644 --- a/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs +++ b/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs @@ -1,7 +1,7 @@ use num_bigint::{BigInt, BigUint}; use num_traits::ToPrimitive; -use crate::vm_hooks::VMHooksHandlerSource; +use crate::{vm_err_msg::ERROR_NO_CALLBACK_CLOSURE, vm_hooks::VMHooksHandlerSource}; use crate::types::RawHandle; @@ -47,7 +47,10 @@ pub trait VMHooksEndpointArgument: VMHooksHandlerSource + VMHooksManagedTypes { } fn load_callback_closure_buffer(&self, dest: RawHandle) { - let closure_data = self.input_ref().promise_callback_closure_data.clone(); - self.m_types_lock().mb_set(dest, closure_data); + if let Some(closure_data) = &self.input_ref().promise_callback_closure_data { + self.m_types_lock().mb_set(dest, closure_data.clone()); + } else { + self.vm_error(ERROR_NO_CALLBACK_CLOSURE); + } } } diff --git a/vm/src/vm_hooks/vh_handler/vh_log.rs b/vm/src/vm_hooks/vh_handler/vh_log.rs index f6320947e8..04f5825896 100644 --- a/vm/src/vm_hooks/vh_handler/vh_log.rs +++ b/vm/src/vm_hooks/vh_handler/vh_log.rs @@ -3,12 +3,12 @@ use crate::{tx_mock::TxLog, types::RawHandle, vm_hooks::VMHooksHandlerSource}; pub trait VMHooksLog: VMHooksHandlerSource { fn managed_write_log(&self, topics_handle: RawHandle, data_handle: RawHandle) { let topics = self.m_types_lock().mb_get_vec_of_bytes(topics_handle); - let data = self.m_types_lock().mb_get(data_handle).to_vec(); + let single_data_field = self.m_types_lock().mb_get(data_handle).to_vec(); self.push_tx_log(TxLog { address: self.current_address().clone(), endpoint: self.input_ref().func_name.clone(), topics, - data, + data: vec![single_data_field], }); } } diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs index 1e2410fc9c..4c2c06b49a 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs @@ -8,7 +8,7 @@ use core::{ ops::{Add, Div, Mul, Neg, Sub}, }; use num_bigint::BigInt; -use num_traits::ToPrimitive; +use num_traits::{ToPrimitive, Zero}; use std::convert::TryInto; macro_rules! binary_op_method { @@ -115,16 +115,18 @@ pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError { fn bf_sign(&self, x: RawHandle) -> i32 { let bf = self.m_types_lock().bf_get_f64(x); + if bf.is_zero() { + return 0; + } + if !bf.is_normal() { self.vm_error(vm_err_msg::NUMBER_IS_NOT_NORMAL) } if bf.is_sign_positive() { 1 - } else if bf.is_sign_negative() { - -1 } else { - 0 + -1 } } diff --git a/vm/src/vm_hooks/vh_impl/vh_debug_api.rs b/vm/src/vm_hooks/vh_impl/vh_debug_api.rs index ca74f544c6..618788d966 100644 --- a/vm/src/vm_hooks/vh_impl/vh_debug_api.rs +++ b/vm/src/vm_hooks/vh_impl/vh_debug_api.rs @@ -5,8 +5,8 @@ use multiversx_chain_vm_executor::BreakpointValue; use crate::{ tx_execution::execute_current_tx_context_input, tx_mock::{ - async_call_tx_input, AsyncCallTxData, BackTransfers, BlockchainUpdate, TxCache, TxContext, - TxFunctionName, TxInput, TxManagedTypes, TxPanic, TxResult, + async_call_tx_input, AsyncCallTxData, BackTransfers, BlockchainUpdate, CallType, TxCache, + TxContext, TxFunctionName, TxInput, TxManagedTypes, TxPanic, TxResult, }, types::{VMAddress, VMCodeMetadata}, vm_err_msg, @@ -83,8 +83,9 @@ impl VMHooksHandlerSource for DebugApiVMHooksHandler { self.0.back_transfers_lock() } - fn account_data(&self, address: &VMAddress) -> AccountData { - self.0.with_account(address, |account| account.clone()) + fn account_data(&self, address: &VMAddress) -> Option { + self.0 + .with_account_or_else(address, |account| Some(account.clone()), || None) } fn account_code(&self, address: &VMAddress) -> Vec { @@ -118,7 +119,7 @@ impl VMHooksHandlerSource for DebugApiVMHooksHandler { arguments: Vec>, ) -> Vec> { let async_call_data = self.create_async_call_data(to, egld_value, func_name, arguments); - let tx_input = async_call_tx_input(&async_call_data); + let tx_input = async_call_tx_input(&async_call_data, CallType::ExecuteOnDestContext); let tx_cache = TxCache::new(self.0.blockchain_cache_arc()); let (tx_result, blockchain_updates) = self.0.vm_ref.execute_builtin_function_or_default( tx_input, @@ -138,7 +139,7 @@ impl VMHooksHandlerSource for DebugApiVMHooksHandler { &self, egld_value: num_bigint::BigUint, contract_code: Vec, - _code_metadata: VMCodeMetadata, + code_metadata: VMCodeMetadata, args: Vec>, ) -> (VMAddress, Vec>) { let contract_address = self.current_address(); @@ -161,6 +162,7 @@ impl VMHooksHandlerSource for DebugApiVMHooksHandler { let (tx_result, new_address, blockchain_updates) = self.0.vm_ref.deploy_contract( tx_input, contract_code, + code_metadata, tx_cache, execute_current_tx_context_input, ); @@ -183,7 +185,11 @@ impl VMHooksHandlerSource for DebugApiVMHooksHandler { arguments: Vec>, ) { let async_call_data = self.create_async_call_data(to, egld_value, func_name, arguments); - let tx_input = async_call_tx_input(&async_call_data); + let mut tx_input = async_call_tx_input(&async_call_data, CallType::TransferExecute); + if self.is_back_transfer(&tx_input) { + tx_input.call_type = CallType::BackTransfer; + } + let tx_cache = TxCache::new(self.0.blockchain_cache_arc()); let (tx_result, blockchain_updates) = self.0.vm_ref.execute_builtin_function_or_default( tx_input, @@ -232,6 +238,11 @@ impl DebugApiVMHooksHandler { self.0.result_lock().merge_after_sync_call(&tx_result); + let contract_address = &self.0.input_ref().to; + let builtin_functions = &self.0.vm_ref.builtin_functions; + self.back_transfers_lock() + .new_from_result(contract_address, &tx_result, builtin_functions); + tx_result.result_values } @@ -240,6 +251,17 @@ impl DebugApiVMHooksHandler { self.vm_error("cannot write to storage under reserved key"); } } + + fn is_back_transfer(&self, tx_input: &TxInput) -> bool { + let caller_address = &self.0.input_ref().from; + if !caller_address.is_smart_contract_address() { + return false; + } + + let builtin_functions = &self.0.vm_ref.builtin_functions; + let token_transfers = builtin_functions.extract_token_transfers(tx_input); + &token_transfers.real_recipient == caller_address + } } impl VMHooksBigInt for DebugApiVMHooksHandler {} diff --git a/vm/src/vm_hooks/vh_impl/vh_single_tx_api.rs b/vm/src/vm_hooks/vh_impl/vh_single_tx_api.rs index 819e8c9e5c..27fa484a4a 100644 --- a/vm/src/vm_hooks/vh_impl/vh_single_tx_api.rs +++ b/vm/src/vm_hooks/vh_impl/vh_single_tx_api.rs @@ -97,8 +97,8 @@ impl VMHooksHandlerSource for SingleTxApiVMHooksHandler { panic!("cannot access back transfers in the SingleTxApi") } - fn account_data(&self, address: &VMAddress) -> AccountData { - self.0.with_account_mut(address, |account| account.clone()) + fn account_data(&self, address: &VMAddress) -> Option { + Some(self.0.with_account_mut(address, |account| account.clone())) } fn account_code(&self, _address: &VMAddress) -> Vec { diff --git a/vm/src/vm_hooks/vh_impl/vh_static_api.rs b/vm/src/vm_hooks/vh_impl/vh_static_api.rs index ef4e4b5c6a..aba07908e0 100644 --- a/vm/src/vm_hooks/vh_impl/vh_static_api.rs +++ b/vm/src/vm_hooks/vh_impl/vh_static_api.rs @@ -72,7 +72,7 @@ impl VMHooksHandlerSource for StaticApiVMHooksHandler { panic!("cannot access the back transfers in the StaticApi") } - fn account_data(&self, _address: &VMAddress) -> AccountData { + fn account_data(&self, _address: &VMAddress) -> Option { panic!("cannot access account data in the StaticApi") } diff --git a/vm/src/vm_hooks/vh_source.rs b/vm/src/vm_hooks/vh_source.rs index ed66297c24..0ad2e59e2a 100644 --- a/vm/src/vm_hooks/vh_source.rs +++ b/vm/src/vm_hooks/vh_source.rs @@ -52,13 +52,14 @@ pub trait VMHooksHandlerSource: Debug { /// For ownership reasons, needs to return a clone. /// /// Can be optimized, but is not a priority right now. - fn account_data(&self, address: &VMAddress) -> AccountData; + fn account_data(&self, address: &VMAddress) -> Option; /// For ownership reasons, needs to return a clone. /// /// Can be optimized, but is not a priority right now. fn current_account_data(&self) -> AccountData { self.account_data(&self.input_ref().to) + .expect("missing current account") } fn account_code(&self, address: &VMAddress) -> Vec; diff --git a/vm/src/world_mock/account_data.rs b/vm/src/world_mock/account_data.rs index e7f5b9330b..9268c4535c 100644 --- a/vm/src/world_mock/account_data.rs +++ b/vm/src/world_mock/account_data.rs @@ -2,7 +2,10 @@ use num_bigint::BigUint; use num_traits::Zero; use super::AccountEsdt; -use crate::{display_util::key_hex, types::VMAddress}; +use crate::{ + display_util::key_hex, + types::{VMAddress, VMCodeMetadata}, +}; use std::{collections::HashMap, fmt, fmt::Write}; pub type AccountStorage = HashMap, Vec>; @@ -16,6 +19,7 @@ pub struct AccountData { pub storage: AccountStorage, pub username: Vec, pub contract_path: Option>, + pub code_metadata: VMCodeMetadata, pub contract_owner: Option, pub developer_rewards: BigUint, } @@ -30,6 +34,7 @@ impl AccountData { storage: AccountStorage::default(), username: vec![], contract_path: None, + code_metadata: VMCodeMetadata::empty(), contract_owner: None, developer_rewards: BigUint::zero(), } @@ -56,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, diff --git a/framework/scenario/tests/test_crypto.rs b/vm/tests/test_crypto.rs similarity index 100% rename from framework/scenario/tests/test_crypto.rs rename to vm/tests/test_crypto.rs